diff --git a/frontend/src/views/settings/ModelsList.vue b/frontend/src/views/settings/ModelsList.vue index 82e60e5..05f2284 100644 --- a/frontend/src/views/settings/ModelsList.vue +++ b/frontend/src/views/settings/ModelsList.vue @@ -138,34 +138,51 @@
Model image
- - Save the model first, then upload a photo. + + + + + + {{ pendingImageFile.name }} will be uploaded when you save. +
+ - Manual alternative. Uploading a photo overwrites this URL. + + Set automatically when you upload a photo. Accepts a full web address or a path on this server. +
@@ -224,6 +241,8 @@ const perPage = ref(20) const showModal = ref(false) const editingModel = ref(null) +// A photo chosen while CREATING a model, uploaded once the model has an id. +const pendingImageFile = ref(null) const saving = ref(false) const error = ref('') @@ -337,6 +356,9 @@ function openModal(m = null) { function closeModal() { showModal.value = false editingModel.value = null + // Or a photo picked for a model that was never saved would be uploaded onto + // the NEXT model created in this session. + pendingImageFile.value = null } async function saveModel() { @@ -351,7 +373,20 @@ async function saveModel() { if (editingModel.value) { await modelsApi.update(editingModel.value.modelnumberid, data) } else { - await modelsApi.create(data) + const created = await modelsApi.create(data) + // Send a photo chosen before the model existed. A failure here must not + // read as "the model was not saved" - it was. + if (pendingImageFile.value) { + const newId = created?.data?.data?.modelnumberid + if (newId) { + try { + await modelsApi.uploadImage(newId, pendingImageFile.value) + } catch (imgErr) { + console.error('Error uploading image:', imgErr) + toast.error(apiError(imgErr, 'Model saved, but the photo could not be uploaded')) + } + } + } } closeModal() loadModels() @@ -369,7 +404,14 @@ function triggerImageUpload() { async function onImageSelected(event) { const file = event.target.files?.[0] - if (!file || !editingModel.value) return + if (!file) return + // No model id yet, so hold the file and send it once saveModel has created + // the record. Nothing is written to the server until the operator saves. + if (!editingModel.value) { + pendingImageFile.value = file + if (imageFileInput.value) imageFileInput.value.value = '' + return + } uploadingImage.value = true try { const response = await modelsApi.uploadImage(editingModel.value.modelnumberid, file) @@ -387,7 +429,12 @@ async function onImageSelected(event) { } async function removeImage() { - if (!editingModel.value) return + // On a new model there is nothing on the server yet; just drop the choice. + if (!editingModel.value) { + pendingImageFile.value = null + form.value.imageurl = '' + return + } if (!confirm('Remove this model image?')) return try { await modelsApi.removeImage(editingModel.value.modelnumberid) diff --git a/plugins/network/api/routes.py b/plugins/network/api/routes.py index 46516b3..3dfdc87 100644 --- a/plugins/network/api/routes.py +++ b/plugins/network/api/routes.py @@ -346,7 +346,7 @@ def create_network_device(): Optional fields: - name, serialnumber, statusid, locationid, businessunitid - - networkdevicetypeid, vendorid, hostname + - networkdevicetypeid, vendorid, modelnumberid, hostname - firmwareversion, portcount, ispoe, ismanaged, rackunit - mapx, mapy, notes """ @@ -408,6 +408,7 @@ def create_network_device(): assetid=asset.assetid, networkdevicetypeid=data.get('networkdevicetypeid'), vendorid=data.get('vendorid'), + modelnumberid=data.get('modelnumberid'), hostname=data.get('hostname'), firmwareversion=data.get('firmwareversion'), portcount=data.get('portcount'), @@ -495,7 +496,7 @@ def update_network_device(device_id: int): setattr(asset, key, data[key]) # Update network device fields - netdev_fields = ['networkdevicetypeid', 'vendorid', 'hostname', + netdev_fields = ['networkdevicetypeid', 'vendorid', 'modelnumberid', 'hostname', 'firmwareversion', 'portcount', 'ispoe', 'ismanaged', 'rackunit'] for key in netdev_fields: if key in data: diff --git a/plugins/network/frontend/views/NetworkDeviceForm.vue b/plugins/network/frontend/views/NetworkDeviceForm.vue index 3488cca..605144b 100644 --- a/plugins/network/frontend/views/NetworkDeviceForm.vue +++ b/plugins/network/frontend/views/NetworkDeviceForm.vue @@ -133,6 +133,23 @@
+
+ + + +
+ + +