diff --git a/src/components/Model/EditForm.vue b/src/components/Model/EditForm.vue
index f266b3a23d2bc350dde4ac66f1a064ee7bb0c986..e11181ff4669f9ff573ce7487404a95e7dee71e5 100644
--- a/src/components/Model/EditForm.vue
+++ b/src/components/Model/EditForm.vue
@@ -1,65 +1,76 @@
 <template>
-  <slot name="action">
-    <button
-      class="button"
-      v-on:click="openModal = allowEdition"
-      v-bind="$attrs"
-      :disabled="!allowEdition || null"
-      :title="allowTitle"
-    >
-      <i class="icon-edit"></i>
-    </button>
-  </slot>
+  <button
+    v-if="mode === 'edit'"
+    class="button"
+    v-on:click="openModal = allowOpen"
+    v-bind="$attrs"
+    :disabled="!allowOpen || undefined"
+    :title="openButtonTitle"
+  >
+    <i class="icon-edit"></i>
+  </button>
+  <button
+    v-else-if="mode === 'create'"
+    class="button is-primary"
+    v-on:click="openModal = allowOpen"
+    v-bind="$attrs"
+    :disabled="!allowOpen || undefined"
+    :title="openButtonTitle"
+  >
+    Create
+  </button>
 
-  <Modal v-model="openModal" :title="modalTitle" is-large>
-    <form class="form" v-on:submit.prevent="update">
-      <div class="field">
-        <label class="label">Name</label>
-        <div class="control">
-          <input
-            class="input"
-            :class="{ 'is-danger': fieldErrors.name }"
-            type="text"
-            maxlength="100"
-            v-model.trim="payload.name"
-            :disabled="loading || null"
-          />
-          <template v-if="fieldErrors.name">
-            <p class="help is-danger" v-for="err in fieldErrors.name" :key="err">{{ err }}</p>
-          </template>
+  <Teleport to="body">
+    <Modal v-model="openModal" :title="modalTitle" is-large>
+      <form class="form" v-on:submit.prevent="saveAction">
+        <div class="field">
+          <label class="label">Name</label>
+          <div class="control">
+            <input
+              class="input"
+              :class="{ 'is-danger': fieldErrors.name }"
+              type="text"
+              maxlength="100"
+              v-model.trim="payload.name"
+              :disabled="loading || undefined"
+            />
+            <template v-if="fieldErrors.name">
+              <p class="help is-danger" v-for="err in fieldErrors.name" :key="err">{{ err }}</p>
+            </template>
+          </div>
         </div>
-      </div>
 
-      <div class="field">
-        <label class="label">Description</label>
-        <div class="control">
-          <textarea
-            class="textarea"
-            :class="{ 'is-danger': fieldErrors.description }"
-            type="text"
-            v-model.trim="payload.description"
-            :disabled="loading || null"
-          ></textarea>
-          <template v-if="fieldErrors.description">
-            <p class="help is-danger" v-for="err in fieldErrors.description" :key="err">{{ err }}</p>
-          </template>
+        <div class="field">
+          <label class="label">Description</label>
+          <div class="control">
+            <textarea
+              class="textarea"
+              :class="{ 'is-danger': fieldErrors.description }"
+              type="text"
+              v-model.trim="payload.description"
+              :disabled="loading || undefined"
+            ></textarea>
+            <template v-if="fieldErrors.description">
+              <p class="help is-danger" v-for="err in fieldErrors.description" :key="err">{{ err }}</p>
+            </template>
+          </div>
         </div>
-      </div>
-    </form>
+      </form>
 
-    <template v-slot:footer="{ close }">
-      <button class="button" v-on:click="close">Cancel</button>
-      <button
-        type="submit"
-        v-on:click="update"
-        class="button is-primary ml-auto"
-        :class="{ 'is-loading': loading }"
-        :disabled="loading || null"
-      >
-        Update
-      </button>
-    </template>
-  </Modal>
+      <template v-slot:footer="{ close }">
+        <button class="button" v-on:click="close">Cancel</button>
+        <button
+          type="submit"
+          v-on:click="saveAction"
+          class="button is-primary ml-auto"
+          :class="{ 'is-loading': loading }"
+          :disabled="loading || !payload.name.length || undefined"
+        >
+          {{ saveButtonName }}
+        </button>
+      </template>
+    </Modal>
+  </Teleport>
 </template>
 
 <script lang="ts">
@@ -67,7 +78,7 @@ import { mapActions } from 'pinia'
 import { errorParser, ensureArray } from '@/helpers'
 import Modal from '@/components/Modal.vue'
 import { useNotificationStore, useModelStore } from '@/stores'
-import { UpdateModelPayload } from '@/api'
+import { CreateModelPayload } from '@/api'
 import { PropType, defineComponent } from 'vue'
 import { isAxiosError } from 'axios'
 import { Model } from '@/types/model'
@@ -76,10 +87,17 @@ export default defineComponent({
   components: {
     Modal
   },
+  emits: {
+    reload: (value: boolean) => typeof value === 'boolean'
+  },
   props: {
-    model: {
-      type: Object as PropType<Model>,
+    mode: {
+      type: String,
       required: true
+    },
+    modelInstance: {
+      type: Object as PropType<Model>,
+      default: null
     }
   },
   data: () => ({
@@ -87,33 +105,48 @@ export default defineComponent({
     payload: {
       name: '',
       description: ''
-    } as UpdateModelPayload,
+    } as CreateModelPayload,
     loading: false,
-    fieldErrors: {} as Partial<Record<keyof UpdateModelPayload, string[]>>
+    fieldErrors: {} as Partial<Record<keyof CreateModelPayload, string[]>>
   }),
   computed: {
-    allowEdition () {
-      return this.model.rights.includes('write')
+    allowOpen () {
+      if (this.mode === 'edit' && this.modelInstance) return this.modelInstance.rights.includes('write')
+      return true
     },
-    allowTitle () {
-      return this.allowEdition
-        ? 'Edit model'
-        : 'A contributor access level is required to edit a model'
+    openButtonTitle () {
+      if (this.mode === 'edit') {
+        return this.allowOpen
+          ? 'Edit model'
+          : 'A contributor access level is required to edit a model'
+      }
+      return 'Create a new model'
     },
     modalTitle () {
-      return `Edit model "${this.model.name}"`
+      if (this.mode === 'edit' && this.modelInstance) return `Edit model "${this.modelInstance.name}"`
+      return 'Create a new model'
+    },
+    saveButtonName () {
+      if (this.mode === 'edit') return 'Update'
+      return 'Create'
     }
   },
   methods: {
-    ...mapActions(useModelStore, ['updateModel']),
+    ...mapActions(useModelStore, ['updateModel', 'createModel', 'listModels']),
     ...mapActions(useNotificationStore, ['notify']),
-    async update () {
-      if (this.loading) return
+    async saveAction () {
+      if (this.loading || (this.mode === 'edit' && !this.modelInstance) || !this.payload.name.length) return
       this.loading = true
       this.fieldErrors = {}
       try {
-        await this.updateModel(this.model.id, this.payload)
-        this.notify({ type: 'info', text: 'Model updated successfully.' })
+        if (this.mode === 'edit' && this.modelInstance) {
+          await this.updateModel(this.modelInstance.id, this.payload)
+          this.notify({ type: 'info', text: 'Model updated successfully.' })
+        } else {
+          await this.createModel(this.payload)
+          this.$emit('reload', true)
+          this.notify({ type: 'success', text: 'Model successfully created.' })
+        }
         this.openModal = false
       } catch (err) {
         this.notify({ type: 'error', text: errorParser(err) })
@@ -128,11 +161,12 @@ export default defineComponent({
     }
   },
   watch: {
-    model: {
+    modelInstance: {
       immediate: true,
       handler () {
-        this.payload.name = this.model.name
-        this.payload.description = this.model.description
+        if (!this.modelInstance) return
+        this.payload.name = this.modelInstance.name
+        this.payload.description = this.modelInstance.description
       }
     }
   }
diff --git a/src/router/index.js b/src/router/index.js
index cf43d27968cfaabd897307149e8a7132ebc007b5..ae9eaa52ab5b995ac934bb450788c7a2522aadba 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -29,7 +29,6 @@ const ImportFromBucket = () => import(/* webpackChunkName: "users" */ '@/views/I
 const ProcessList = () => import(/* webpackChunkName: "users" */ '@/views/Process/List')
 const ModelsList = () => import(/* webpackChunkName: "users" */ '@/views/Model/List')
 const Model = () => import(/* webpackChunkName: "users" */ '@/views/Model')
-const ModelCreate = () => import(/* webpackChunkName: "users" */ '@/views/Model/Create')
 const ModelVersion = () => import(/* webpackChunkName: "users" */ '@/views/Model/Version')
 const ProcessDetails = () => import(/* webpackChunkName: "users" */ '@/views/Process/Details')
 const ProcessDatasets = () => import(/* webpackChunkName: "users" */ '@/views/Process/Datasets')
@@ -308,13 +307,6 @@ const routes = [
     meta: { requiresLogin: true, requiresVerified: true },
     props: true
   },
-  {
-    path: '/models/create',
-    name: 'model-create',
-    component: ModelCreate,
-    meta: { requiresLogin: true, requiresVerified: true },
-    props: false
-  },
   {
     path: `/model/:modelId(${UUID})`,
     name: 'model',
diff --git a/src/views/Model/Create.vue b/src/views/Model/Create.vue
deleted file mode 100644
index f921f6463f6d76249e42e37fedf2c9541f16a665..0000000000000000000000000000000000000000
--- a/src/views/Model/Create.vue
+++ /dev/null
@@ -1,114 +0,0 @@
-<template>
-  <main class="container is-fluid">
-    <router-link v-if="mainView" class="button is-pulled-right" :to="{ name: 'models-list' }">
-      <i class="icon-arrow-left"></i>
-      Models
-    </router-link>
-    <h1 class="title">New model</h1>
-    <h2 class="subtitle">Add a Machine-Learning model</h2>
-
-    <form v-on:submit.prevent="create">
-      <div class="field">
-        <label class="label">Model name *</label>
-        <div class="control">
-          <input
-            class="input is-fullwidth"
-            :disabled="loading || undefined"
-            type="text"
-            v-model.trim="fields.name"
-          />
-        </div>
-        <p v-if="errors.name" class="help is-danger">{{ errors.name }}</p>
-      </div>
-
-      <div class="field">
-        <label class="label">Model description</label>
-        <div class="control">
-          <input
-            class="input is-fullwidth"
-            :disabled="loading || undefined"
-            type="text"
-            v-model.trim="fields.description"
-          />
-        </div>
-        <p v-if="errors.description" class="help is-danger">{{ errors.description }}</p>
-      </div>
-
-      <div class="columns is-pulled-right mt-2">
-        <div class="column is-narrow">
-          <button
-            type="submit"
-            class="button is-primary is-fullwidth"
-            v-on:click="create"
-            :disabled="!allowCreate || undefined"
-            :title="allowCreate ? 'Create a new model' : 'A name is required to create a new model'"
-          >
-            <i v-if="loading" class="loader"></i>
-            <span v-else class="icon-plus">Create model</span>
-          </button>
-        </div>
-      </div>
-    </form>
-  </main>
-</template>
-
-<script lang="ts">
-import { isAxiosError } from 'axios'
-import { defineComponent } from 'vue'
-import { mapActions } from 'pinia'
-
-import { CreateModelPayload } from '@/api'
-import { corporaMixin } from '@/mixins'
-import { errorParser } from '@/helpers'
-import { useModelStore, useNotificationStore } from '@/stores'
-import { Model } from '@/types/model'
-
-export default defineComponent({
-  emits: {
-    'create-model' (value: Model) {
-      return value.id !== undefined
-    }
-  },
-  mixins: [
-    corporaMixin
-  ],
-  data: () => ({
-    loading: false,
-    fields: {
-      name: '',
-      description: ''
-    } as CreateModelPayload,
-    errors: {} as Record<string, unknown>
-  }),
-  computed: {
-    mainView () {
-      // The component can be mounted as a single view
-      return this.$route.name === 'model-create'
-    },
-    allowCreate () {
-      return Boolean(this.fields.name) && !this.loading
-    }
-  },
-  methods: {
-    ...mapActions(useNotificationStore, ['notify']),
-    async create () {
-      if (!this.allowCreate) return
-      this.loading = true
-      this.errors = {}
-      try {
-        const payload: CreateModelPayload = { name: this.fields.name }
-        if (this.fields.description?.trim()) payload.description = this.fields.description
-        const model = await useModelStore().createModel(payload)
-        this.notify({ type: 'success', text: `Model "${this.fields.name}" created successfully.` })
-        this.$emit('create-model', model)
-        this.fields.name = this.fields.description = ''
-      } catch (err) {
-        if (isAxiosError(err) && err.response?.data) this.errors = err.response.data
-        this.notify({ type: 'error', text: errorParser(err) })
-      } finally {
-        this.loading = false
-      }
-    }
-  }
-})
-</script>
diff --git a/src/views/Model/List.vue b/src/views/Model/List.vue
index 00679daca793b3f908d18944ff1764ff75c874e4..78cf9ca958c6d45f5bc3150b43e8830d62f5ce94 100644
--- a/src/views/Model/List.vue
+++ b/src/views/Model/List.vue
@@ -1,14 +1,12 @@
 <template>
   <main class="container is-fluid">
     <div class="columns">
-      <div class="column is-one-third">
-        <div class="has-text-right">
-          <router-link
-            class="button mb-2"
-            :to="{ name: 'model-create' }"
-          >
-            Create a model
-          </router-link>
+      <div class="field column is-one-third">
+        <div class="has-text-right mb-2">
+          <CreateForm
+            mode="create"
+            v-on:reload="updateModelsPage"
+          />
         </div>
 
         <div v-if="compatibleWorkerId" class="field has-text-right">
@@ -93,7 +91,7 @@
         <div v-if="!selectedModel" class="notification is-info">
           Please select a <strong>model</strong> on the left panel.
         </div>
-        <Model
+        <ModelComponent
           v-else
           :model-id="selectedModel"
           :process-id="processId"
@@ -118,6 +116,7 @@ import { Model } from '@/types/model'
 
 import Paginator from '@/components/Paginator.vue'
 import ModelComponent from '@/components/Model/Model.vue'
+import CreateForm from '@/components/Model/EditForm.vue'
 import { PageNumberPagination } from '@/types'
 
 export default defineComponent({
@@ -126,7 +125,8 @@ export default defineComponent({
   ],
   components: {
     Paginator,
-    Model: ModelComponent
+    ModelComponent,
+    CreateForm
   },
   props: {
     /**
diff --git a/src/views/Model/Model.vue b/src/views/Model/Model.vue
index 63753af6018a99e20fec3d1e63eb278ed4ab6a68..d0197a230f41bf04c11e7e76b6b69398597537b0 100644
--- a/src/views/Model/Model.vue
+++ b/src/views/Model/Model.vue
@@ -7,7 +7,7 @@
       </router-link>
       <div class="title">
         <span v-if="model.archived" class="tag">Archived</span> {{ model.name }}
-        <EditForm class="ml-2 is-primary" :model="model" />
+        <EditForm class="ml-2 is-primary" :model-instance="model" mode="edit" />
       </div>
       <div class="subtitle is-5">
         <p>Model <ItemId :item-id="model.id" /></p>
@@ -51,7 +51,7 @@
       </div>
 
       <hr />
-      <Model :model-id="modelId" />
+      <ModelDetails :model-id="modelId" />
     </template>
     <div v-else-if="error" class="notification is-danger">{{ error }}</div>
     <div v-else class="loader is-size-2 mx-auto"></div>
@@ -72,7 +72,8 @@ import { mapState, mapActions } from 'pinia'
 import { UUID_REGEX } from '@/config'
 import { ago, errorParser } from '@/helpers'
 import { UUID } from '@/types'
-import Model from '@/components/Model'
+import { Model } from '@/types/model'
+import ModelDetails from '@/components/Model'
 import EditForm from '@/components/Model/EditForm.vue'
 import { useModelStore, useNotificationStore } from '@/stores'
 import ItemId from '@/components/ItemId.vue'
@@ -87,7 +88,7 @@ export default defineComponent({
     }
   },
   components: {
-    Model,
+    ModelDetails,
     EditForm,
     ItemId,
     ArchivalModal
@@ -100,7 +101,7 @@ export default defineComponent({
   }),
   computed: {
     ...mapState(useModelStore, ['models']),
-    model () {
+    model (): Model {
       return this.models[this.modelId]
     },
     creationDate (): string | null {