diff --git a/components/AttachmentList.vue b/components/AttachmentList.vue
deleted file mode 100644
index c50b08ba75178b68b20d132c401f09defbcea539..0000000000000000000000000000000000000000
--- a/components/AttachmentList.vue
+++ /dev/null
@@ -1,240 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-form ref="attachmentsForm" @submit.prevent>
-    <v-row v-if="!readonly">
-      <v-col cols="12" md="3">
-        <v-radio-group
-          v-model="attachmentType"
-          label="Type"
-          row
-        >
-          <v-radio label="File" value="file" />
-          <v-radio label="Url" value="url" />
-        </v-radio-group>
-      </v-col>
-    </v-row>
-    <v-row v-if="!readonly">
-      <v-col cols="12" md="4">
-        <v-file-input
-          v-if="attachmentType === 'file'"
-          v-model="file"
-          :accept="mimeTypeList"
-          label="File"
-          required
-          class="required"
-          :rules="[rules.required]"
-          show-size
-        />
-        <v-text-field
-          v-if="attachmentType === 'url'"
-          v-model="attachment.url"
-          label="URL"
-          type="url"
-          placeholder="http://"
-          required
-          class="required"
-          :rules="[rules.required, rules.validUrl]"
-        />
-      </v-col>
-    </v-row>
-    <v-row v-if="!readonly">
-      <v-col cols="12" md="4">
-        <v-text-field
-          v-model="attachment.label"
-          label="Label"
-        />
-      </v-col>
-    </v-row>
-    <v-row v-if="!readonly">
-      <v-col cols="12">
-        <v-spacer />
-        <v-btn
-          color="primary"
-          small
-          data-role="add-attachment"
-          @click="add()"
-        >
-          {{ attachmentType === 'url' ? 'Add' : 'Upload' }}
-        </v-btn>
-      </v-col>
-    </v-row>
-    <v-row>
-      <v-col cols="12">
-        <v-list
-          two-line
-          subheader
-        >
-          <v-subheader v-if="value.length" inset>
-            Attachments
-          </v-subheader>
-
-          <AttachmentListItem
-            v-for="(item, index) in value"
-            :key="getUrlIndex(item)"
-            v-model="value[index]"
-            :readonly="readonly"
-          >
-            <template
-              v-if="!readonly"
-              #action
-            >
-              <v-btn
-                icon
-                color="error"
-                data-role="delete-attachment"
-                @click="remove(index)"
-              >
-                <v-icon>
-                  mdi-delete
-                </v-icon>
-              </v-btn>
-            </template>
-          </AttachmentListItem>
-        </v-list>
-      </v-col>
-    </v-row>
-  </v-form>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component for a listing of attachments
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Vue, Component, Prop, mixins } from 'nuxt-property-decorator'
-import { Rules } from '@/mixins/Rules'
-
-import AttachmentListItem from '@/components/AttachmentListItem.vue'
-
-import { Attachment } from '@/models/Attachment'
-
-/**
- * A class component for a list of Attachments and an upload form
- * @extends Vue
- */
-@Component({
-  components: { AttachmentListItem }
-})
-// @ts-ignore
-export default class AttachmentList extends mixins(Rules) {
-  /**
-   * an Array of Attachments
-   */
-  @Prop({
-    default: () => [] as Attachment[],
-    required: true,
-    type: Array
-  })
-  // @ts-ignore
-  readonly value!: Attachment[]
-
-  /**
-   * whether the component is in readonly mode or not
-   */
-  @Prop({
-    default: false,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly readonly: boolean
-
-  private attachment: Attachment = new Attachment()
-  private attachmentType: string = 'file'
-  private file: File | null = null
-
-  /**
-   * adds a new Attachment instance
-   *
-   * @fires AttachmentList#input
-   */
-  add () {
-    // see https://stackoverflow.com/a/52109899/86224
-    if (!(this.$refs.attachmentsForm as Vue & { validate: () => boolean }).validate()) {
-      return
-    }
-
-    (this.$refs.attachmentsForm as Vue & { resetValidation: () => boolean }).resetValidation()
-
-    /**
-     * fires an input event
-     * @event AttachmentList#input
-     * @type {Attachment[]}
-     */
-    this.$emit('input', [
-      ...this.value,
-      this.attachment
-    ] as Attachment[])
-
-    this.attachment = new Attachment()
-    this.file = null
-  }
-
-  /**
-   * removes an Attachment instance
-   *
-   * @param {number} index - the index of the attachment to remove
-   * @fires AttachmentList#input
-   */
-  remove (index: number) {
-    if (this.value[index]) {
-      const properties = [...this.value] as Attachment[]
-      properties.splice(index, 1)
-      /**
-       * fires an input event
-       * @event AttachmentList#input
-       * @type {Attachment[]}
-       */
-      this.$emit('input', properties)
-    }
-  }
-
-  /**
-   * returns a list of MimeTypes, seperated by ,
-   *
-   * @return {string} a list of MimeTypes
-   */
-  get mimeTypeList (): string {
-    return Object.keys(Attachment.mimeTypes).join(',')
-  }
-
-  /**
-   * returns a unique index for the attachment in the list
-   *
-   * @param {Attachment} item - the attachment for that the index shall be created
-   * @return {string} the index in the form url + '#' + <count of url in the list if gt 0>
-   */
-  getUrlIndex (item: Attachment) {
-    const cnt: number = this.value.filter((attachment: Attachment): boolean => item.url === attachment.url).indexOf(item)
-    return cnt > 0 ? item.url + '#' + cnt : item.url
-  }
-}
-</script>
diff --git a/components/AttachmentListItem.vue b/components/AttachmentListItem.vue
deleted file mode 100644
index c09b2581a60e4f9f988676dbc2dc3f5275971ed0..0000000000000000000000000000000000000000
--- a/components/AttachmentListItem.vue
+++ /dev/null
@@ -1,194 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-list-item>
-    <v-list-item-avatar>
-      <v-icon large>
-        {{ filetypeIcon }}
-      </v-icon>
-    </v-list-item-avatar>
-    <v-list-item-content>
-      <v-list-item-subtitle>
-        {{ filename }}, uploaded at {{ uploadedDateTime }}
-      </v-list-item-subtitle>
-      <v-list-item-title v-if="readonly">
-        <a :href="value.url" target="_blank">{{ value.label }}</a>
-      </v-list-item-title>
-      <v-list-item-title v-else>
-        <v-text-field
-          :value="value.label"
-          @input="update('label', $event)"
-        />
-      </v-list-item-title>
-    </v-list-item-content>
-    <v-list-item-action
-      v-if="!readonly"
-    >
-      <v-btn
-        icon
-        color="primary"
-        :href="value.url"
-        target="_blank"
-      >
-        <v-icon>
-          mdi-open-in-new
-        </v-icon>
-      </v-btn>
-    </v-list-item-action>
-    <v-list-item-action>
-      <slot name="action" />
-    </v-list-item-action>
-  </v-list-item>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component for an attachment
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import { Attachment } from '@/models/Attachment'
-
-/**
- * A class component that displays a single attached file
- * @extends Vue
- */
-@Component
-// @ts-ignore
-export default class AttachmentListItem extends Vue {
-  /**
-   * an Attachment
-   */
-  @Prop({
-    required: true,
-    type: Attachment
-  })
-  // @ts-ignore
-  readonly value!: Attachment
-
-  /**
-   * whether the component is in readonly mode or not
-   */
-  @Prop({
-    default: false,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly readonly: boolean
-
-  /**
-   * returns a filename from a full filepath
-   *
-   * @return {string} the filename
-   */
-  get filename (): string {
-    const UNKNOWN_FILENAME = 'unknown filename'
-
-    if (this.value.url === '') {
-      return UNKNOWN_FILENAME
-    }
-    const paths = this.value.url.split('/')
-    if (!paths.length) {
-      return UNKNOWN_FILENAME
-    }
-    // @ts-ignore
-    return paths.pop()
-  }
-
-  /**
-   * returns the timestamp of the upload date
-   *
-   * @TODO this must be implemented when the file API is ready
-   * @return {string} a readable timestamp
-   */
-  get uploadedDateTime (): string {
-    return '2020-06-17 16:35 (TODO)'
-  }
-
-  /**
-   * returns a material design icon name based on the file type extension
-   *
-   * @return {string} a material design icon name
-   */
-  get filetypeIcon (): string {
-    let extension = ''
-    const paths = this.filename.split('.')
-    if (paths.length) {
-      // @ts-ignore
-      extension = paths.pop().toLowerCase()
-    }
-    switch (extension) {
-      case 'png':
-      case 'jpg':
-      case 'jpeg':
-        return 'mdi-image'
-      case 'pdf':
-        return 'mdi-file-pdf-box'
-      case 'doc':
-      case 'docx':
-      case 'odt':
-        return 'mdi-text-box'
-      default:
-        return 'mdi-paperclip'
-    }
-  }
-
-  /**
-   * update the internal model at a given key
-   *
-   * @param {string} key - a path to the property to set
-   * @param {string} value - the value to set
-   * @fires AttachmentListItem#input
-   */
-  update (key: string, value: string) {
-    const newObj: Attachment = Attachment.createFromObject(this.value)
-
-    switch (key) {
-      case 'url':
-        newObj.url = value
-        break
-      case 'label':
-        newObj.label = value
-        break
-      default:
-        throw new TypeError('key ' + key + ' is not valid')
-    }
-
-    /**
-     * fires an input event
-     * @event AttachmentListItem#input
-     * @type {Attachment}
-     */
-    this.$emit('input', newObj)
-  }
-}
-</script>
diff --git a/components/ConfigurationsDemoTreeView.vue b/components/ConfigurationsDemoTreeView.vue
deleted file mode 100644
index b1680c62fdc67aefe292ad11bdebd07c4d7e7668..0000000000000000000000000000000000000000
--- a/components/ConfigurationsDemoTreeView.vue
+++ /dev/null
@@ -1,209 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020-2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <div>
-    <v-treeview
-      :items="items"
-      :activatable="false"
-      :hoverable="false"
-      rounded
-      open-all
-    >
-      <template #prepend="{ item }">
-        <v-icon v-if="item.isPlatform()">
-          mdi-rocket-outline
-        </v-icon>
-        <v-icon v-else>
-          mdi-network-outline
-        </v-icon>
-      </template>
-    </v-treeview>
-    <p
-      class="font-italic text--secondary"
-    >
-      This is a demo hierarchy. Replace it with your own platform and devices.
-    </p>
-  </div>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component to select platforms and devices for a configuration
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Vue, Component } from 'nuxt-property-decorator'
-import { DateTime } from 'luxon'
-
-import { Contact } from '@/models/Contact'
-import { Device } from '@/models/Device'
-import { DeviceMountAction } from '@/models/DeviceMountAction'
-import { DeviceUnmountAction } from '@/models/DeviceUnmountAction'
-import { Platform } from '@/models/Platform'
-import { PlatformMountAction } from '@/models/PlatformMountAction'
-import { PlatformUnmountAction } from '@/models/PlatformUnmountAction'
-
-import { ConfigurationsTreeNode } from '@/viewmodels/ConfigurationsTreeNode'
-
-import { buildConfigurationTree } from '@/modelUtils/mountHelpers'
-
-/**
- * A class component to select platforms and devices for a configuration
- * @extends Vue
- */
-@Component
-// @ts-ignore
-export default class ConfigurationsDemoTreeView extends Vue {
-  createPlatform (id: string) {
-    const p = new Platform()
-    p.id = id
-    p.shortName = 'Platform ' + id
-    return p
-  }
-
-  createDevice (id: string) {
-    const d = new Device()
-    d.id = id
-    d.shortName = 'Device ' + id
-    return d
-  }
-
-  private platforms: Platform[] = [
-    this.createPlatform('1'),
-    this.createPlatform('2'),
-    this.createPlatform('3')
-  ]
-
-  private devices: Device[] = [
-    this.createDevice('1'),
-    this.createDevice('2'),
-    this.createDevice('3')
-  ]
-
-  /**
-   * returns a demo tree
-   *
-   * @return {ConfigurationsTreeNode[]} a demo tree
-   */
-  get items (): ConfigurationsTreeNode[] {
-    const demoContact = new Contact()
-    demoContact.givenName = 'Max'
-    demoContact.familyName = 'Mustermann'
-    demoContact.email = 'max.mustermann@mail.org'
-
-    const platformMountActions = [
-      PlatformMountAction.createFromObject({
-        id: '',
-        platform: this.platforms[0],
-        parentPlatform: null,
-        date: DateTime.utc(2020, 10, 11),
-        offsetX: 0,
-        offsetY: 0,
-        offsetZ: 0,
-        contact: demoContact,
-        description: 'Mounted platform 1'
-      }),
-      PlatformMountAction.createFromObject({
-        id: '',
-        platform: this.platforms[1],
-        parentPlatform: this.platforms[0],
-        date: DateTime.utc(2020, 10, 13),
-        offsetX: 0,
-        offsetY: 0,
-        offsetZ: 0,
-        contact: demoContact,
-        description: 'Mounted platform 2 on platform 1'
-      })
-    ]
-    const platformUnmountActions = [
-      PlatformUnmountAction.createFromObject({
-        id: '',
-        platform: this.platforms[1],
-        date: DateTime.utc(2020, 10, 19),
-        contact: demoContact,
-        description: 'Unmounted platform 2'
-      })
-    ]
-    const deviceMountActions = [
-      DeviceMountAction.createFromObject({
-        id: '',
-        device: this.devices[0],
-        parentPlatform: this.platforms[0],
-        date: DateTime.utc(2020, 10, 12),
-        offsetX: 0,
-        offsetY: 0,
-        offsetZ: 0,
-        contact: demoContact,
-        description: 'Mounted device 1 on platform 1'
-      }),
-      DeviceMountAction.createFromObject({
-        id: '',
-        device: this.devices[1],
-        parentPlatform: this.platforms[1],
-        date: DateTime.utc(2020, 10, 15),
-        offsetX: 0,
-        offsetY: 0,
-        offsetZ: 0,
-        contact: demoContact,
-        description: 'Mounted device 2 on platform 2'
-      }),
-      DeviceMountAction.createFromObject({
-        id: '',
-        device: this.devices[2],
-        parentPlatform: null,
-        date: DateTime.utc(2020, 10, 17),
-        offsetX: 0,
-        offsetY: 0,
-        offsetZ: 0,
-        contact: demoContact,
-        description: 'Mounted device 3'
-      })
-    ]
-    const deviceUnmountActions = [
-      DeviceUnmountAction.createFromObject({
-        id: '',
-        device: this.devices[1],
-        date: DateTime.utc(2020, 10, 16),
-        contact: demoContact,
-        description: 'Unmounted device 2'
-      })
-    ]
-
-    const tree = buildConfigurationTree({
-      platformMountActions,
-      platformUnmountActions,
-      deviceMountActions,
-      deviceUnmountActions
-    }, DateTime.utc(2020, 10, 17))
-
-    return tree.toArray()
-  }
-}
-</script>
diff --git a/components/ConfigurationsPlatformDeviceSearch.vue b/components/ConfigurationsPlatformDeviceSearch.vue
deleted file mode 100644
index 9ffe4f918522938e5866a55bab6ae2b4ffdc2a52..0000000000000000000000000000000000000000
--- a/components/ConfigurationsPlatformDeviceSearch.vue
+++ /dev/null
@@ -1,432 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020-2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <div>
-    Add platforms and devices:
-    <v-row v-if="searchOptions">
-      <v-col cols="12" md="3">
-        <v-select
-          v-model="searchOptions.searchType"
-          label="Type"
-          :items="searchTypes"
-        />
-      </v-col>
-      <v-col cols="12" md="6">
-        <v-text-field
-          v-model="searchOptions.text"
-          label="Name"
-          @keydown.enter="search"
-        />
-      </v-col>
-      <v-col cols="12" md="3">
-        <v-btn
-          color="primary"
-          @click="search"
-        >
-          search
-        </v-btn>
-      </v-col>
-    </v-row>
-    <div v-if="loading">
-      <div class="text-center pt-2">
-        <v-progress-circular indeterminate />
-      </div>
-    </div>
-    <div v-else>
-      <v-row v-if="searchedForPlatforms && platforms.length">
-        <v-col cols="12">
-          <v-expansion-panels
-            v-model="selectedPlatform"
-          >
-            <v-expansion-panel
-              v-for="item in platforms"
-              :key="'platform-' + item.id"
-            >
-              <v-expansion-panel-header>
-                {{ item.shortName }} {{ isPlatformUsedFunc(item) ? ' - already mounted': '' }}
-              </v-expansion-panel-header>
-              <v-expansion-panel-content>
-                <v-expansion-panels multiple>
-                  <v-expansion-panel>
-                    <v-expansion-panel-header>
-                      Platform overview
-                    </v-expansion-panel-header>
-                    <v-expansion-panel-content>
-                      <v-row>
-                        <v-col>
-                          <label>Long name</label>
-                        </v-col>
-                        <v-col>
-                          {{ item.longName }}
-                        </v-col>
-                      </v-row>
-                      <v-row>
-                        <v-col>
-                          <label>URN</label>
-                        </v-col>
-                        <v-col>
-                          (TODO)
-                        </v-col>
-                      </v-row>
-                      <v-row>
-                        <v-col>
-                          <v-btn :href="'platforms/' + item.id" target="_blank" :disabled="false">
-                            <v-icon>
-                              mdi-open-in-new
-                            </v-icon>
-                            Open in new tab
-                          </v-btn>
-                        </v-col>
-                      </v-row>
-                    </v-expansion-panel-content>
-                  </v-expansion-panel>
-                  <v-expansion-panel :disabled="isPlatformUsedFunc(item)">
-                    <v-expansion-panel-header class="mount-expansion-panel">
-                      Mount
-                    </v-expansion-panel-header>
-                    <v-expansion-panel-content>
-                      <ConfigurationsPlatformDeviceMountForm
-                        ref="mountForm"
-                        data-role-btn="add-platform"
-                        :readonly="isPlatformUsedFunc(item)"
-                        :contacts="contacts"
-                        :current-user-mail="currentUserMail"
-                        @add="addPlatform(item, $event)"
-                      />
-                    </v-expansion-panel-content>
-                  </v-expansion-panel>
-                </v-expansion-panels>
-              </v-expansion-panel-content>
-            </v-expansion-panel>
-          </v-expansion-panels>
-        </v-col>
-      </v-row>
-      <v-row v-else-if="searchedForPlatforms && !platforms.length">
-        <p class="text-center">
-          There are no platforms that match your search criteria.
-        </p>
-      </v-row>
-      <v-row v-if="searchedForDevices && devices.length">
-        <v-col cols="12">
-          <v-expansion-panels
-            v-model="selectedDevice"
-          >
-            <v-expansion-panel
-              v-for="item in devices"
-              :key="'device-' + item.id"
-            >
-              <v-expansion-panel-header>
-                {{ item.shortName }} {{ isDeviceUsedFunc(item) ? ' - already mounted': '' }}
-              </v-expansion-panel-header>
-              <v-expansion-panel-content>
-                <v-expansion-panels multiple>
-                  <v-expansion-panel>
-                    <v-expansion-panel-header>
-                      Device overview
-                    </v-expansion-panel-header>
-                    <v-expansion-panel-content>
-                      <v-row>
-                        <v-col>
-                          <label>Long name</label>
-                        </v-col>
-                        <v-col>
-                          {{ item.longName }}
-                        </v-col>
-                      </v-row>
-                      <v-row>
-                        <v-col>
-                          <label>URN</label>
-                        </v-col>
-                        <v-col>
-                          (TODO)
-                        </v-col>
-                      </v-row>
-                      <v-row>
-                        <v-col>
-                          <v-btn :href="'devices/' + item.id" target="_blank" :disabled="false">
-                            <v-icon>
-                              mdi-open-in-new
-                            </v-icon>
-                            Open in new tab
-                          </v-btn>
-                        </v-col>
-                      </v-row>
-                    </v-expansion-panel-content>
-                  </v-expansion-panel>
-                  <v-expansion-panel :disabled="isDeviceUsedFunc(item)">
-                    <v-expansion-panel-header class="mount-expansion-panel">
-                      Mount
-                    </v-expansion-panel-header>
-                    <v-expansion-panel-content>
-                      <ConfigurationsPlatformDeviceMountForm
-                        data-role-btn="add-device"
-                        :readonly="isDeviceUsedFunc(item)"
-                        :contacts="contacts"
-                        :current-user-mail="currentUserMail"
-                        @add="addDevice(item, $event)"
-                      />
-                    </v-expansion-panel-content>
-                  </v-expansion-panel>
-                </v-expansion-panels>
-              </v-expansion-panel-content>
-            </v-expansion-panel>
-          </v-expansion-panels>
-        </v-col>
-      </v-row>
-      <v-row v-else-if="searchedForDevices && !devices.length">
-        <p class="text-center">
-          There are no devices that match your search criteria.
-        </p>
-      </v-row>
-    </div>
-  </div>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component to select platforms and devices for a configuration
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-import { DateTime } from 'luxon'
-
-import ConfigurationsPlatformDeviceMountForm from '@/components/ConfigurationsPlatformDeviceMountForm.vue'
-
-import { Contact } from '@/models/Contact'
-import { Platform } from '@/models/Platform'
-import { Device } from '@/models/Device'
-
-import { IMountData } from '@/viewmodels/IMountData'
-
-enum SearchType {
-  Platform = 'Platform',
-  Device = 'Device'
-}
-
-interface ISearchOptions {
-  searchType: SearchType
-  text: string
-}
-
-type IsPlatformUsedFunc = (p: Platform) => boolean
-type IsDeviceUsedFunc = (d: Device) => boolean
-
-/**
- * A class component to search for platforms and devices
- * @extends Vue
- */
-@Component({
-  components: {
-    ConfigurationsPlatformDeviceMountForm
-  }
-})
-// @ts-ignore
-export default class ConfigurationsPlatformDeviceSearch extends Vue {
-  private searchOptions: ISearchOptions = {
-    searchType: SearchType.Platform,
-    text: ''
-  }
-
-  private platformsResult: Platform[] = [] as Platform[]
-  private devicesResult: Device[] = [] as Device[]
-
-  private selectedPlatform = -1
-  private selectedDevice = -1
-
-  private loading = false
-  private searchedForPlatforms = false
-  private searchedForDevices = false
-
-  /**
-   * a function that returns if a device is already present in a tree or not
-   */
-  @Prop({
-    default: () => false,
-    type: Function
-  })
-  // @ts-ignore
-  readonly isDeviceUsedFunc: IsDeviceUsedFunc
-
-  /**
-   * a function that returns if a platform is already present in a tree or not
-   */
-  @Prop({
-    default: () => false,
-    type: Function
-  })
-  // @ts-ignore
-  readonly isPlatformUsedFunc: IsPlatformUsedFunc
-
-  @Prop({
-    default: DateTime.utc(),
-    type: DateTime
-  })
-  readonly selectedDate!: DateTime
-
-  @Prop({
-    default: () => [],
-    type: Array
-  })
-  readonly contacts!: Contact[]
-
-  @Prop({
-    type: String
-  })
-  // @ts-ignore
-  readonly currentUserMail: string | null
-
-  get searchTypes (): string[] {
-    return [SearchType.Platform, SearchType.Device]
-  }
-
-  /**
-   * returns a list of platforms
-   *
-   * @return {Platform[]} an Array of platforms
-   */
-  get platforms (): Platform[] {
-    return this.platformsResult
-  }
-
-  /**
-   * sets the list of platforms
-   *
-   * when the list is not empty, the list of devices gets cleared
-   *
-   * @param {Platform[]} platforms - an Array of platforms to set
-   */
-  set platforms (platforms: Platform[]) {
-    this.platformsResult = platforms
-    if (platforms.length) {
-      this.devicesResult = [] as Device[]
-    }
-  }
-
-  /**
-   * returns a list of devices
-   *
-   * @return {Device[]} an Array of devices
-   */
-  get devices (): Device[] {
-    return this.devicesResult
-  }
-
-  /**
-   * sets the list of devices
-   *
-   * when the list is not empty, the list of platforms gets cleared
-   *
-   * @param {Device[]} devices - an Array of devices to set
-   */
-  set devices (devices: Device[]) {
-    this.devicesResult = devices
-    if (devices.length) {
-      this.platformsResult = [] as Platform[]
-    }
-  }
-
-  /**
-   * searches for platforms or devices depending on the searchType
-   *
-   * @async
-   */
-  async search () {
-    this.loading = true
-    this.searchedForPlatforms = false
-    this.searchedForDevices = false
-    switch (this.searchOptions.searchType) {
-      case SearchType.Platform:
-        this.platforms = await this.$api.platforms.newSearchBuilder()
-          .withText(this.searchOptions.text)
-          .build()
-          .findMatchingAsList()
-        this.searchedForPlatforms = true
-        break
-      case SearchType.Device:
-        this.devices = await this.$api.devices.newSearchBuilder()
-          .withText(this.searchOptions.text)
-          .build()
-          .findMatchingAsList()
-        this.searchedForDevices = true
-        break
-      default:
-        throw new TypeError('search function not defined for unknown value')
-    }
-    this.loading = false
-  }
-
-  /**
-   * triggers an add-platform event
-   *
-   * @param {Platform} platform - the platform to add
-   * @fires ConfigurationsPlatformDeviceSearch#add-platform
-   */
-  addPlatform (platform: Platform, mountData: IMountData) {
-    /**
-     * fires an add-plaform event
-     * @event ConfigurationsPlatformDeviceSearch#add-platform
-     * @type {Platform}
-     */
-    this.$emit(
-      'add-platform',
-      platform,
-      mountData.offsetX,
-      mountData.offsetY,
-      mountData.offsetZ,
-      mountData.contact,
-      mountData.description
-    )
-  }
-
-  /**
-   * triggers an add-device event
-   *
-   * @param {Device} device - the device to add
-   * @fires ConfigurationsPlatformDeviceSearch#add-device
-   */
-  addDevice (device: Device, mountData: IMountData) {
-    /**
-     * fires an add-device event
-     * @event ConfigurationsPlatformDeviceSearch#add-device
-     * @type {Device}
-     */
-    this.$emit(
-      'add-device',
-      device,
-      mountData.offsetX,
-      mountData.offsetY,
-      mountData.offsetZ,
-      mountData.contact,
-      mountData.description
-    )
-  }
-}
-</script>
diff --git a/components/ConfigurationsSelectedItem.vue b/components/ConfigurationsSelectedItem.vue
deleted file mode 100644
index 300ecafeb3524232ca17ac5251de5f494d70c20c..0000000000000000000000000000000000000000
--- a/components/ConfigurationsSelectedItem.vue
+++ /dev/null
@@ -1,378 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020-2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-card
-    v-if="value"
-    outlined
-  >
-    <v-breadcrumbs :items="breadcrumbs" divider=">" />
-    <v-expansion-panels multiple>
-      <v-expansion-panel>
-        <v-expansion-panel-header>
-          <span v-if="value.isPlatform()">
-            Platform overview
-          </span>
-          <span v-else>
-            Device overview
-          </span>
-        </v-expansion-panel-header>
-        <v-expansion-panel-content>
-          <template v-if="description">
-            {{ description }}
-          </template>
-          <template v-else-if="value.isPlatform()">
-            <span class="text--disabled">The selected platform has no description.</span>
-          </template>
-          <template v-else-if="value.isDevice()">
-            <span class="text--disabled">The selected device has no description.</span>
-          </template>
-        </v-expansion-panel-content>
-      </v-expansion-panel>
-      <v-expansion-panel>
-        <v-expansion-panel-header>
-          Mount information
-        </v-expansion-panel-header>
-        <v-expansion-panel-content>
-          <v-form
-            ref="mountUpdateForm"
-            @submit.prevent
-          >
-            <v-card-text>
-              <v-row>
-                <v-col>
-                  <label>Mounted:</label>
-                  {{ value.unpack().date | dateToDateTimeString }}
-                  <span class="text-caption text--secondary">(UTC)</span>
-                </v-col>
-              </v-row>
-              <v-row>
-                <v-col
-                  cols="12"
-                  md="3"
-                >
-                  <v-text-field
-                    v-model.number="offsetX"
-                    label="Offset (x)"
-                    type="number"
-                    step="any"
-                    :readonly="readonly"
-                    :disabled="readonly"
-                    required
-                    :rules="[rules.numericRequired]"
-                    class="m-annotated"
-                    @wheel.prevent
-                  />
-                </v-col>
-                <v-col
-                  cols="12"
-                  md="3"
-                >
-                  <v-text-field
-                    v-model.number="offsetY"
-                    label="Offset (y)"
-                    type="number"
-                    step="any"
-                    :readonly="readonly"
-                    :disabled="readonly"
-                    required
-                    :rules="[rules.numericRequired]"
-                    class="m-annotated"
-                    @wheel.prevent
-                  />
-                </v-col>
-                <v-col
-                  cols="12"
-                  md="3"
-                >
-                  <v-text-field
-                    v-model.number="offsetZ"
-                    label="Offset (z)"
-                    type="number"
-                    step="any"
-                    :readonly="readonly"
-                    :disabled="readonly"
-                    required
-                    :rules="[rules.numericRequired]"
-                    class="m-annotated"
-                    @wheel.prevent
-                  />
-                </v-col>
-              </v-row>
-              <v-row>
-                <v-col>
-                  <v-autocomplete
-                    v-model="mountContact"
-                    :items="contacts"
-                    label="Contact"
-                    clearable
-                    required
-                    :rules="[rules.required]"
-                    :readonly="readonly"
-                    :disabled="readonly"
-                  />
-                </v-col>
-                <v-col>
-                  <v-btn v-if="!readonly" small @click="selectCurrentUserAsMountContact">
-                    Set current user
-                  </v-btn>
-                </v-col>
-              </v-row>
-              <v-row>
-                <v-col cols="12" md="12">
-                  <v-textarea
-                    v-model="mountDescription"
-                    label="Description"
-                    rows="3"
-                    :readonly="readonly"
-                    :disabled="readonly"
-                  />
-                </v-col>
-              </v-row>
-            </v-card-text>
-          </v-form>
-          <div
-            v-if="value && !readonly"
-          >
-            <v-btn @click="overwriteExistingMountAction">
-              Update existing mount
-            </v-btn>
-          </div>
-        </v-expansion-panel-content>
-      </v-expansion-panel>
-      <v-expansion-panel v-if="!readonly">
-        <v-expansion-panel-header class="unmount-expansion-panel">
-          Unmount
-        </v-expansion-panel-header>
-        <v-expansion-panel-content>
-          <ConfigurationsSelectedItemUnmountForm
-            v-if="value"
-            :key="valueKey"
-            :contacts="contacts"
-            :readonly="readonly"
-            :current-user-mail="currentUserMail"
-            @remove="remove"
-          />
-        </v-expansion-panel-content>
-      </v-expansion-panel>
-    </v-expansion-panels>
-  </v-card>
-</template>
-
-<script lang="ts">
-/**
-* @file provides a component to display information about a selected tree node
-* @author <marc.hanisch@gfz-potsdam.de>
-*/
-import { Vue, Component, Prop, Watch, mixins } from 'nuxt-property-decorator'
-import { DateTime } from 'luxon'
-
-// @ts-ignore
-import ConfigurationsSelectedItemUnmountForm from '@/components/ConfigurationsSelectedItemUnmountForm.vue'
-
-import { Contact } from '@/models/Contact'
-
-import { Rules } from '@/mixins/Rules'
-
-import { ConfigurationsTreeNode } from '@/viewmodels/ConfigurationsTreeNode'
-import { DeviceNode } from '@/viewmodels/DeviceNode'
-import { IUnmountData } from '@/viewmodels/IUnmountData'
-import { PlatformNode } from '@/viewmodels/PlatformNode'
-
-import { dateToDateTimeStringHHMM, dateToDateTimeString } from '@/utils/dateHelper'
-
-/**
-* A class component to display information about a selected tree node
-* @extends Vue
-*/
-@Component({
-  components: {
-    ConfigurationsSelectedItemUnmountForm
-  },
-  filters: {
-    dateToDateTimeStringHHMM,
-    dateToDateTimeString
-  }
-})
-// @ts-ignore
-export default class ConfigurationsSelectedItem extends mixins(Rules) {
-  private offsetX: number = 0.0
-  private offsetY: number = 0.0
-  private offsetZ: number = 0.0
-
-  private mountContact: Contact | null = null
-
-  private mountDescription: string = ''
-
-  /**
-   * the selected node
-   */
-  @Prop({
-    default: null,
-    type: Object
-  })
-  // @ts-ignore
-  readonly value: ConfigurationsTreeNode | null
-
-  @Prop({
-    default: DateTime.utc(),
-    type: DateTime
-  })
-  readonly selectedDate!: DateTime
-
-  /**
-   * the breadcrumbs string array
-   */
-  @Prop({
-    default: () => [],
-    type: Array
-  })
-  // @ts-ignore
-  readonly breadcrumbs: string[]
-
-  @Prop({
-    default: () => [],
-    type: Array
-  })
-  readonly contacts!: Contact[]
-
-  /**
-   * whether the component is in readonly mode or not
-   */
-  @Prop({
-    default: false,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly readonly: boolean
-
-  @Prop({
-    type: String
-  })
-  // @ts-ignore
-  readonly currentUserMail: string | null
-
-  /**
-   * returns the description of a node
-   *
-   * @return {string} the description
-   */
-  get description (): string {
-    if (!this.value) {
-      return ''
-    }
-    if (this.value.isPlatform()) {
-      return (this.value as PlatformNode).unpack().platform.description
-    }
-    return (this.value as DeviceNode).unpack().device.description
-  }
-
-  get isMountedOnSelectedDate (): boolean {
-    if (!this.value) {
-      return false
-    }
-    const value = this.value
-    const node = value.unpack()
-    const date = node.date
-    return date.equals(this.selectedDate)
-  }
-
-  get valueKey (): string {
-    if (this.value && this.value.id) {
-      return this.value.id
-    }
-    return 'no-key'
-  }
-
-  /**
-   * triggers a remove event for a node
-   *
-   * @fires ConfigurationsSelectedItem#remove
-   */
-  remove (unmountData: IUnmountData) {
-    /**
-     * fires an input event
-     * @event ConfigurationsSelectedItem#remove
-     * @type {ConfigurationsTreeNode}
-     */
-    this.$emit('remove', this.value, unmountData.contact, unmountData.description)
-  }
-
-  overwriteExistingMountAction () {
-    if (this.validateMountUpdateForm()) {
-      this.$emit(
-        'overwriteExistingMountAction',
-        this.value,
-        {
-          offsetX: this.offsetX,
-          offsetY: this.offsetY,
-          offsetZ: this.offsetZ,
-          contact: this.mountContact,
-          description: this.mountDescription
-        }
-      )
-    } else {
-      this.$store.commit('snackbar/setError', 'Please correct the errors')
-    }
-  }
-
-  selectCurrentUserAsMountContact () {
-    if (this.currentUserMail) {
-      const userIndex = this.contacts.findIndex(c => c.email === this.currentUserMail)
-      if (userIndex > -1) {
-        this.mountContact = this.contacts[userIndex]
-        return
-      }
-    }
-    this.$store.commit('snackbar/setError', 'No contact found with your data')
-  }
-
-  @Watch('value')
-  onValueChange (node: ConfigurationsTreeNode | null) {
-    this.offsetX = node?.unpack().offsetX || 0.0
-    this.offsetY = node?.unpack().offsetY || 0.0
-    this.offsetZ = node?.unpack().offsetZ || 0.0
-    this.mountContact = node?.unpack().contact || null
-    this.mountDescription = node?.unpack().description || ''
-  }
-
-  validateMountUpdateForm (): boolean {
-    return (this.$refs.mountUpdateForm as Vue & { validate: () => boolean }).validate()
-  }
-}
-</script>
-
-<style scoped>
-/* the m-annotated class is to add the unit (meters) to the fields */
-.m-annotated::after {
-  content: " m";
-  white-space: pre;
-}
-</style>
diff --git a/components/ContactSelect.vue b/components/ContactSelect.vue
deleted file mode 100644
index 36caf1d7a672abd7d3329ea3c64101bc5a363d6a..0000000000000000000000000000000000000000
--- a/components/ContactSelect.vue
+++ /dev/null
@@ -1,130 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <EntitySelect
-    v-model="wrappedValue"
-    :readonly="readonly"
-    :fetch-function="findAllContacts"
-    :label="label"
-    color="indigo"
-    avatar-icon="mdi-account-circle"
-  />
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component to select contacts
- * @author <marc.hanisch@gfz-potsdam.de>
- * @author <nils.brinckmann@gfz-potsdam.de>
- */
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import EntitySelect from '@/components/EntitySelect.vue'
-
-import { Contact } from '@/models/Contact'
-
-type ContactsLoaderFunction = () => Promise<Contact[]>
-
-/**
- * A class component to select contacts
- * @extends Vue
- */
-@Component({
-  components: { EntitySelect }
-})
-// @ts-ignore
-export default class ContactSelect extends Vue {
-  private contacts: Contact[] = []
-
-  /**
-   * a list of Contacts
-   */
-  @Prop({
-    default: () => [] as Contact[],
-    required: true,
-    type: Array
-  })
-  // @ts-ignore
-  readonly value!: Contact[]
-
-  /**
-   * whether the component is in readonly mode or not
-   */
-  @Prop({
-    default: false,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly readonly: boolean
-
-  /**
-   * the label of the component
-   */
-  @Prop({
-    required: true,
-    type: String
-  })
-  readonly label!: string
-
-  /**
-   * fetches all contacts from the API
-   *
-   * @return {ContactsLoaderFunction} a function that returns a promise which returns a list of contacts
-   */
-  get findAllContacts (): ContactsLoaderFunction {
-    return () => { return this.$api.contacts.findAll() }
-  }
-
-  /**
-   * returns the list of contacts
-   *
-   * @return {Contact[]} a list of contacts
-   */
-  get wrappedValue () {
-    return this.value
-  }
-
-  /**
-   * triggers an input event when the list of contacts has changed
-   *
-   * @param {Contact[]} newValue - a list of contacts
-   * @fires ContactSelect#input
-   */
-  set wrappedValue (newValue) {
-    /**
-     * fires an input event
-     * @event ContactSelect#input
-     * @type {Contact[]}
-     */
-    this.$emit('input', newValue)
-  }
-}
-</script>
diff --git a/components/CustomFieldCard.vue b/components/CustomFieldCard.vue
deleted file mode 100644
index 0865d587323796bb9db1a8379d6637e7ca4cfc55..0000000000000000000000000000000000000000
--- a/components/CustomFieldCard.vue
+++ /dev/null
@@ -1,91 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-card
-    class="mb-2"
-  >
-    <v-card-text>
-      <v-row
-        no-gutters
-      >
-        <v-col
-          cols="12"
-          md="2"
-        >
-          <label>Key:</label>
-          {{ value.key }}
-        </v-col>
-        <v-col
-          cols="12"
-          md="8"
-        >
-          <label>Value:</label>
-          {{ value.value }}
-        </v-col>
-        <v-col
-          cols="12"
-          md="2"
-          class="text-right"
-          align-self="center"
-        >
-          <slot name="actions" />
-        </v-col>
-      </v-row>
-    </v-card-text>
-  </v-card>
-</template>
-
-<script lang="ts">
-import { Component, Vue, Prop } from 'nuxt-property-decorator'
-
-import { CustomTextField } from '@/models/CustomTextField'
-
-@Component
-export default class CustomFieldCard extends Vue {
-  @Prop({
-    required: true,
-    type: Object
-  })
-  readonly value!: CustomTextField
-
-  get field (): CustomTextField {
-    return this.value
-  }
-
-  set field (value: CustomTextField) {
-    this.$emit('input', value)
-  }
-
-  get deviceId (): string {
-    return this.$route.params.deviceId
-  }
-}
-</script>
diff --git a/components/CustomFieldCardForm.vue b/components/CustomFieldCardForm.vue
deleted file mode 100644
index 0a5ef75520e0008e8dba5d4f23f3576aca3caacd..0000000000000000000000000000000000000000
--- a/components/CustomFieldCardForm.vue
+++ /dev/null
@@ -1,138 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-card
-    class="mb-2"
-  >
-    <v-card-text>
-      <v-row
-        dense
-      >
-        <v-col
-          cols="12"
-          md="2"
-        >
-          <v-text-field
-            ref="keyfield"
-            label="Key"
-            :value="value.key"
-            required
-            class="required"
-            :rules="[rules.required]"
-            @input="update('key', $event)"
-          />
-        </v-col>
-        <v-col
-          cols="12"
-          md="8"
-        >
-          <v-text-field
-            label="Value"
-            :value="value.value"
-            @input="update('value', $event)"
-          />
-        </v-col>
-        <v-col
-          cols="12"
-          md="2"
-          class="text-right"
-          align-self="center"
-        >
-          <slot name="actions" />
-        </v-col>
-      </v-row>
-    </v-card-text>
-  </v-card>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component for a custom field which consists of an key and a value
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Component, Prop, Vue, mixins } from 'nuxt-property-decorator'
-
-import { Rules } from '@/mixins/Rules'
-
-import { CustomTextField } from '@/models/CustomTextField'
-
-/**
- * A class component for a custom field
- * @extends Vue
- */
-@Component
-// @ts-ignore
-export default class CustomFieldCardForm extends mixins(Rules) {
-  /**
-   * a CustomTextField
-   */
-  @Prop({
-    default: () => new CustomTextField(),
-    required: true,
-    type: CustomTextField
-  })
-  // @ts-ignore
-  readonly value!: CustomTextField
-
-  /**
-   * updates a copy of the internal model at a given key and triggers an input event
-   *
-   * @param {string} key - a path to the property to set
-   * @param {string} value - the value to set
-   * @fires CustomFieldForm#input
-   */
-  update (key: string, value: string) {
-    const newObj: CustomTextField = CustomTextField.createFromObject(this.value)
-
-    switch (key) {
-      case 'key':
-        newObj.key = value
-        break
-      case 'value':
-        newObj.value = value
-        break
-      default:
-        throw new TypeError('key ' + key + ' is not valid')
-    }
-
-    /**
-     * input event
-     * @event CustomTextFieldForm#input
-     * @type {CustomTextField}
-     */
-    this.$emit('input', newObj)
-  }
-
-  focus (): void {
-    (this.$refs.keyfield as Vue & { focus: () => void }).focus()
-  }
-}
-</script>
diff --git a/components/CustomFieldCards.vue b/components/CustomFieldCards.vue
deleted file mode 100644
index 246c80fa7c574539af8ebd082d7d8670adc79cca..0000000000000000000000000000000000000000
--- a/components/CustomFieldCards.vue
+++ /dev/null
@@ -1,154 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-form ref="customFieldsForm">
-    <v-btn
-      v-if="!readonly"
-      small
-      color="primary"
-      data-role="add-field"
-      @click="addField"
-    >
-      add Custom Field
-    </v-btn>
-    <br><br>
-    <template
-      v-for="(item, index) in value"
-    >
-      <v-card
-        :key="'customfield-' + index"
-      >
-        <v-card-text>
-          <CustomFieldForm
-            v-model="value[index]"
-            :readonly="readonly"
-          >
-            <template #actions>
-              <v-btn
-                v-if="!readonly"
-                icon
-                color="error"
-                data-role="delete-field"
-                @click="removeField(index)"
-              >
-                <v-icon>
-                  mdi-delete
-                </v-icon>
-              </v-btn>
-            </template>
-          </CustomFieldForm>
-        </v-card-text>
-      </v-card>
-      <br
-        :key="'br-' + index"
-      >
-    </template>
-  </v-form>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component for collections of CustomFieldForms
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import CustomFieldForm from '@/components/CustomFieldForm.vue'
-
-import { CustomTextField } from '@/models/CustomTextField'
-
-/**
- * A class component that lists CustomFieldForms as Cards
- * @extends Vue
- */
-@Component({
-  components: { CustomFieldForm }
-})
-// @ts-ignore
-export default class CustomFieldCards extends Vue {
-  /**
-   * a list of CustomTextFields
-   */
-  @Prop({
-    default: () => [] as CustomTextField[],
-    required: true,
-    type: Array
-  })
-  // @ts-ignore
-  readonly value!: CustomTextField[]
-
-  /**
-   * whether the component is in readonly mode or not
-   */
-  @Prop({
-    default: false,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly readonly: boolean
-
-  /**
-   * adds a new CustomTextField instance and triggers an event
-   *
-   * @fires CustomFieldCards#input
-   */
-  addField () {
-    /**
-     * fires an input event
-     * @event CustomFieldCards#input
-     * @type {CustomTextField[]}
-     */
-    this.$emit('input', [
-      ...this.value,
-      new CustomTextField()
-    ] as CustomTextField[])
-  }
-
-  /**
-   * removes a CustomTextField instance and triggers an event
-   *
-   * @param {CustomTextField} index - the index of the property to remove
-   * @fires CustomFieldCards#input
-   */
-  removeField (index: number) {
-    if (this.value[index]) {
-      const properties = [...this.value] as CustomTextField[]
-      properties.splice(index, 1)
-      /**
-      * Update event
-      * @event CustomFieldCards#input
-      * @type {CustomTextField[]}
-      */
-      this.$emit('input', properties)
-    }
-  }
-}
-</script>
diff --git a/components/DatePicker.vue b/components/DatePicker.vue
deleted file mode 100644
index 1cb4705aab5acde9537e7e5c1999604c18228748..0000000000000000000000000000000000000000
--- a/components/DatePicker.vue
+++ /dev/null
@@ -1,166 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <div>
-    <v-menu
-      v-if="!readonly"
-      v-model="dateMenu"
-      :close-on-content-click="false"
-      :nudge-right="40"
-      transition="scale-transition"
-      offset-y
-      min-width="290px"
-    >
-      <template #activator="{ on, attrs }">
-        <v-text-field
-          :value="getDate()"
-          :rules="rules"
-          v-bind="attrs"
-          :label="label"
-          :clearable="clearable"
-          prepend-icon="mdi-calendar-range"
-          readonly
-          v-on="on"
-          @click:clear="setDate(null)"
-        />
-      </template>
-      <v-date-picker
-        :value="getDate()"
-        first-day-of-week="1"
-        :show-week="true"
-        @input="setDate"
-      />
-    </v-menu>
-    <v-text-field
-      v-else
-      :value="getDate()"
-      :label="label"
-      prepend-icon="mdi-calendar-range"
-      readonly
-      disabled
-    />
-  </div>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component to pick dates from an calendar
- * @author <marc.hanisch@gfz-potsdam.de>
- * @author <nils.brinckmann@gfz-potsdam.de>
- */
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import { DateTime } from 'luxon'
-import { dateToString, stringToDate } from '@/utils/dateHelper'
-
-/**
- * A class component to pick dates from an calendar
- * wraps a v-date-picker
- * @extends Vue
- */
-@Component
-// @ts-ignore
-export default class DatePicker extends Vue {
-  private dateMenu: boolean = false
-
-  /**
-   * a date
-   */
-  @Prop({
-    default: null,
-    type: Object
-  })
-  // @ts-ignore
-  readonly value!: DateTime | null
-
-  /**
-   * the label of the component
-   */
-  @Prop({
-    required: true,
-    type: String
-  })
-  // @ts-ignore
-  readonly label!: string
-
-  /**
-   * a rules array
-   */
-  @Prop({
-    default: () => [],
-    type: Array
-  })
-  // @ts-ignore
-  readonly rules!: []
-
-  /**
-   * whether the component is in readonly mode or not
-   */
-  @Prop({
-    default: false,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly readonly: boolean
-
-  @Prop({
-    default: true,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly clearable: boolean
-
-  /**
-   * returns the date as a string representation
-   *
-   * @return {string} a date as an ISO string
-   */
-  getDate (): string {
-    return dateToString(this.value)
-  }
-
-  /**
-   * triggers an input event when a date was selected or cleared
-   *
-   * @param {string | null} aDate - the selected date from the v-date-picker component
-   * @fires DatePicker#input
-   */
-  setDate (aDate: string | null) {
-    this.dateMenu = false
-    /**
-     * fires an input event
-     * @event DatePicker#input
-     * @type {DateTime}
-     */
-    this.$emit('input', aDate !== null ? stringToDate(aDate) : null)
-  }
-}
-</script>
diff --git a/components/DevicePropertyExpansionPanel.vue b/components/DevicePropertyExpansionPanel.vue
deleted file mode 100644
index 537e9ef2316e955e686a18014a79067c3d211b7c..0000000000000000000000000000000000000000
--- a/components/DevicePropertyExpansionPanel.vue
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-expansion-panel>
-    <v-expansion-panel-header>
-      <v-row no-gutters>
-        <v-col cols="10">
-          {{ value.label | orDefault('unknown property') }}
-        </v-col>
-        <v-col
-          cols="2"
-          align-self="end"
-          class="text-right"
-        >
-          <slot name="actions" />
-        </v-col>
-      </v-row>
-    </v-expansion-panel-header>
-    <v-expansion-panel-content
-      eager
-    >
-      <slot />
-    </v-expansion-panel-content>
-  </v-expansion-panel>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component for collections of DevicePropertyForms
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-import { DeviceProperty } from '@/models/DeviceProperty'
-
-/**
- * A class component that lists DevicePropertyForms as ExpansionPanels
- * @extends Vue
- */
-@Component
-// @ts-ignore
-export default class DevicePropertyExpansionPanel extends Vue {
-  /**
-   * a DeviceProperty
-   */
-  @Prop({
-    required: true,
-    type: Object
-  })
-  // @ts-ignore
-  readonly value!: DeviceProperty
-}
-</script>
diff --git a/components/DevicePropertyExpansionPanels.vue b/components/DevicePropertyExpansionPanels.vue
deleted file mode 100644
index a8f92e524a60c6f48084ac0b0488750b2299b763..0000000000000000000000000000000000000000
--- a/components/DevicePropertyExpansionPanels.vue
+++ /dev/null
@@ -1,298 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-form ref="propertiesForm">
-    <v-btn
-      v-if="!readonly"
-      small
-      color="primary"
-      data-role="add-property"
-      @click="addProperty"
-    >
-      add Property
-    </v-btn>
-    <br><br>
-    <v-expansion-panels
-      v-model="openedPanels"
-      multiple
-    >
-      <v-expansion-panel
-        v-for="(item, index) in value"
-        :key="index"
-      >
-        <v-expansion-panel-header>
-          <v-row no-gutters>
-            <v-col cols="11">
-              Property {{ index+1 }} {{ item.label ? ' - ' + item.label : '' }}
-            </v-col>
-            <v-col
-              cols="1"
-              align-self="end"
-              class="text-right"
-            >
-              <v-menu
-                v-if="!readonly"
-                right
-                offset-y
-              >
-                <template #activator="{ on }">
-                  <v-btn
-                    data-role="property-menu"
-                    icon
-                    small
-                    v-on="on"
-                  >
-                    <v-icon
-                      dense
-                      small
-                    >
-                      mdi-dots-vertical
-                    </v-icon>
-                  </v-btn>
-                </template>
-
-                <v-list
-                  dense
-                >
-                  <v-list-item
-                    data-role="copy-property"
-                    @click="copyProperty(index)"
-                  >
-                    <v-list-item-title>
-                      <v-icon
-                        left
-                        small
-                      >
-                        mdi-content-copy
-                      </v-icon>
-                      Copy
-                    </v-list-item-title>
-                  </v-list-item>
-                  <v-list-item
-                    dense
-                    data-role="delete-property"
-                    @click="removeProperty(index)"
-                  >
-                    <v-list-item-title
-                      class="red--text"
-                    >
-                      <v-icon
-                        left
-                        small
-                        color="red"
-                      >
-                        mdi-delete
-                      </v-icon>
-                      Delete
-                    </v-list-item-title>
-                  </v-list-item>
-                </v-list>
-              </v-menu>
-            </v-col>
-          </v-row>
-        </v-expansion-panel-header>
-        <v-expansion-panel-content>
-          <DevicePropertyForm
-            v-model="value[index]"
-            :readonly="readonly"
-            :compartments="compartments"
-            :sampling-medias="samplingMedias"
-            :properties="properties"
-            :units="units"
-            :measured-quantity-units="measuredQuantityUnits"
-          />
-        </v-expansion-panel-content>
-      </v-expansion-panel>
-    </v-expansion-panels>
-  </v-form>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component for collections of DevicePropertyForms
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import DevicePropertyForm from '@/components/DevicePropertyForm.vue'
-
-import { Compartment } from '@/models/Compartment'
-import { Property } from '@/models/Property'
-import { SamplingMedia } from '@/models/SamplingMedia'
-import { Unit } from '@/models/Unit'
-import { MeasuredQuantityUnit } from '@/models/MeasuredQuantityUnit'
-import { DeviceProperty } from '@/models/DeviceProperty'
-
-/**
- * A class component that lists DevicePropertyForms as ExpansionPanels
- * @extends Vue
- */
-@Component({
-  components: { DevicePropertyForm }
-})
-// @ts-ignore
-export default class DevicePropertyExpansionPanels extends Vue {
-  private openedPanels: number[] = []
-
-  /**
-   * a list of DeviceProperty
-   */
-  @Prop({
-    default: () => [] as DeviceProperty[],
-    required: true,
-    type: Array
-  })
-  // @ts-ignore
-  readonly value!: DeviceProperty[]
-
-  /**
-   * whether the component is in readonly mode or not
-   */
-  @Prop({
-    default: false,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly readonly: boolean
-
-  /**
-   * a list of Compartments
-   */
-  @Prop({
-    default: () => [] as Compartment[],
-    required: true,
-    type: Array
-  })
-  readonly compartments!: Compartment[]
-
-  /**
-   * a list of SamplingMedias
-   */
-  @Prop({
-    default: () => [] as SamplingMedia[],
-    required: true,
-    type: Array
-  })
-  readonly samplingMedias!: SamplingMedia[]
-
-  /**
-   * a list of Properties
-   */
-  @Prop({
-    default: () => [] as Property[],
-    required: true,
-    type: Array
-  })
-  readonly properties!: Property[]
-
-  /**
-   * a list of Units
-   */
-  @Prop({
-    default: () => [] as Unit[],
-    required: true,
-    type: Array
-  })
-  readonly units!: Unit[]
-
-  /**
-   * a list of MeasuredQuantityUnits
-   */
-  @Prop({
-    default: () => [] as MeasuredQuantityUnit[],
-    required: true,
-    type: Array
-  })
-  readonly measuredQuantityUnits!: MeasuredQuantityUnit[]
-
-  /**
-   * adds a new DeviceProperty instance and triggers an input event
-   *
-   * @fires DevicePropertyExpansionPanels#input
-   */
-  addProperty () {
-    /**
-     * Update event
-     * @event DevicePropertyExpansionPanels#input
-     * @type {DeviceProperty[]}
-     */
-    this.$emit('input', [
-      ...this.value,
-      new DeviceProperty()
-    ] as DeviceProperty[])
-
-    this.openedPanels.push(this.value.length)
-    // @TODO: scroll to new property with this.$vuetify.goTo()
-  }
-
-  /**
-   * removes a DeviceProperty instance and triggers an input event
-   *
-   * @param {DeviceProperty} index - the index of the property to remove
-   * @fires DevicePropertyExpansionPanels#input
-   */
-  removeProperty (index: number) {
-    if (this.value[index]) {
-      const properties = [...this.value] as DeviceProperty[]
-      properties.splice(index, 1)
-      /**
-      * Update event
-      * @event DevicePropertyExpansionPanels#input
-      * @type {DeviceProperty[]}
-      */
-      this.$emit('input', properties)
-    }
-  }
-
-  /**
-   * copies a DeviceProperty instance and triggers an input event
-   *
-   * @param {DeviceProperty} index - the index of the property to copy
-   * @fires DevicePropertyExpansionPanels#input
-   */
-  copyProperty (index: number) {
-    if (this.value[index]) {
-      const newProperty = DeviceProperty.createFromObject(this.value[index])
-      newProperty.label += ' (copy)'
-
-      /**
-       * Update event
-       * @event DevicePropertyExpansionPanels#input
-       * @type {DeviceProperty[]}
-       */
-      this.$emit('input', [
-        ...this.value,
-        newProperty
-      ] as DeviceProperty[])
-    }
-  }
-}
-</script>
diff --git a/components/DevicePropertySelect.vue b/components/DevicePropertySelect.vue
deleted file mode 100644
index 79dc26062f7a08a838e666707f75cb7ec7dcf9da..0000000000000000000000000000000000000000
--- a/components/DevicePropertySelect.vue
+++ /dev/null
@@ -1,147 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <EntitySelect
-    v-model="wrappedValue"
-    :readonly="readonly"
-    :fetch-function="getAvailableDeviceProperties"
-    :label="label"
-    color="blue"
-  />
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component to select device properties
- * @author <marc.hanisch@gfz-potsdam.de>
- * @author <nils.brinckmann@gfz-potsdam.de>
- */
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import EntitySelect from '@/components/EntitySelect.vue'
-
-import { DeviceProperty } from '@/models/DeviceProperty'
-
-type DevicePropertysLoaderFunction = () => Promise<DeviceProperty[]>
-
-/**
- * A class component to select deviceProperties
- * @extends Vue
- */
-@Component({
-  components: { EntitySelect }
-})
-// @ts-ignore
-export default class DevicePropertySelect extends Vue {
-  private deviceProperties: DeviceProperty[] = []
-
-  /**
-   * a list of DeviceProperties
-   */
-  @Prop({
-    default: () => [] as DeviceProperty[],
-    required: true,
-    type: Array
-  })
-  // @ts-ignore
-  readonly value!: DeviceProperty[]
-
-  /**
-   * whether the component is in readonly mode or not
-   */
-  @Prop({
-    default: false,
-    type: Boolean
-  })
-  // @ts-ignore
-  readonly readonly: boolean
-
-  /**
-   * the label of the component
-   */
-  @Prop({
-    required: true,
-    type: String
-  })
-  // @ts-ignore
-  readonly label!: string
-
-  /**
-   * a list of DeviceProperties
-   */
-  @Prop({
-    default: () => [] as DeviceProperty[],
-    required: true,
-    type: Array
-  })
-  // @ts-ignore
-  readonly properties!: DeviceProperty[]
-
-  /**
-   * returns a list if DeviceProperties
-   *
-   * the method returns a function which is passed to the EntitySelect component
-   *
-   * @return {DevicePropertysLoaderFunction} a function that returns the list of DeviceProperties
-   */
-  get getAvailableDeviceProperties (): DevicePropertysLoaderFunction {
-    return () => new Promise((resolve) => {
-      resolve(
-        this.properties
-      )
-    })
-  }
-
-  /**
-   * returns the list of DeviceProperties
-   *
-   * @return {DeviceProperty[]} a list of DeviceProperties
-   */
-  get wrappedValue () {
-    return this.value
-  }
-
-  /**
-   * triggers an input event when the list of device properties has changed
-   *
-   * @param {DeviceProperty[]} newValue - a list of DeviceProperties
-   * @fires DevicePropertySelect#input
-   */
-  set wrappedValue (newValue) {
-    /**
-     * fires an input event
-     * @event DevicePropertySelect#input
-     * @type {DeviceProperty[]}
-     */
-    this.$emit('input', newValue)
-  }
-}
-</script>
diff --git a/components/InfoBox.vue b/components/InfoBox.vue
deleted file mode 100644
index 6ccb81ff79d8280ce2917b39d006896fdebb7298..0000000000000000000000000000000000000000
--- a/components/InfoBox.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-alert
-    border="left"
-    colored-border
-    type="info"
-    elevation="2"
-    dismissible
-  >
-    <slot />
-  </v-alert>
-</template>
-
-<script lang="ts">
-/**
- * @file provides a component to show an info text
- * @author <marc.hanisch@gfz-potsdam.de>
- */
-import { Vue, Component } from 'nuxt-property-decorator'
-
-/**
- * A class component to show an info text
- * @extends Vue
- */
-@Component
-// @ts-ignore
-export default class InfoBox extends Vue {
-}
-</script>
diff --git a/components/actions/ActionButtonTray.md b/components/actions/ActionButtonTray.md
deleted file mode 100644
index fbd5d32d3ca88adb07826e25d329106116ffda25..0000000000000000000000000000000000000000
--- a/components/actions/ActionButtonTray.md
+++ /dev/null
@@ -1,43 +0,0 @@
-The action button tray can be used to display an *apply* and a *cancel* button
-for all action forms.
-
-## Usage
-
-### Standard Usage
-
-```vue
-<template>
-  <ActionButtonTray
-    cancel-url="/"
-  />
-</template>
-```
-
-### Disabled Apply Button
-
-The *apply* button can be disabled by providing `true` to the property
-`isSaving`. This is usually used during a asynchronous API action:
-
-```vue
-<template>
-  <ActionButtonTray
-    cancel-url="/"
-    :is-saving="true"
-  />
-</template>
-```
-
-### Hidden Apply Button
-
-The *apply* button can be also hidden by providing `false` to the `show-apply`
-property:
-
-```vue
-<template>
-  <ActionButtonTray
-    cancel-url="/"
-    :show-apply="false"
-  />
-</template>
-```
-
diff --git a/components/actions/ActionButtonTray.vue b/components/actions/ActionButtonTray.vue
deleted file mode 100644
index 93cb5d1df16d6d892856d93fbb92333c87d90469..0000000000000000000000000000000000000000
--- a/components/actions/ActionButtonTray.vue
+++ /dev/null
@@ -1,108 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <div>
-    <v-btn
-      small
-      text
-      nuxt
-      :to="cancelUrl"
-    >
-      cancel
-    </v-btn>
-    <v-btn
-      v-if="showApply"
-      color="green"
-      small
-      :disabled="isSaving"
-      @click="onApplyButtonClick"
-    >
-      apply
-    </v-btn>
-  </div>
-</template>
-
-<script lang="ts">
-import { Component, Prop, Vue } from 'nuxt-property-decorator'
-
-/**
- * A simple button tray with an apply and a cancel button
- *
- * @augments Vue
- */
-@Component
-export default class ActionButtonTray extends Vue {
-  /**
-   * a Nuxt router link for the cancel action
-   */
-  @Prop({
-    type: String,
-    required: true
-  })
-  readonly cancelUrl!: string
-
-  /**
-   * whether the apply button is disabled or not
-   */
-  @Prop({
-    type: Boolean,
-    default: false
-  })
-  readonly isSaving!: boolean
-
-  /**
-   * whether the apply button is hidden or not
-   */
-  @Prop({
-    type: Boolean,
-    default: true
-  })
-  readonly showApply!: boolean
-
-  /**
-   * triggers the apply event when the button is clicked
-   *
-   * @fires ActionButtonTray#apply
-   */
-  onApplyButtonClick (): void {
-    /**
-     * is triggered when the apply button was clicked
-     *
-     * @event apply
-     */
-    this.$emit('apply')
-  }
-}
-</script>
diff --git a/components/actions/ActionCardMenu.md b/components/actions/ActionCardMenu.md
deleted file mode 100644
index d68964fa1fbf49400033495d0dc31f49152522bf..0000000000000000000000000000000000000000
--- a/components/actions/ActionCardMenu.md
+++ /dev/null
@@ -1,49 +0,0 @@
-A menu with action related menu items.
-
-## Usage
-
-### Standard Usage
-
-```vue
-<template>
-  <v-card
-    v-if="showCard"
-  >
-    <v-card-subtitle>
-      <v-row no-gutters>
-        <v-col>
-          A simple card with a menu
-        </v-col>
-        <v-col
-          align-self="end"
-          class="text-right"
-        >
-          <ActionCardMenu
-            :value="action"
-            @delete-menu-item-click="hideCard"
-          />
-        </v-col>
-      </v-row>
-    </v-card-subtitle>
-  </v-card>
-</template>
-
-<script>
-  import { ActionCommonDetails } from '@/models/ActionCommonDetails'
-
-  export default {
-    data () {
-      return {
-        action: new ActionCommonDetails(),
-        showCard: true
-      }
-    },
-    methods: {
-      hideCard: function () {
-        this.showCard = false
-        setTimeout(() => this.showCard = true, 2000)
-      }
-    }
-  }
-</script>
-```
diff --git a/components/actions/ActionCardMenu.vue b/components/actions/ActionCardMenu.vue
deleted file mode 100644
index c2c956b90d29fc473d14ce612378bb6fa46218a0..0000000000000000000000000000000000000000
--- a/components/actions/ActionCardMenu.vue
+++ /dev/null
@@ -1,109 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-menu
-    close-on-click
-    close-on-content-click
-    offset-x
-    left
-    z-index="999"
-  >
-    <template #activator="{ on }">
-      <v-btn
-        data-role="property-menu"
-        icon
-        small
-        v-on="on"
-      >
-        <v-icon dense small>
-          mdi-dots-vertical
-        </v-icon>
-      </v-btn>
-    </template>
-
-    <v-list>
-      <v-list-item
-        dense
-        @click="onDeleteButtonClick"
-      >
-        <v-list-item-content>
-          <v-list-item-title class="red--text">
-            <v-icon
-              left
-              small
-              color="red"
-            >
-              mdi-delete
-            </v-icon>
-            Delete
-          </v-list-item-title>
-        </v-list-item-content>
-      </v-list-item>
-    </v-list>
-  </v-menu>
-</template>
-
-<script lang="ts">
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import { IActionCommonDetails } from '@/models/ActionCommonDetails'
-
-@Component
-/**
- * A component that provides a simple menu for action related user-actions
- *
- * @augments Vue
- */
-export default class ActionCardMenu extends Vue {
-  /**
-   * The action to which the menu relates
-   */
-  @Prop({
-    type: Object,
-    required: true
-  })
-  readonly value!: IActionCommonDetails
-
-  onDeleteButtonClick (): void {
-    /**
-     * is triggered when the user clicks the delete menu item
-     *
-     * @event delete-menu-item-click
-     * @property {IActionCommonDetails} value
-     */
-    this.$emit('delete-menu-item-click', this.value)
-  }
-}
-</script>
diff --git a/components/actions/DeviceActionTimeline.vue b/components/actions/DeviceActionTimeline.vue
index 8b0c793aba091e03262882f92482524a501aaa15..88b04b38b40d4456c43ec56def606e15576a850e 100644
--- a/components/actions/DeviceActionTimeline.vue
+++ b/components/actions/DeviceActionTimeline.vue
@@ -46,98 +46,14 @@ permissions and limitations under the Licence.
       <slot v-if="action.isDeviceCalibrationAction" name="calibration-action" :action="action" :index="index"></slot>
       <slot v-if="action.isDeviceMountAction" name="device-mount-action" :action="action.inner" :index="index"></slot>
       <slot v-if="action.isDeviceUnmountAction" name="device-unmount-action" :action="action.inner" :index="index"></slot>
-<!--      <GenericActionCard-->
-<!--        v-if="action.isGenericAction"-->
-<!--        :value="value[index]"-->
-<!--        :delete-callback="getActionApiDispatcherDeleteMethod(action)"-->
-<!--        :is-user-authenticated="isUserAuthenticated"-->
-<!--        @delete-success="removeActionFromModel"-->
-<!--        @showdelete="$emit('showdelete', $event)"-->
-<!--      >-->
-<!--        <template #actions>-->
-<!--          <v-btn-->
-<!--            v-if="isUserAuthenticated"-->
-<!--            :to="'/devices/' + deviceId + '/actions/generic-device-actions/' + action.id + '/edit'"-->
-<!--            color="primary"-->
-<!--            text-->
-<!--            @click.stop.prevent-->
-<!--          >-->
-<!--            Edit-->
-<!--          </v-btn>-->
-<!--        </template>-->
-<!--      </GenericActionCard>-->
-
-<!--      <SoftwareUpdateActionCard-->
-<!--        v-if="action.isSoftwareUpdateAction"-->
-<!--        target="Device"-->
-<!--        :value="value[index]"-->
-<!--        :delete-callback="getActionApiDispatcherDeleteMethod(action)"-->
-<!--        :is-user-authenticated="isUserAuthenticated"-->
-<!--        @delete-success="removeActionFromModel"-->
-<!--        @showdelete="$emit('showdelete', $event)"-->
-<!--      >-->
-<!--        <template #actions>-->
-<!--          <v-btn-->
-<!--            v-if="isUserAuthenticated"-->
-<!--            :to="'/devices/' + deviceId + '/actions/software-update-actions/' + action.id + '/edit'"-->
-<!--            color="primary"-->
-<!--            text-->
-<!--            @click.stop.prevent-->
-<!--          >-->
-<!--            Edit-->
-<!--          </v-btn>-->
-<!--        </template>-->
-<!--      </SoftwareUpdateActionCard>-->
-
-<!--      <DeviceCalibrationActionCard-->
-<!--        v-if="action.isDeviceCalibrationAction"-->
-<!--        :value="value[index]"-->
-<!--        :delete-callback="getActionApiDispatcherDeleteMethod(action)"-->
-<!--        :is-user-authenticated="isUserAuthenticated"-->
-<!--        @delete-success="removeActionFromModel"-->
-<!--        @showdelete="$emit('showdelete', $event)"-->
-<!--      >-->
-<!--        <template #actions>-->
-<!--          <v-btn-->
-<!--            v-if="isUserAuthenticated"-->
-<!--            :to="'/devices/' + deviceId + '/actions/device-calibration-actions/' + action.id + '/edit'"-->
-<!--            color="primary"-->
-<!--            text-->
-<!--            @click.stop.prevent-->
-<!--          >-->
-<!--            Edit-->
-<!--          </v-btn>-->
-<!--        </template>-->
-<!--      </DeviceCalibrationActionCard>-->
-
-<!--      <DeviceMountActionCard-->
-<!--        v-if="action.isDeviceMountAction"-->
-<!--        v-model="action.inner"-->
-<!--      />-->
-
-<!--      <DeviceUnmountActionCard-->
-<!--        v-if="action.isDeviceUnmountAction"-->
-<!--        v-model="action.inner"-->
-<!--      />-->
     </v-timeline-item>
   </v-timeline>
 </template>
 
 <script lang="ts">
 import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import GenericActionCard from '@/components/actions/GenericActionCard.vue'
-import SoftwareUpdateActionCard from '@/components/actions/SoftwareUpdateActionCard.vue'
-import DeviceCalibrationActionCard from '@/components/actions/DeviceCalibrationActionCard.vue'
-import DeviceMountActionCard from '@/components/actions/DeviceMountActionCard.vue'
-import DeviceUnmountActionCard from '@/components/actions/DeviceUnmountActionCard.vue'
-
+import { getActionColor} from '@/modelUtils/actionHelpers'
 import { IActionCommonDetails } from '@/models/ActionCommonDetails'
-import {
-  getActionColor,
-  IActionApiDispatcher,
-  ActionApiDeleteMethod
-} from '@/modelUtils/actionHelpers'
 
 /**
  * A component to display Device related actions in a timeline
@@ -145,14 +61,6 @@ import {
  * The component offers the following properties:
  *
  * * value - an Array of actions
- * * deviceId - the id of the device the actions belong to
- * * actionApiDispatcher - an object that returns the methods that are required
- * to modifiy the actions (for example via an Api)
- *
- * The component triggers the following events:
- *
- * * input - the Array of actions was altered (for example because of an action
- * that was deleted)
  *
  * @augments Vue
  */
@@ -168,83 +76,5 @@ export default class DeviceActionTimeline extends Vue {
     type: Array
   })
   readonly value!: IActionCommonDetails[]
-  //
-  // @Prop({
-  //   type: String,
-  //   required: true
-  // })
-  // readonly deviceId!: string
-  //
-  // /**
-  //  * an object that dispatches Api methods to handle actions
-  //  */
-  // @Prop({
-  //   default: null,
-  //   required: false,
-  //   type: Object
-  // })
-  // // @ts-ignore
-  // readonly actionApiDispatcher!: IActionApiDispatcher | null
-  //
-  // @Prop({
-  //   type: Boolean,
-  //   required: true
-  // })
-  // readonly isUserAuthenticated!: boolean
-  //
-  // getActionTypeIterationKey (action: IActionCommonDetails): string {
-  //   return this.getActionType(action) + '-' + action.id
-  // }
-  //
-  // getActionType (action: IActionCommonDetails): string {
-  //   switch (true) {
-  //     case 'isGenericAction' in action:
-  //       return 'generic-action'
-  //     case 'isSoftwareUpdateAction' in action:
-  //       return 'software-update-action'
-  //     case 'isDeviceCalibrationAction' in action:
-  //       return 'device-calibration-action'
-  //     case 'isDeviceMountAction' in action:
-  //       return 'device-mount-action'
-  //     case 'isDeviceUnmountAction' in action:
-  //       return 'device-unmount-action'
-  //     default:
-  //       return 'unknown-action'
-  //   }
-  // }
-  //
-  // /**
-  //  * removes the action from the model and triggers the input event with the
-  //  * updated model
-  //  *
-  //  * @param {IActionCommonDetails} action - the action to remove
-  //  * @fires DeviceActionTimeline#input
-  //  */
-  // removeActionFromModel (action: IActionCommonDetails) {
-  //   const actions: IActionCommonDetails[] = [...this.value]
-  //   const actionIndex: number = actions.findIndex(someAction => someAction === action)
-  //   if (actionIndex > -1) {
-  //     actions.splice(actionIndex, 1)
-  //   }
-  //   /**
-  //    * fires an input event
-  //    * @event DeviceActionTimeline#input
-  //    * @type {IActionCommonDetails[]}
-  //    */
-  //   this.$emit('input', actions)
-  // }
-  //
-  // /**
-  //  * returns the Api method to delete the specific action, if available
-  //  *
-  //  * @param {IActionCommonDetails} action - the action to get the delete method for
-  //  * @return {ActionApiDeleteMethod | undefined} an Api method to delete the action
-  //  */
-  // getActionApiDispatcherDeleteMethod (action: IActionCommonDetails): ActionApiDeleteMethod | undefined {
-  //   if (!this.actionApiDispatcher) {
-  //     return
-  //   }
-  //   return this.actionApiDispatcher.getDeleteMethod(action)
-  // }
 }
 </script>
diff --git a/components/configurations/ConfigurationsBasicSearch.vue b/components/configurations/ConfigurationsBasicSearch.vue
deleted file mode 100644
index 0789c768b2de02e9a634ed7c1b834b936c42d709..0000000000000000000000000000000000000000
--- a/components/configurations/ConfigurationsBasicSearch.vue
+++ /dev/null
@@ -1,107 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-row>
-    <v-col cols="12" md="5">
-      <v-text-field
-        v-model="searchTextModel"
-        label="Label"
-        placeholder="Label of configuration"
-        hint="Please enter at least 3 characters"
-        @keydown.enter="emitSearch"
-      />
-    </v-col>
-    <v-col
-      cols="12"
-      md="7"
-      align-self="center"
-    >
-      <v-btn
-        color="primary"
-        small
-        @click="emitSearch"
-      >
-        Search
-      </v-btn>
-      <v-btn
-        text
-        small
-        @click="clearSearch"
-      >
-        Clear
-      </v-btn>
-    </v-col>
-  </v-row>
-</template>
-
-<script lang="ts">
-import { Component, Vue, Prop } from 'nuxt-property-decorator'
-
-import { IConfigurationBasicSearchParams } from '@/modelUtils/ConfigurationSearchParams'
-
-@Component
-export default class ConfigurationsBasicSearch extends Vue {
-  @Prop({
-    default: '',
-    required: false,
-    type: String
-  })
-  private readonly searchText!: string
-
-  private internalSearchText: string | null = null
-
-  get searchTextModel (): string | null {
-    return this.internalSearchText || this.searchText
-  }
-
-  set searchTextModel (value: string | null) {
-    this.internalSearchText = value
-  }
-
-  emitSearch () {
-    this.$emit('search', {
-      searchText: this.searchTextModel
-    } as IConfigurationBasicSearchParams)
-  }
-
-  clearSearch () {
-    this.searchTextModel = null
-  }
-}
-</script>
-
-<style scoped>
-
-</style>
diff --git a/components/configurations/ConfigurationsDownloader.vue b/components/configurations/ConfigurationsDownloader.vue
deleted file mode 100644
index 1579b0d032666add3d01e52cd3be39e16744618f..0000000000000000000000000000000000000000
--- a/components/configurations/ConfigurationsDownloader.vue
+++ /dev/null
@@ -1,102 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-menu
-    close-on-click
-    close-on-content-click
-    offset-x
-    left
-    z-index="999"
-  >
-    <template #activator="{ on }">
-      <v-btn
-        icon
-        v-on="on"
-      >
-        <v-icon
-          dense
-        >
-          mdi-file-download
-        </v-icon>
-      </v-btn>
-    </template>
-    <v-list>
-      <v-list-item
-        dense
-        @click.prevent="exportCsv"
-      >
-        <v-list-item-content>
-          <v-list-item-title>
-            <v-icon
-              left
-            >
-              mdi-table
-            </v-icon>
-            CSV
-          </v-list-item-title>
-        </v-list-item-content>
-      </v-list-item>
-    </v-list>
-  </v-menu>
-</template>
-
-<script lang="ts">
-import { Component, Prop, Vue } from 'nuxt-property-decorator'
-
-import { saveAs } from 'file-saver'
-
-import { ConfigurationSearcher } from '@/services/sms/ConfigurationApi'
-
-@Component
-export default class ConfigurationsDownloader extends Vue {
-  @Prop({
-    required: true,
-    type: Object
-  })
-  readonly lastActiveSearcher!: ConfigurationSearcher
-
-  exportCsv () { // TODO lastActiveSearcher ist nur noch in der ConfigurationsSearch
-    this.lastActiveSearcher.findMatchingAsCsvBlob().then((blob) => {
-      saveAs(blob, 'configurations.csv')
-    }).catch((_err) => {
-      this.$store.commit('snackbar/setError', 'CSV export failed')
-    })
-  }
-}
-</script>
-
-<style scoped>
-
-</style>
diff --git a/components/configurations/ConfigurationsExtendedSearch.vue b/components/configurations/ConfigurationsExtendedSearch.vue
deleted file mode 100644
index 6fc1e05ad9e8289055a0cfcc6693e2e296c01a2b..0000000000000000000000000000000000000000
--- a/components/configurations/ConfigurationsExtendedSearch.vue
+++ /dev/null
@@ -1,184 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <div>
-    <v-row>
-      <v-col cols="12" md="6">
-        <v-text-field
-          v-model="searchTextModel"
-          label="Label"
-          placeholder="Label of configuration"
-          hint="Please enter at least 3 characters"
-          @keydown.enter="emitSearch"
-        />
-      </v-col>
-    </v-row>
-    <v-row>
-      <v-col cols="12" md="3">
-        <StringSelect
-          v-model="selectedConfigurationStatesModel"
-          label="Select a status"
-          :items="configurationStates"
-          color="green"
-        />
-      </v-col>
-    </v-row>
-    <v-row>
-      <v-col cols="12" md="3">
-        <ProjectSelect
-          v-model="selectedProjectsModel"
-          label="Select a project"
-        />
-      </v-col>
-    </v-row>
-    <v-row>
-      <v-col
-        cols="12"
-        align-self="center"
-      >
-        <v-btn
-          color="primary"
-          small
-          @click="emitSearch"
-        >
-          Search
-        </v-btn>
-        <v-btn
-          text
-          small
-          @click="clearSearch"
-        >
-          Clear
-        </v-btn>
-      </v-col>
-    </v-row>
-  </div>
-</template>
-
-<script lang="ts">
-import { Component, Vue, Prop } from 'nuxt-property-decorator'
-
-import { Project } from '@/models/Project'
-
-import { IConfigurationSearchParams } from '@/modelUtils/ConfigurationSearchParams'
-
-import ProjectSelect from '@/components/ProjectSelect.vue'
-import StringSelect from '@/components/StringSelect.vue'
-
-@Component({
-  components: {
-    StringSelect,
-    ProjectSelect
-  }
-})
-export default class ConfigurationsExtendedSearch extends Vue {
-  @Prop({
-    default: '',
-    required: false,
-    type: String
-  })
-  private readonly searchText!: string
-
-  @Prop({
-    default: () => [],
-    required: false,
-    type: Array
-  })
-  private readonly selectedConfigurationStates!: string[]
-
-  @Prop({
-    default: () => [],
-    required: false,
-    type: Array
-  })
-  private readonly selectedProjects!: Project[]
-
-  private internalSearchText: string | null = null
-  private internalSelectedConfigurationStates: string[] = []
-  private internalSelectedProjects: Project[] = []
-
-  private configurationStates: string[] = []
-
-  mounted () {
-    this.$api.configurationStates.findAll().then((foundStates) => {
-      this.configurationStates = foundStates
-    }).catch((_error) => {
-      this.$store.commit('snackbar/setError', 'Loading configuration states failed')
-    })
-  }
-
-  get searchTextModel (): string | null {
-    return this.internalSearchText || this.searchText
-  }
-
-  set searchTextModel (value: string | null) {
-    this.internalSearchText = value
-  }
-
-  get selectedConfigurationStatesModel (): string[] {
-    return this.internalSelectedConfigurationStates.length ? this.internalSelectedConfigurationStates : this.selectedConfigurationStates
-  }
-
-  set selectedConfigurationStatesModel (value: string[]) {
-    this.internalSelectedConfigurationStates = value
-  }
-
-  get selectedProjectsModel (): Project[] {
-    return this.internalSelectedProjects.length ? this.internalSelectedProjects : this.selectedProjects
-  }
-
-  set selectedProjectsModel (value: Project[]) {
-    this.internalSelectedProjects = value
-  }
-
-  emitSearch () {
-    this.$emit('search', {
-      searchText: this.searchTextModel,
-      states: this.selectedConfigurationStatesModel,
-      projects: this.selectedProjectsModel
-    } as IConfigurationSearchParams)
-  }
-
-  clearSearch () {
-    this.searchTextModel = null
-    this.selectedConfigurationStatesModel = []
-    this.selectedProjectsModel = []
-  }
-}
-</script>
-
-<style scoped>
-
-</style>
diff --git a/components/configurations/ConfigurationsOverviewCard.vue b/components/configurations/ConfigurationsOverviewCard.vue
deleted file mode 100644
index bc6d6b96e21e3ea90de02bf3a5b54aede09eb837..0000000000000000000000000000000000000000
--- a/components/configurations/ConfigurationsOverviewCard.vue
+++ /dev/null
@@ -1,230 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <v-hover>
-    <template #default="{ hover }">
-      <v-card
-        :elevation="hover ? 6:2"
-        class="ma-2"
-      >
-        <v-card-text
-          @click.stop.prevent="toggleExapansion"
-        >
-          <v-row
-            no-gutters
-          >
-            <v-col>
-              <StatusBadge
-                :value="configuration.status"
-              >
-                <div class="text-caption">
-                  {{ configuration.projectName || 'no project' }}
-                </div>
-              </StatusBadge>
-            </v-col>
-            <v-col
-              align-self="end"
-              class="text-right"
-            >
-              <DotMenu>
-                <template #actions>
-                  <DotMenuActionDelete
-                    :readonly="!isUserAuthenticated"
-                    @click="$emit('showDeleteDialog',configuration)"
-                  />
-                </template>
-              </DotMenu>
-            </v-col>
-          </v-row>
-          <v-row
-            no-gutters
-          >
-            <v-col class="text-subtitle-1">
-              {{ getTextOrDefault(configuration.label, 'Configuration') }}
-            </v-col>
-            <v-col
-              align-self="end"
-              class="text-right"
-            >
-              <v-btn
-                nuxt
-                :to="'/configurations/' + configuration.id"
-                color="primary"
-                text
-                @click.stop.prevent
-              >
-                View
-              </v-btn>
-              <v-btn
-                icon
-                @click.stop.prevent="toggleExapansion"
-              >
-                <v-icon>{{ isExpanded ? 'mdi-chevron-up' : 'mdi-chevron-down' }}</v-icon>
-              </v-btn>
-            </v-col>
-          </v-row>
-        </v-card-text>
-        <v-expand-transition>
-          <v-card
-            v-show="isExpanded"
-            flat
-            tile
-            color="grey lighten-5"
-          >
-            <v-card-text>
-              <v-row
-                dense
-              >
-                <v-col
-                  cols="4"
-                  xs="4"
-                  sm="3"
-                  md="2"
-                  lg="2"
-                  xl="1"
-                  class="font-weight-medium"
-                >
-                  Start:
-                </v-col>
-                <v-col
-                  cols="8"
-                  xs="8"
-                  sm="9"
-                  md="4"
-                  lg="4"
-                  xl="5"
-                  class="nowrap-truncate"
-                >
-                  {{ configuration.startDate | dateToDateTimeString }}
-                  <span
-                    v-if="configuration.startDate"
-                    class="text-caption text--secondary"
-                  >
-                    (UTC)
-                  </span>
-                </v-col>
-                <v-col
-                  cols="4"
-                  xs="4"
-                  sm="3"
-                  md="2"
-                  lg="2"
-                  xl="1"
-                  class="font-weight-medium"
-                >
-                  End:
-                </v-col>
-                <v-col
-                  cols="8"
-                  xs="8"
-                  sm="9"
-                  md="4"
-                  lg="4"
-                  xl="5"
-                  class="nowrap-truncate"
-                >
-                  {{ configuration.endDate | dateToDateTimeString }}
-                  <span
-                    v-if="configuration.endDate"
-                    class="text-caption text--secondary"
-                  >
-                    (UTC)
-                  </span>
-                </v-col>
-              </v-row>
-            </v-card-text>
-          </v-card>
-        </v-expand-transition>
-      </v-card>
-    </template>
-  </v-hover>
-</template>
-
-<script lang="ts">
-import { Component, Prop, Vue } from 'nuxt-property-decorator'
-
-import { Configuration } from '@/models/Configuration'
-import { DynamicLocation, LocationType, StationaryLocation } from '@/models/Location'
-
-import { dateToDateTimeString } from '@/utils/dateHelper'
-
-import StatusBadge from '@/components/StatusBadge.vue'
-import DotMenu from '@/components/DotMenu.vue'
-import DotMenuActionDelete from '@/components/DotMenuActionDelete.vue'
-
-@Component({
-  filters: { dateToDateTimeString },
-  components: {
-    DotMenuActionDelete,
-    DotMenu,
-    StatusBadge
-  }
-})
-export default class ConfigurationsOverviewCard extends Vue {
-  @Prop({
-    required: true,
-    type: Object
-  })
-  readonly configuration!: Configuration
-
-  @Prop({
-    type: Boolean,
-    required: true
-  })
-  readonly isUserAuthenticated!: boolean
-
-  private isExpanded: boolean = false
-
-  getLocationType (configuration: Configuration): string {
-    if (configuration.location instanceof StationaryLocation) {
-      return LocationType.Stationary
-    }
-    if (configuration.location instanceof DynamicLocation) {
-      return LocationType.Dynamic
-    }
-    return ''
-  }
-
-  toggleExapansion () {
-    this.isExpanded = !this.isExpanded
-  }
-
-  getTextOrDefault = (text: string, defaultValue: string): string => text || defaultValue
-}
-</script>
-
-<style scoped>
-
-</style>
diff --git a/components/configurations/ConfigurationsSearch.vue b/components/configurations/ConfigurationsSearch.vue
deleted file mode 100644
index cbd7f520c0dad6b4fd3aeef764b6b9ee74eefe97..0000000000000000000000000000000000000000
--- a/components/configurations/ConfigurationsSearch.vue
+++ /dev/null
@@ -1,421 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <div>
-    <v-tabs-items
-      v-model="activeTab"
-    >
-      <v-tab-item :eager="true">
-        <ConfigurationsBasicSearch
-          :search-text="searchText"
-          @search="basicSearch"
-        />
-      </v-tab-item>
-      <v-tab-item :eager="true">
-        <ConfigurationsExtendedSearch
-          :search-text="searchText"
-          :selected-projects="selectedProjects"
-          :selected-configuration-states="selectedConfigurationStates"
-          @search="extendedSearch"
-        />
-      </v-tab-item>
-    </v-tabs-items>
-
-    <v-progress-circular
-      v-if="loading"
-      class="progress-spinner"
-      color="primary"
-      indeterminate
-    />
-
-    <div v-if="!totalCount && !loading">
-      <p class="text-center">
-        There are no configurations that match your search criteria.
-      </p>
-    </div>
-
-    <div
-      v-if="totalCount"
-    >
-      <v-subheader>
-        {{ numbersFoundMessage }}
-        <v-spacer />
-
-        <ConfigurationsDownloader
-          v-if="lastActiveSearcher != null"
-          :last-active-searcher="lastActiveSearcher"
-        />
-      </v-subheader>
-
-      <v-pagination
-        :value="page"
-        :disabled="loading"
-        :length="numberOfPages"
-        :total-visible="7"
-        @input="loadAndSetPage"
-      />
-      <ConfigurationsOverviewCard
-        v-for="result in getSearchResultForPage(page)"
-        :key="result.id"
-        :configuration="result"
-        :is-user-authenticated="$auth.loggedIn"
-        @showDeleteDialog="initDeleteDialog"
-      />
-      <v-pagination
-        :value="page"
-        :disabled="loading"
-        :length="numberOfPages"
-        :total-visible="7"
-        @input="loadAndSetPage"
-      />
-    </div>
-    <ConfigurationsDeleteDialog
-      v-model="showDeleteDialog"
-      :configuration-to-delete="configurationToDelete"
-      @cancel-deletion="closeDialog"
-      @submit-deletion="deleteAndCloseDialog"
-    />
-  </div>
-</template>
-
-<script lang="ts">
-import { Component, Prop, Vue } from 'nuxt-property-decorator'
-
-import { Project } from '@/models/Project'
-import { Configuration } from '@/models/Configuration'
-
-import { IPaginationLoader } from '@/utils/PaginatedLoader'
-
-import { ConfigurationSearcher } from '@/services/sms/ConfigurationApi'
-
-import { QueryParams } from '@/modelUtils/QueryParams'
-import {
-  IConfigurationSearchParams,
-  ConfigurationSearchParamsSerializer,
-  IConfigurationBasicSearchParams
-} from '@/modelUtils/ConfigurationSearchParams'
-
-import ConfigurationsBasicSearch from '@/components/configurations/ConfigurationsBasicSearch.vue'
-import ConfigurationsDeleteDialog from '@/components/configurations/ConfigurationsDeleteDialog.vue'
-import ConfigurationsDownloader from '@/components/configurations/ConfigurationsDownloader.vue'
-import ConfigurationsExtendedSearch from '@/components/configurations/ConfigurationsExtendedSearch.vue'
-import ConfigurationsOverviewCard from '@/components/configurations/ConfigurationsOverviewCard.vue'
-
-export type PaginatedResult = {
-  [page: number]: Configuration[]
-}
-
-export type ConfigurationCallbackFunc = (value: Configuration) => Promise<void>
-
-@Component({
-  components: {
-    ConfigurationsBasicSearch,
-    ConfigurationsDeleteDialog,
-    ConfigurationsDownloader,
-    ConfigurationsExtendedSearch,
-    ConfigurationsOverviewCard
-  }
-})
-export default class ConfigurationsSearch extends Vue {
-  private totalCount: number = 0
-  private lastActiveSearcher: ConfigurationSearcher | null = null
-  private loader: null | IPaginationLoader<Configuration> = null
-  private loading: boolean = true
-  private page: number = 0
-  private pageSize: number = 20
-  private searchResults: PaginatedResult = {}
-
-  private showDeleteDialog: boolean = false
-  private configurationToDelete: Configuration | null = null
-
-  private searchText: string = ''
-  private selectedProjects: Project[] = []
-  private selectedConfigurationStates: string[] = []
-
-  private projects: Project[] = []
-  private configurationStates: string[] = []
-
-  @Prop({
-    default: 0,
-    required: false,
-    type: Number
-  })
-  readonly activeTab!: number
-
-  @Prop({
-    default: true,
-    required: false,
-    type: Boolean
-  })
-  private loadInitialData!: boolean
-
-  @Prop({
-    required: false,
-    type: Function
-  })
-  readonly deleteCallback!: undefined | ConfigurationCallbackFunc
-
-  async mounted () {
-    await this.fetchEntities()
-    this.initSearchQueryParams(this.$route.query)
-    if (this.loadInitialData) {
-      this.runInitialSearch()
-    }
-  }
-
-  async fetchEntities (): Promise<void> {
-    try {
-      const [configurationStates, projects] = await Promise.all([
-        this.$api.configurationStates.findAll(),
-        this.$api.projects.findAll()
-      ])
-      this.configurationStates = configurationStates
-      this.projects = projects
-    } catch (_error) {
-      this.$store.commit('snackbar/setError', 'Loading of entities failed')
-    }
-  }
-
-  get numbersFoundMessage () {
-    let message = ''
-    if (this.totalCount === 1) {
-      message = '1 configuration found'
-    }
-    if (this.totalCount > 1) {
-      message = `${this.totalCount} configurations found`
-    }
-    return message
-  }
-
-  isExtendedSearch (): boolean {
-    return !!this.selectedConfigurationStates.length || !!this.selectedProjects.length
-  }
-
-  async runInitialSearch (): Promise<void> {
-    this.$emit('change-active-tab', this.isExtendedSearch() ? 1 : 0)
-
-    const page: number | undefined = this.getPageFromUrl()
-
-    await this.runSearch(
-      {
-        searchText: this.searchText,
-        states: this.selectedConfigurationStates,
-        projects: this.selectedProjects
-      },
-      page
-    )
-  }
-
-  basicSearch (searchParams: IConfigurationBasicSearchParams): Promise<void> {
-    return this.runSearch({
-      ...searchParams,
-      states: [],
-      projects: []
-    })
-  }
-
-  extendedSearch (searchParams: IConfigurationSearchParams): Promise<void> {
-    return this.runSearch(searchParams)
-  }
-
-  async runSearch (
-    searchParams: IConfigurationSearchParams,
-    page: number = 1
-  ) {
-    this.initUrlQueryParams(searchParams)
-
-    this.totalCount = 0
-    this.loading = true
-    this.searchResults = {}
-    this.loader = null
-
-    this.lastActiveSearcher = this.$api.configurations
-      .newSearchBuilder()
-      .withText(searchParams.searchText)
-      .withOneStatusOf(searchParams.states)
-      .withOneMatchingProjectOf(searchParams.projects)
-      .build()
-
-    try {
-      this.loader = await this.lastActiveSearcher.findMatchingAsPaginationLoaderOnPage(page, this.pageSize)
-      this.searchResults[page] = this.loader.elements
-      this.totalCount = this.loader.totalCount
-      this.page = page
-      this.setPageInUrl(page)
-    } catch (_error) {
-      this.$store.commit('snackbar/setError', 'Loading of configurations failed')
-    } finally {
-      this.loading = false
-    }
-  }
-
-  async loadPage (pageNr: number, useCache: boolean = true) {
-    // use the results that were already loaded if available
-    if (useCache && this.searchResults[pageNr]) {
-      return
-    }
-    if (this.loader != null && this.loader.funToLoadPage != null) {
-      try {
-        this.loading = true
-        const loader = await this.loader.funToLoadPage(pageNr)
-        this.loader = loader
-        this.searchResults[pageNr] = loader.elements
-        this.totalCount = loader.totalCount
-      } catch (_error) {
-        this.$store.commit('snackbar/setError', 'Loading of configurations failed')
-      } finally {
-        this.loading = false
-      }
-    }
-  }
-
-  get numberOfPages (): number {
-    return Math.ceil(this.totalCount / this.pageSize)
-  }
-
-  async loadAndSetPage (page: number, useCache: boolean = true) {
-    await this.loadPage(page, useCache)
-    this.page = page
-    this.setPageInUrl(page, false)
-  }
-
-  getSearchResultForPage (pageNr: number): Configuration[] | undefined {
-    return this.searchResults[pageNr]
-  }
-
-  initDeleteDialog (configuration: Configuration) {
-    this.showDeleteDialog = true
-    this.configurationToDelete = configuration
-  }
-
-  closeDialog () {
-    this.showDeleteDialog = false
-    this.configurationToDelete = null
-  }
-
-  async deleteAndCloseDialog () {
-    if (this.configurationToDelete === null) {
-      this.closeDialog()
-      return
-    }
-    if (!this.deleteCallback || typeof this.deleteCallback !== 'function') {
-      this.closeDialog()
-      return
-    }
-    this.loading = true
-    try {
-      await this.deleteCallback(this.configurationToDelete)
-      this.closeDialog()
-      // if we know that the deleted device was the last of the page, we
-      // decrement the page by one
-      let page = this.page
-      if (this.getSearchResultForPage(page)?.length === 1) {
-        page = page > 1 ? page - 1 : 1
-      }
-      this.loadAndSetPage(page, false)
-    } finally {
-      this.loading = false
-    }
-  }
-
-  initSearchQueryParams (params: QueryParams): void {
-    const searchParamsObject = (new ConfigurationSearchParamsSerializer({
-      states: this.configurationStates,
-      projects: this.projects
-    })).toSearchParams(params)
-
-    // prefill the form by the serialized search params from the URL
-    if (searchParamsObject.searchText) {
-      this.searchText = searchParamsObject.searchText
-    }
-    if (searchParamsObject.projects) {
-      this.selectedProjects = searchParamsObject.projects
-    }
-    if (searchParamsObject.states) {
-      this.selectedConfigurationStates = searchParamsObject.states
-    }
-  }
-
-  initUrlQueryParams (params: IConfigurationSearchParams): void {
-    this.$router.push({
-      query: (new ConfigurationSearchParamsSerializer()).toQueryParams(params),
-      hash: this.$route.hash
-    })
-  }
-
-  getPageFromUrl (): number | undefined {
-    if ('page' in this.$route.query && typeof this.$route.query.page === 'string') {
-      return parseInt(this.$route.query.page) || 0
-    }
-  }
-
-  setPageInUrl (page: number, preserveHash: boolean = true): void {
-    let query: QueryParams = {}
-    if (page) {
-      // add page to the current url params
-      query = {
-        ...this.$route.query,
-        page: String(page)
-      }
-    } else {
-      // remove page from the current url params
-      const {
-        // eslint-disable-next-line
-        page,
-        ...params
-      } = this.$route.query
-      query = params
-    }
-    this.$router.push({
-      query,
-      hash: preserveHash ? this.$route.hash : ''
-    })
-  }
-}
-</script>
-
-<style lang="scss">
-@import "@/assets/styles/_search.scss";
-.progress-spinner {
-  position: absolute;
-  top: 40vh;
-  left: 0;
-  right: 0;
-  margin-left: auto;
-  margin-right: auto;
-  width: 32px;
-  z-index: 99;
-}
-</style>
diff --git a/components/configurations/DynamicLocationRow.vue b/components/configurations/DynamicLocationRow.vue
deleted file mode 100644
index 812a72c9c77c04d29820363239ddba0b52ddfa57..0000000000000000000000000000000000000000
--- a/components/configurations/DynamicLocationRow.vue
+++ /dev/null
@@ -1,146 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <div>
-    <v-row v-if="!readonly">
-      <v-col cols="12" md="3">
-        <device-property-hierarchy-select
-          :value="configuration.location.latitude"
-          :devices="getAllDevices()"
-          device-select-label="Device that measures latitude"
-          property-select-label="Measured quantity for latitude"
-          :readonly="readonly"
-          @input="updateLatitude"
-        />
-      </v-col>
-      <v-col cols="12" md="3">
-        <device-property-hierarchy-select
-          :value="configuration.location.longitude"
-          :devices="getAllDevices()"
-          device-select-label="Device that measures longitude"
-          property-select-label="Measured quantity for longitude"
-          :readonly="readonly"
-          @input="updateLongitude"
-        />
-      </v-col>
-      <v-col cols="12" md="3">
-        <device-property-hierarchy-select
-          :value="configuration.location.elevation"
-          :devices="getAllDevices()"
-          device-select-label="Device that measures elevation"
-          property-select-label="Measured quantity for elevation"
-          :readonly="readonly"
-          @input="updateElevation"
-        />
-      </v-col>
-    </v-row>
-    <v-row v-else>
-      <v-col cols="12" md="3">
-        <label>Latitude</label>
-        <span v-if="configuration.location.latitude">
-          {{ configuration.location.latitude.propertyName }}
-        </span>
-      </v-col>
-      <v-col cols="12" md="3">
-        <label>Longitude</label>
-        <span v-if="configuration.location.longitude">
-          {{ configuration.location.longitude.propertyName }}
-        </span>
-      </v-col>
-      <v-col cols="12" md="3">
-        <label>Elevation</label>
-        <span v-if="configuration.location.elevation">
-          {{ configuration.location.elevation.propertyName }}
-        </span>
-      </v-col>
-    </v-row>
-  </div>
-</template>
-
-<script lang="ts">
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import { Configuration } from '@/models/Configuration'
-import { Device } from '@/models/Device'
-import { DeviceProperty } from '@/models/DeviceProperty'
-import { IDynamicLocation } from '@/models/Location'
-
-import DevicePropertyHierarchySelect from '@/components/DevicePropertyHierarchySelect.vue'
-
-@Component({
-  components: { DevicePropertyHierarchySelect }
-})
-export default class DynamicLocationRow extends Vue {
-  @Prop({ default: false, type: Boolean }) readonly readonly!: boolean
-  @Prop({ default: false, type: Configuration }) configuration!: Configuration
-
-  getAllDevices (): Device[] {
-    const result = []
-    const alreadyAddedDeviceIds = new Set()
-    for (const deviceMountAction of this.configuration.deviceMountActions) {
-      const device = deviceMountAction.device
-      const deviceId = device.id
-      if (!alreadyAddedDeviceIds.has(deviceId)) {
-        result.push(device)
-        alreadyAddedDeviceIds.add(deviceId)
-      }
-    }
-    return result
-  }
-
-  updateLatitude (property: DeviceProperty | null) {
-    this.updateLocation('latitude', property)
-  }
-
-  updateLongitude (property: DeviceProperty | null) {
-    this.updateLocation('longitude', property)
-  }
-
-  updateElevation (property: DeviceProperty | null) {
-    this.updateLocation('elevation', property)
-  }
-
-  updateLocation (target: keyof IDynamicLocation, property: DeviceProperty | null) {
-    const configurationCopy = Configuration.createFromObject(this.configuration)
-    if (!configurationCopy.location) {
-      return
-    }
-    if (target in configurationCopy.location) {
-      configurationCopy.location[target] = property
-    }
-    this.$emit('input', configurationCopy)
-  }
-}
-</script>
diff --git a/components/configurations/StationaryLocationRow.vue b/components/configurations/StationaryLocationRow.vue
deleted file mode 100644
index 0c28371bfe5430fa6b714183318327b435319c01..0000000000000000000000000000000000000000
--- a/components/configurations/StationaryLocationRow.vue
+++ /dev/null
@@ -1,100 +0,0 @@
-<!--
-Web client of the Sensor Management System software developed within the
-Helmholtz DataHub Initiative by GFZ and UFZ.
-
-Copyright (C) 2020, 2021
-- Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
-- Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
-- Tobias Kuhnert (UFZ, tobias.kuhnert@ufz.de)
-- Erik Pongratz (UFZ, erik.pongratz@ufz.de)
-- Helmholtz Centre Potsdam - GFZ German Research Centre for
-  Geosciences (GFZ, https://www.gfz-potsdam.de)
-- Helmholtz Centre for Environmental Research GmbH - UFZ
-  (UFZ, https://www.ufz.de)
-
-Parts of this program were developed within the context of the
-following publicly funded projects or measures:
-- Helmholtz Earth and Environment DataHub
-  (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
-
-Licensed under the HEESIL, Version 1.0 or - as soon they will be
-approved by the "Community" - subsequent versions of the HEESIL
-(the "Licence").
-
-You may not use this work except in compliance with the Licence.
-
-You may obtain a copy of the Licence at:
-https://gitext.gfz-potsdam.de/software/heesil
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the Licence is distributed on an "AS IS" basis,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-implied. See the Licence for the specific language governing
-permissions and limitations under the Licence.
--->
-<template>
-  <div>
-    <v-row v-if="!readonly">
-      <v-col cols="12" md="3">
-        <v-text-field
-          v-model.number.lazy="configuration.location.latitude"
-          label="Latitude (WGS84)"
-          type="number"
-          step="any"
-          :readonly="readonly"
-          @wheel.prevent
-        />
-      </v-col>
-      <v-col cols="12" md="3">
-        <v-text-field
-          v-model.number.lazy="configuration.location.longitude"
-          label="Longitude (WGS84)"
-          type="number"
-          step="any"
-          :readonly="readonly"
-          @wheel.prevent
-        />
-      </v-col>
-      <v-col cols="12" md="3">
-        <v-text-field
-          v-model.number="configuration.location.elevation"
-          label="Elevation (m asl)"
-          type="number"
-          step="any"
-          :readonly="readonly"
-          @wheel.prevent
-        />
-      </v-col>
-    </v-row>
-    <v-row v-else>
-      <v-col cols="12" md="3">
-        <label>Latitude (WGS84)</label>
-        {{ configuration.location.latitude }}
-      </v-col>
-      <v-col cols="12" md="3">
-        <label>Longitude (WGS84)</label>
-        {{ configuration.location.longitude }}
-      </v-col>
-      <v-col cols="12" md="3">
-        <label>Elevation (m asl)</label>
-        {{ configuration.location.elevation }}
-      </v-col>
-    </v-row>
-  </div>
-</template>
-
-<script lang="ts">
-import { Vue, Component, Prop } from 'nuxt-property-decorator'
-
-import { Configuration } from '@/models/Configuration'
-
-@Component
-export default class StationaryLocationRow extends Vue {
-  @Prop({ default: false, type: Boolean }) readonly readonly!: boolean
-  @Prop({ default: false, type: Configuration }) configuration!: Configuration
-}
-</script>
-
-<style scoped>
-
-</style>
diff --git a/pages/devices/_deviceId/customfields/_customfieldId/edit.vue b/pages/devices/_deviceId/customfields/_customfieldId/edit.vue
index ad0d4ed18c97c9e9992a8ba384a6b8ae42873468..08fe6e324c7c83c95243561b0d3a1bc69ccf3625 100644
--- a/pages/devices/_deviceId/customfields/_customfieldId/edit.vue
+++ b/pages/devices/_deviceId/customfields/_customfieldId/edit.vue
@@ -34,7 +34,7 @@ permissions and limitations under the Licence.
       v-model="isInProgress"
       :dark="isSaving"
     />
-    <CustomFieldCardForm
+    <CustomFieldForm
       ref="customFieldCardForm"
       v-model="valueCopy"
     >
@@ -45,7 +45,7 @@ permissions and limitations under the Licence.
           @save="save"
         />
       </template>
-    </CustomFieldCardForm>
+    </CustomFieldForm>
   </div>
 </template>
 
@@ -53,18 +53,18 @@ permissions and limitations under the Licence.
 import { Component, Vue } from 'nuxt-property-decorator'
 
 
-import CustomFieldCardForm from '@/components/CustomFieldCardForm.vue'
 import ProgressIndicator from '@/components/ProgressIndicator.vue'
 import SaveAndCancelButtons from '@/components/configurations/SaveAndCancelButtons.vue'
 
 import { CustomTextField } from '@/models/CustomTextField'
 import { mapActions, mapState } from 'vuex'
+import CustomFieldForm from '@/components/CustomFieldForm.vue'
 
 
 @Component({
   components: {
+    CustomFieldForm,
     SaveAndCancelButtons,
-    CustomFieldCardForm,
     ProgressIndicator
   },
   middleware: ['auth'],
diff --git a/store/devices.ts b/store/devices.ts
index 24330b2aca74901ab51ab6b0dc018c1fcf05ec87..a4d9e3b03f87540edd884fe861da51fbc36f1cbe 100644
--- a/store/devices.ts
+++ b/store/devices.ts
@@ -11,7 +11,6 @@ import { DeviceCalibrationAction } from '@/models/DeviceCalibrationAction'
 import { IActionType } from '@/models/ActionType'
 import { DeviceProperty } from '@/models/DeviceProperty'
 import { CustomTextField } from '@/models/CustomTextField'
-import CustomFieldCard from '@/components/CustomFieldCard.vue'
 import { Platform } from '@/models/Platform'
 import { PlatformUnmountAction } from '@/models/PlatformUnmountAction'
 import { PlatformUnmountActionWrapper } from '@/viewmodels/PlatformUnmountActionWrapper'
diff --git a/test/AttachmentList.test.ts b/test/AttachmentList.test.ts
deleted file mode 100644
index ef313d2da2442f93d20cd50b8343afb108cdaad7..0000000000000000000000000000000000000000
--- a/test/AttachmentList.test.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * @license
- * Web client of the Sensor Management System software developed within
- * the Helmholtz DataHub Initiative by GFZ and UFZ.
- *
- * Copyright (C) 2020
- * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
- * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
- * - Helmholtz Centre Potsdam - GFZ German Research Centre for
- *   Geosciences (GFZ, https://www.gfz-potsdam.de)
- *
- * Parts of this program were developed within the context of the
- * following publicly funded projects or measures:
- * - Helmholtz Earth and Environment DataHub
- *   (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
- *
- * Licensed under the HEESIL, Version 1.0 or - as soon they will be
- * approved by the "Community" - subsequent versions of the HEESIL
- * (the "Licence").
- *
- * You may not use this work except in compliance with the Licence.
- *
- * You may obtain a copy of the Licence at:
- * https://gitext.gfz-potsdam.de/software/heesil
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied. See the Licence for the specific language governing
- * permissions and limitations under the Licence.
- */
-import Vue from 'vue'
-import Vuetify from 'vuetify'
-
-import { mount, createLocalVue } from '@vue/test-utils'
-
-// @ts-ignore
-import AttachmentList from '@/components/AttachmentList.vue'
-import { Attachment } from '@/models/Attachment'
-
-Vue.use(Vuetify)
-
-describe('AttachmentList', () => {
-  let wrapper: any
-
-  /*
-   * setup
-   */
-
-  beforeEach(() => {
-    const localVue = createLocalVue()
-    const vuetify = new Vuetify()
-    // disable "[Vuetify] Unable to locate target [data-app]" warnings:
-    document.body.setAttribute('data-app', 'true')
-
-    wrapper = mount(AttachmentList, {
-      localVue,
-      vuetify,
-      propsData: {
-        value: [
-          Attachment.createFromObject({
-            id: '1',
-            url: 'https://foo.pdf',
-            label: 'Manual'
-          }),
-          Attachment.createFromObject({
-            id: '2',
-            url: 'https://bar.png',
-            label: 'Product Image'
-          })
-        ] as Attachment[]
-      }
-    })
-  })
-
-  /*
-   * initial state
-   */
-
-  it('should be a Vue instance', () => {
-    expect(wrapper.vm).toBeTruthy()
-  })
-
-  /*
-   * add by URL
-   */
-
-  it('should trigger an input event when add button is clicked', async () => {
-    await wrapper.get('input[type="radio"][value="url"]').trigger('click')
-    wrapper.get('input[type="url"]').setValue('https://foo.bar/document.docx')
-    await wrapper.get('button[data-role="add-attachment"]').trigger('click')
-    expect(wrapper.emitted('input')).toBeTruthy()
-  })
-
-  it('must not trigger an input event when the url is empty and the add button is clicked', async () => {
-    await wrapper.get('input[type="radio"][value="url"]').trigger('click')
-    wrapper.get('input[type="url"]').setValue('')
-    await wrapper.get('button[data-role="add-attachment"]').trigger('click')
-    expect(wrapper.emitted('input')).toBeFalsy()
-  })
-
-  it('should trigger an input event with a attachment array length increased by 1 when the add button is clicked', async () => {
-    await wrapper.get('input[type="radio"][value="url"]').trigger('click')
-    wrapper.get('input[type="url"]').setValue('https://foo.bar/document.docx')
-    await wrapper.get('button[data-role="add-attachment"]').trigger('click')
-    expect(wrapper.emitted('input')[0][0]).toHaveLength(3)
-  })
-
-  /*
-   * removing
-   */
-
-  it('should trigger an input event when delete button is clicked', async () => {
-    await wrapper.get('[data-role="delete-attachment"]').trigger('click')
-    expect(wrapper.emitted('input')).toBeTruthy()
-  })
-
-  it('should trigger an input event with a fields array length decreased by 1 when the delete buttom is clicked', async () => {
-    await wrapper.get('[data-role="delete-attachment"]').trigger('click')
-    expect(wrapper.emitted('input')[0][0]).toHaveLength(1)
-  })
-})
diff --git a/test/AttachmentListItem.test.ts b/test/AttachmentListItem.test.ts
deleted file mode 100644
index 4916eb5b6e2818e7ab353902fa95defd2b73fad3..0000000000000000000000000000000000000000
--- a/test/AttachmentListItem.test.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @license
- * Web client of the Sensor Management System software developed within
- * the Helmholtz DataHub Initiative by GFZ and UFZ.
- *
- * Copyright (C) 2020
- * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
- * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
- * - Helmholtz Centre Potsdam - GFZ German Research Centre for
- *   Geosciences (GFZ, https://www.gfz-potsdam.de)
- *
- * Parts of this program were developed within the context of the
- * following publicly funded projects or measures:
- * - Helmholtz Earth and Environment DataHub
- *   (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
- *
- * Licensed under the HEESIL, Version 1.0 or - as soon they will be
- * approved by the "Community" - subsequent versions of the HEESIL
- * (the "Licence").
- *
- * You may not use this work except in compliance with the Licence.
- *
- * You may obtain a copy of the Licence at:
- * https://gitext.gfz-potsdam.de/software/heesil
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied. See the Licence for the specific language governing
- * permissions and limitations under the Licence.
- */
-import Vue from 'vue'
-import Vuetify from 'vuetify'
-
-import { mount, createLocalVue } from '@vue/test-utils'
-
-// @ts-ignore
-import AttachmentListItem from '@/components/AttachmentListItem.vue'
-import { Attachment } from '@/models/Attachment'
-
-Vue.use(Vuetify)
-
-describe('AttachmentListItem', () => {
-  let wrapper: any
-
-  /*
-   * setup
-   */
-
-  beforeEach(() => {
-    const localVue = createLocalVue()
-    const vuetify = new Vuetify()
-
-    wrapper = mount(AttachmentListItem, {
-      localVue,
-      vuetify,
-      propsData: {
-        value: Attachment.createFromObject({
-          id: '1',
-          url: 'https://foo.bar/Document.docx',
-          label: 'Assembling Instructions'
-        })
-      }
-    })
-  })
-
-  /*
-   * initial state
-   */
-
-  it('should be a Vue instance', () => {
-    expect(wrapper.vm).toBeTruthy()
-  })
-
-  it('should trigger an input event on change', () => {
-    wrapper.get('input[type="text"]').setValue('Disassembling Instructions')
-    expect(wrapper.emitted('input')).toBeTruthy()
-  })
-})
diff --git a/test/ConfigurationsPlatformDeviceSearch.test.ts b/test/ConfigurationsPlatformDeviceSearch.test.ts
deleted file mode 100644
index 3a95b05eb1a148e08c009df5f20a7d4d39dd8265..0000000000000000000000000000000000000000
--- a/test/ConfigurationsPlatformDeviceSearch.test.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * @license
- * Web client of the Sensor Management System software developed within
- * the Helmholtz DataHub Initiative by GFZ and UFZ.
- *
- * Copyright (C) 2020-2021
- * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
- * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
- * - Helmholtz Centre Potsdam - GFZ German Research Centre for
- *   Geosciences (GFZ, https://www.gfz-potsdam.de)
- *
- * Parts of this program were developed within the context of the
- * following publicly funded projects or measures:
- * - Helmholtz Earth and Environment DataHub
- *   (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
- *
- * Licensed under the HEESIL, Version 1.0 or - as soon they will be
- * approved by the "Community" - subsequent versions of the HEESIL
- * (the "Licence").
- *
- * You may not use this work except in compliance with the Licence.
- *
- * You may obtain a copy of the Licence at:
- * https://gitext.gfz-potsdam.de/software/heesil
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied. See the Licence for the specific language governing
- * permissions and limitations under the Licence.
- */
-import Vue from 'vue'
-import Vuetify from 'vuetify'
-import { DateTime } from 'luxon'
-
-import { mount, createLocalVue } from '@vue/test-utils'
-
-// @ts-ignore
-import ConfigurationsPlatformDeviceSearch from '@/components/ConfigurationsPlatformDeviceSearch.vue'
-// @ts-ignore
-import ConfigurationsPlatformDeviceMountForm from '@/components/ConfigurationsPlatformDeviceMountForm.vue'
-
-import { Contact } from '@/models/Contact'
-import { Device } from '@/models/Device'
-import { Platform } from '@/models/Platform'
-
-const contact = new Contact()
-contact.email = 'aa@bb.cc'
-const date = DateTime.utc(2020, 2, 3, 0, 0, 0, 0)
-
-Vue.use(Vuetify)
-
-describe('ConfigurationsPlatformDeviceSearch', () => {
-  const createWrapper = (
-    platformsResult: Platform[],
-    devicesResult: Device[]
-  ) => {
-    const localVue = createLocalVue()
-    const vuetify = new Vuetify()
-
-    const searchType = devicesResult.length ? 'Device' : 'Platform'
-    const searchOptions = {
-      searchType,
-      text: ''
-    }
-
-    // select the first entry
-    const selectedPlatform = devicesResult.length ? -1 : 0
-    const selectedDevice = devicesResult.length ? 0 : -1
-
-    const wrapper = mount(ConfigurationsPlatformDeviceSearch, {
-      localVue,
-      vuetify,
-      propsData: {
-        selectedDate: date,
-        isPlatformUsedFunc (_p: Platform) { return false },
-        isDeviceUsedFunc (_x: Device) { return false },
-        contacts: [contact]
-      },
-      data () {
-        return {
-          platformsResult,
-          searchedForPlatforms: !devicesResult.length,
-          devicesResult,
-          searchedForDevices: !!devicesResult.length,
-          searchOptions,
-          selectedPlatform,
-          selectedDevice
-        }
-      }
-    })
-
-    return wrapper
-  }
-
-  it('should trigger an add-platform event when a platform is added', async () => {
-    const platform = new Platform()
-    platform.id = '1'
-    platform.shortName = 'a platform'
-
-    const wrapper: any = createWrapper([platform], [])
-
-    await wrapper.get('.mount-expansion-panel').trigger('click')
-    const mountForm = wrapper.findComponent(ConfigurationsPlatformDeviceMountForm)
-    await mountForm.setData({
-      offsetX: 1,
-      offsetY: 2,
-      offsetZ: 3,
-      contact,
-      description: 'dummy description'
-    })
-    expect(mountForm.vm.$data.description).toEqual('dummy description')
-    await wrapper.get('button[data-role="add-platform"]').trigger('click')
-    expect(wrapper.emitted('add-platform')).toBeTruthy()
-    expect(wrapper.emitted('add-platform').length).toBe(1)
-    expect(wrapper.emitted('add-platform')[0]).toEqual([platform, 1, 2, 3, contact, 'dummy description'])
-  })
-
-  it('should trigger an add-device event when a device is added', async () => {
-    const device = new Device()
-    device.id = '1'
-    device.shortName = 'a device'
-
-    const wrapper: any = createWrapper([], [device])
-
-    await wrapper.get('.mount-expansion-panel').trigger('click')
-    const mountForm = wrapper.findComponent(ConfigurationsPlatformDeviceMountForm)
-    await mountForm.setData({
-      offsetX: 1,
-      offsetY: 2,
-      offsetZ: 3,
-      contact,
-      description: 'dummy description'
-    })
-
-    await wrapper.get('button[data-role="add-device"]').trigger('click')
-    expect(wrapper.emitted('add-device')).toBeTruthy()
-    expect(wrapper.emitted('add-device').length).toBe(1)
-    // wrapper.emitted('add-device')[0]) is an array [device, offsetX, offsetY, ...]
-    expect(wrapper.emitted('add-device')[0]).toEqual([device, 1, 2, 3, contact, 'dummy description'])
-  })
-})
diff --git a/test/ConfigurationsSelectedItem.test.ts b/test/ConfigurationsSelectedItem.test.ts
deleted file mode 100644
index a9cdae82778c06e3e788ef2a9382e70119035cc0..0000000000000000000000000000000000000000
--- a/test/ConfigurationsSelectedItem.test.ts
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * @license
- * Web client of the Sensor Management System software developed within
- * the Helmholtz DataHub Initiative by GFZ and UFZ.
- *
- * Copyright (C) 2020-2021
- * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
- * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
- * - Helmholtz Centre Potsdam - GFZ German Research Centre for
- *   Geosciences (GFZ, https://www.gfz-potsdam.de)
- *
- * Parts of this program were developed within the context of the
- * following publicly funded projects or measures:
- * - Helmholtz Earth and Environment DataHub
- *   (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
- *
- * Licensed under the HEESIL, Version 1.0 or - as soon they will be
- * approved by the "Community" - subsequent versions of the HEESIL
- * (the "Licence").
- *
- * You may not use this work except in compliance with the Licence.
- *
- * You may obtain a copy of the Licence at:
- * https://gitext.gfz-potsdam.de/software/heesil
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied. See the Licence for the specific language governing
- * permissions and limitations under the Licence.
- */
-import Vue from 'vue'
-import Vuetify from 'vuetify'
-import { DateTime } from 'luxon'
-
-import { mount, createLocalVue } from '@vue/test-utils'
-
-// @ts-ignore
-import ConfigurationsSelectedItem from '@/components/ConfigurationsSelectedItem.vue'
-// @ts-ignore
-import ConfigurationsSelectedItemUnmountForm from '@/components/ConfigurationsSelectedItemUnmountForm.vue'
-
-import { Contact } from '@/models/Contact'
-import { Device } from '@/models/Device'
-import { DeviceMountAction } from '@/models/DeviceMountAction'
-
-import { DeviceNode } from '@/viewmodels/DeviceNode'
-import { ConfigurationsTreeNode } from '@/viewmodels/ConfigurationsTreeNode'
-
-const contact = new Contact()
-contact.email = 'aa@bb.cc'
-const date = DateTime.utc(2020, 2, 3, 0, 0, 0, 0)
-
-const selectedDate = DateTime.utc(2020, 1, 1, 12, 0, 0)
-
-Vue.use(Vuetify)
-
-describe('ConfigurationsSelectedItem', () => {
-  const createWrapper = (node: ConfigurationsTreeNode) => {
-    const localVue = createLocalVue()
-    const vuetify = new Vuetify()
-
-    return mount(ConfigurationsSelectedItem, {
-      localVue,
-      vuetify,
-      propsData: {
-        value: node,
-        selectedDate
-      },
-      data () {
-        return {}
-      },
-      mocks: {
-        $auth: {
-          user: {
-            email: 'foo@bar.de'
-          }
-        }
-      }
-    })
-  }
-
-  it('should return the description of a given device', () => {
-    const device = new Device()
-    device.id = '1'
-    device.description = 'foo bar baz'
-
-    const wrapper: any = createWrapper(new DeviceNode(DeviceMountAction.createFromObject({
-      id: '',
-      device,
-      parentPlatform: null,
-      offsetX: 0,
-      offsetY: 0,
-      offsetZ: 0,
-      contact,
-      date,
-      description: 'Device mount'
-    })))
-    expect(wrapper.vm.description).toEqual(device.description)
-  })
-  it('should trigger an input event when the remove button is clicked', async () => {
-    const device = new Device()
-    device.id = '1'
-    device.description = 'foo bar baz'
-
-    const node = new DeviceNode(DeviceMountAction.createFromObject({
-      id: '',
-      device,
-      parentPlatform: null,
-      offsetX: 0,
-      offsetY: 0,
-      offsetZ: 0,
-      contact,
-      date,
-      description: 'Device mount'
-    }))
-
-    const wrapper: any = createWrapper(node)
-    await wrapper.get('.unmount-expansion-panel').trigger('click')
-    const unmountForms = wrapper.findAllComponents(ConfigurationsSelectedItemUnmountForm)
-    expect(unmountForms).toHaveLength(1)
-    const unmountForm = unmountForms.at(0)
-    expect(unmountForm.exists()).toBeTruthy()
-    await unmountForm.setData({
-      contact,
-      description: 'dummy description'
-    })
-    expect(unmountForm.vm.$data.description).toEqual('dummy description')
-
-    await wrapper.get('button[data-role="remove-node"]').trigger('click')
-    expect(wrapper.emitted().remove).toBeTruthy()
-    expect(wrapper.emitted().remove.length).toBe(1)
-    const emitted = wrapper.emitted().remove[0]
-    expect(emitted.length).toEqual(3)
-    // we only test here the node, as the contact & description come from sub components
-    expect(emitted[0]).toEqual(node)
-    expect(emitted[2]).toEqual('dummy description')
-    expect(emitted[1]).toEqual(contact)
-  })
-
-  describe('#isMountedOnSelctedDate', () => {
-    it('should return true for the very same instance', () => {
-      const device = new Device()
-      device.id = '1'
-      device.description = 'foo bar baz'
-
-      const node = new DeviceNode(DeviceMountAction.createFromObject({
-        id: '',
-        device,
-        parentPlatform: null,
-        offsetX: 0,
-        offsetY: 0,
-        offsetZ: 0,
-        contact,
-        date: selectedDate,
-        description: 'Device mount'
-      }))
-
-      const wrapper: any = createWrapper(node)
-
-      expect(wrapper.vm.isMountedOnSelectedDate).toEqual(true)
-    })
-    it('should return false for a different date', () => {
-      const device = new Device()
-      device.id = '1'
-      device.description = 'foo bar baz'
-
-      const node = new DeviceNode(DeviceMountAction.createFromObject({
-        id: '',
-        device,
-        parentPlatform: null,
-        offsetX: 0,
-        offsetY: 0,
-        offsetZ: 0,
-        contact,
-        date: DateTime.utc(2021, 1, 1, 12, 0, 0),
-        description: 'Device mount'
-      }))
-
-      const wrapper: any = createWrapper(node)
-
-      expect(wrapper.vm.isMountedOnSelectedDate).toEqual(false)
-    })
-    it('should return true for the an instance with the same datetime', () => {
-      const device = new Device()
-      device.id = '1'
-      device.description = 'foo bar baz'
-
-      const node = new DeviceNode(DeviceMountAction.createFromObject({
-        id: '',
-        device,
-        parentPlatform: null,
-        offsetX: 0,
-        offsetY: 0,
-        offsetZ: 0,
-        contact,
-        date: DateTime.utc(2020, 1, 1, 12, 0, 0),
-        description: 'Device mount'
-      }))
-
-      const wrapper: any = createWrapper(node)
-
-      expect(wrapper.vm.isMountedOnSelectedDate).toEqual(true)
-    })
-  })
-})
diff --git a/test/CustomFieldCards.test.ts b/test/CustomFieldCards.test.ts
deleted file mode 100644
index 7ebde90438cb8d0acdbf286e4d35be068420aa10..0000000000000000000000000000000000000000
--- a/test/CustomFieldCards.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * @license
- * Web client of the Sensor Management System software developed within
- * the Helmholtz DataHub Initiative by GFZ and UFZ.
- *
- * Copyright (C) 2020
- * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
- * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
- * - Helmholtz Centre Potsdam - GFZ German Research Centre for
- *   Geosciences (GFZ, https://www.gfz-potsdam.de)
- *
- * Parts of this program were developed within the context of the
- * following publicly funded projects or measures:
- * - Helmholtz Earth and Environment DataHub
- *   (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
- *
- * Licensed under the HEESIL, Version 1.0 or - as soon they will be
- * approved by the "Community" - subsequent versions of the HEESIL
- * (the "Licence").
- *
- * You may not use this work except in compliance with the Licence.
- *
- * You may obtain a copy of the Licence at:
- * https://gitext.gfz-potsdam.de/software/heesil
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied. See the Licence for the specific language governing
- * permissions and limitations under the Licence.
- */
-import Vue from 'vue'
-import Vuetify from 'vuetify'
-
-import { mount, createLocalVue } from '@vue/test-utils'
-
-// @ts-ignore
-import CustomFieldCards from '@/components/CustomFieldCards.vue'
-import { CustomTextField } from '@/models/CustomTextField'
-
-Vue.use(Vuetify)
-
-describe('CustomFieldCards', () => {
-  let wrapper: any
-
-  /*
-   * setup
-   */
-
-  beforeEach(() => {
-    const localVue = createLocalVue()
-    const vuetify = new Vuetify()
-    // disable "[Vuetify] Unable to locate target [data-app]" warnings:
-    document.body.setAttribute('data-app', 'true')
-
-    wrapper = mount(CustomFieldCards, {
-      localVue,
-      vuetify,
-      propsData: {
-        value: [
-          CustomTextField.createFromObject({
-            id: '2',
-            key: 'foo',
-            value: 'bar'
-          })
-        ] as CustomTextField[]
-      }
-    })
-  })
-
-  /*
-   * initial state
-   */
-
-  it('should be a Vue instance', () => {
-    expect(wrapper.vm).toBeTruthy()
-  })
-
-  /*
-   * adding
-   */
-
-  it('should trigger an input event when add button is clicked', async () => {
-    await wrapper.get('[data-role="add-field"]').trigger('click')
-    expect(wrapper.emitted('input')).toBeTruthy()
-  })
-
-  it('should trigger an input event with a fields array length increased by 1 when the add button is clicked', async () => {
-    await wrapper.get('[data-role="add-field"]').trigger('click')
-    expect(wrapper.emitted('input')[0][0]).toHaveLength(2)
-  })
-
-  /*
-   * removing
-   */
-
-  it('should trigger an input event when delete button is clicked', async () => {
-    await wrapper.get('[data-role="delete-field"]').trigger('click')
-    expect(wrapper.emitted('input')).toBeTruthy()
-  })
-
-  it('should trigger an input event with a fields array length decreased by 1 when the delete buttom is clicked', async () => {
-    await wrapper.get('[data-role="delete-field"]').trigger('click')
-    expect(wrapper.emitted('input')[0][0]).toHaveLength(0)
-  })
-})
diff --git a/test/DevicePropertyExpansionPanels.test.ts b/test/DevicePropertyExpansionPanels.test.ts
deleted file mode 100644
index 276beea0e238d954ee4fe1fb663ab547788f25fe..0000000000000000000000000000000000000000
--- a/test/DevicePropertyExpansionPanels.test.ts
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * @license
- * Web client of the Sensor Management System software developed within
- * the Helmholtz DataHub Initiative by GFZ and UFZ.
- *
- * Copyright (C) 2020
- * - Nils Brinckmann (GFZ, nils.brinckmann@gfz-potsdam.de)
- * - Marc Hanisch (GFZ, marc.hanisch@gfz-potsdam.de)
- * - Helmholtz Centre Potsdam - GFZ German Research Centre for
- *   Geosciences (GFZ, https://www.gfz-potsdam.de)
- *
- * Parts of this program were developed within the context of the
- * following publicly funded projects or measures:
- * - Helmholtz Earth and Environment DataHub
- *   (https://www.helmholtz.de/en/research/earth_and_environment/initiatives/#h51095)
- *
- * Licensed under the HEESIL, Version 1.0 or - as soon they will be
- * approved by the "Community" - subsequent versions of the HEESIL
- * (the "Licence").
- *
- * You may not use this work except in compliance with the Licence.
- *
- * You may obtain a copy of the Licence at:
- * https://gitext.gfz-potsdam.de/software/heesil
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied. See the Licence for the specific language governing
- * permissions and limitations under the Licence.
- */
-import Vue from 'vue'
-import Vuetify from 'vuetify'
-
-import { mount, createLocalVue } from '@vue/test-utils'
-
-// @ts-ignore
-import DevicePropertyExpansionPanels from '@/components/DevicePropertyExpansionPanels.vue'
-
-import { DeviceProperty } from '@/models/DeviceProperty'
-import { Compartment } from '@/models/Compartment'
-import { SamplingMedia } from '@/models/SamplingMedia'
-import { Property } from '@/models/Property'
-import { Unit } from '@/models/Unit'
-import { MeasuredQuantityUnit } from '@/models/MeasuredQuantityUnit'
-
-Vue.use(Vuetify)
-
-describe('DevicePropertyExpansionPanels', () => {
-  let wrapper: any
-
-  /*
-   * setup
-   */
-
-  beforeEach(() => {
-    const localVue = createLocalVue()
-    const vuetify = new Vuetify()
-    // disable "[Vuetify] Unable to locate target [data-app]" warnings:
-    document.body.setAttribute('data-app', 'true')
-
-    wrapper = mount(DevicePropertyExpansionPanels, {
-      localVue,
-      vuetify,
-      propsData: {
-        value: [
-          DeviceProperty.createFromObject({
-            id: null,
-            label: 'test',
-            compartmentUri: 'http://foo/compartment/1',
-            compartmentName: 'bar',
-            unitUri: 'http://foo/unit/1',
-            unitName: 'mm',
-            samplingMediaUri: 'http://foo/samplingMedia/1',
-            samplingMediaName: 'water',
-            propertyUri: 'http://foo/property/1',
-            propertyName: 'foo.bar',
-            measuringRange: {
-              min: 10,
-              max: 1000
-            },
-            accuracy: 0.1,
-            failureValue: 0.01,
-            resolution: 0.001,
-            resolutionUnitUri: 'http://foo/unit/1',
-            resolutionUnitName: 'mm'
-          })
-        ] as DeviceProperty[],
-        compartments: [
-          Compartment.createWithData('1', 'bar', 'http://foo/compartment/1', 'foo'),
-          Compartment.createWithData('2', 'foo', 'http://foo/compartment/2', 'bar')
-        ] as Compartment[],
-        samplingMedias: [
-          SamplingMedia.createWithData('1', 'water', 'http://foo/samplingMedia/1', 'foo', '5'),
-          SamplingMedia.createWithData('2', 'media2', 'http://foo/samplingMedia/2', 'bar', '2')
-        ] as SamplingMedia[],
-        properties: [
-          Property.createWithData('1', 'foo.bar', 'http://foo/property/1', 'foo', '8'),
-          Property.createWithData('2', 'property2', 'http://foo/property/2', 'bar', '3')
-        ] as Property[],
-        units: [
-          Unit.createWithData('1', 'mm', 'http://foo/unit/1', 'foo'),
-          Unit.createWithData('2', 's', 'http://foo/unit/2', 'bar')
-        ] as Unit[],
-        measuredQuantityUnits: [
-          MeasuredQuantityUnit.createWithData('1', 'mm', 'http://foo/measuredquantityunits/1', 'foo', '0.01', '10', '1', '1'),
-          MeasuredQuantityUnit.createWithData('2', 's', 'http://foo/measuredquantityunits/2', 'bar', '0.001', '60', '2', '1')
-        ] as MeasuredQuantityUnit[]
-      }
-    })
-  })
-
-  /*
-   * initial state
-   */
-
-  it('should be a Vue instance', () => {
-    expect(wrapper.vm).toBeTruthy()
-  })
-
-  /*
-   * adding
-   */
-
-  it('should trigger an input event when add button is clicked', async () => {
-    await wrapper.get('button[data-role="add-property"]').trigger('click')
-    expect(wrapper.emitted('input')).toBeTruthy()
-  })
-
-  it('should trigger an input event with a device property array length increased by 1 when the add button is clicked', async () => {
-    await wrapper.get('[data-role="add-property"]').trigger('click')
-    expect(wrapper.emitted('input')[0][0]).toHaveLength(2)
-  })
-
-  /*
-   * removing
-   */
-
-  it('should trigger an input event when delete menu item is clicked', async () => {
-    await wrapper.get('[data-role="property-menu"]').trigger('click')
-    await wrapper.get('[data-role="delete-property"]').trigger('click')
-    expect(wrapper.emitted('input')).toBeTruthy()
-  })
-
-  it('should trigger an input event with a device property array length decreased by 1 when the delete menu item is clicked', async () => {
-    await wrapper.get('[data-role="property-menu"]').trigger('click')
-    await wrapper.get('[data-role="delete-property"]').trigger('click')
-    expect(wrapper.emitted('input')[0][0]).toHaveLength(0)
-  })
-
-  /*
-   * copying
-   */
-
-  it('should trigger an input event when copy menu item is clicked', async () => {
-    await wrapper.get('[data-role="property-menu"]').trigger('click')
-    await wrapper.get('[data-role="copy-property"]').trigger('click')
-    expect(wrapper.emitted('input')).toBeTruthy()
-  })
-
-  it('should trigger an input event with a device property array length increased by 1 when the copy menu item is clicked', async () => {
-    await wrapper.get('[data-role="property-menu"]').trigger('click')
-    await wrapper.get('[data-role="copy-property"]').trigger('click')
-    expect(wrapper.emitted('input')[0][0]).toHaveLength(2)
-  })
-})