diff --git a/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js
index a0648bcf282b18701bdcd83775e1652d1e8a3c5c..c0e8d02a6802019adaad97de3078fe2bef01d4da 100644
--- a/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js
+++ b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js
@@ -153,7 +153,7 @@ export default class TypeBrowserController extends BrowserController {
     }
   }
 
-  doNodeRemove(node) {
+  async doNodeRemove(node) {
     if (!node.object) {
       return Promise.resolve()
     }
@@ -161,34 +161,31 @@ export default class TypeBrowserController extends BrowserController {
     const { type, id } = node.object
     const reason = 'deleted via ng_ui'
 
-    return this._prepareRemoveOperations(type, id, reason)
-      .then(operations => {
-        const options = new openbis.SynchronousOperationExecutionOptions()
-        options.setExecuteInOrder(true)
-        return openbis.executeOperations(operations, options)
-      })
-      .then(() => {
-        this.context.dispatch(actions.objectDelete(this.getPage(), type, id))
-      })
-      .catch(error => {
-        this.context.dispatch(actions.errorChange(error))
-      })
+    try {
+      const operations = await this._prepareRemoveOperations(type, id, reason)
+      const options = new openbis.SynchronousOperationExecutionOptions()
+      options.setExecuteInOrder(true)
+      await openbis.executeOperations(operations, options)
+      this.context.dispatch(actions.objectDelete(this.getPage(), type, id))
+    } catch (error) {
+      this.context.dispatch(actions.errorChange(error))
+    }
   }
 
-  _prepareRemoveOperations(type, id, reason) {
+  async _prepareRemoveOperations(type, id, reason) {
     if (
       type === objectType.OBJECT_TYPE ||
       type === objectType.COLLECTION_TYPE ||
       type === objectType.DATA_SET_TYPE ||
       type === objectType.MATERIAL_TYPE
     ) {
-      return this._prepareRemoveEntityTypeOperations(type, id, reason)
+      return await this._prepareRemoveEntityTypeOperations(type, id, reason)
     } else if (type === objectType.VOCABULARY_TYPE) {
-      return this._prepareRemoveVocabularyTypeOperations(type, id, reason)
+      return await this._prepareRemoveVocabularyTypeOperations(type, id, reason)
     }
   }
 
-  _prepareRemoveEntityTypeOperations(type, id, reason) {
+  async _prepareRemoveEntityTypeOperations(type, id, reason) {
     const operations = []
 
     if (type === objectType.OBJECT_TYPE) {
@@ -229,32 +226,78 @@ export default class TypeBrowserController extends BrowserController {
       )
     }
 
-    const criteria = new openbis.PropertyTypeSearchCriteria()
-    criteria.withCode().thatStartsWith(id + '.')
-    const fo = new openbis.PropertyTypeFetchOptions()
+    const removeUnusuedPropertyTypesOperation =
+      await this._prepareRemoveUnusedPropertyTypesOperations(type, id)
 
-    return openbis.searchPropertyTypes(criteria, fo).then(results => {
-      const ids = results
-        .getObjects()
-        .map(propertyType => propertyType.getPermId())
-      if (!_.isEmpty(ids)) {
-        const options = new openbis.PropertyTypeDeletionOptions()
-        options.setReason(reason)
-        operations.push(new openbis.DeletePropertyTypesOperation(ids, options))
+    if (removeUnusuedPropertyTypesOperation) {
+      operations.push(removeUnusuedPropertyTypesOperation)
+    }
+
+    return operations
+  }
+
+  async _prepareRemoveUnusedPropertyTypesOperations(type, id) {
+    const entityKind = this.getEntityKind(type)
+
+    const propertyAssignmentFetchOptions =
+      new openbis.PropertyAssignmentFetchOptions()
+    propertyAssignmentFetchOptions.withPropertyType()
+    propertyAssignmentFetchOptions.withEntityType()
+
+    const propertyAssignments = await openbis.searchPropertyAssignments(
+      new openbis.PropertyAssignmentSearchCriteria(),
+      propertyAssignmentFetchOptions
+    )
+
+    const potentialPropertyTypesToDelete = []
+    const propertyTypeUsages = {}
+
+    propertyAssignments.objects.forEach(propertyAssignment => {
+      const propertyTypeCode = propertyAssignment.propertyType.code
+
+      propertyTypeUsages[propertyTypeCode] =
+        (propertyTypeUsages[propertyTypeCode] || 0) + 1
+
+      if (
+        propertyAssignment.entityType.permId.permId === id &&
+        propertyAssignment.entityType.permId.entityKind === entityKind &&
+        !propertyAssignment.propertyType.managedInternally
+      ) {
+        potentialPropertyTypesToDelete.push(propertyTypeCode)
       }
-      return operations
     })
+
+    if (potentialPropertyTypesToDelete.length > 0) {
+      const propertyTypesToDelete = []
+
+      potentialPropertyTypesToDelete.forEach(propertyTypeCode => {
+        if (propertyTypeUsages[propertyTypeCode] === 1) {
+          propertyTypesToDelete.push(
+            new openbis.PropertyTypePermId(propertyTypeCode)
+          )
+        }
+      })
+
+      if (propertyTypesToDelete.length > 0) {
+        const options = new openbis.PropertyTypeDeletionOptions()
+        options.setReason('deleted via ng_ui')
+        return new openbis.DeletePropertyTypesOperation(
+          propertyTypesToDelete,
+          options
+        )
+      }
+    }
+
+    return null
   }
 
-  _prepareRemoveVocabularyTypeOperations(type, id, reason) {
+  async _prepareRemoveVocabularyTypeOperations(type, id, reason) {
     const options = new openbis.VocabularyDeletionOptions()
     options.setReason(reason)
-    return Promise.resolve([
-      new openbis.DeleteVocabulariesOperation(
-        [new openbis.VocabularyPermId(id)],
-        options
-      )
-    ])
+    return new openbis.DeleteVocabulariesOperation(
+      [new openbis.VocabularyPermId(id)],
+      options
+    )
   }
 
   doGetObservedModifications() {
@@ -282,6 +325,18 @@ export default class TypeBrowserController extends BrowserController {
     }
   }
 
+  getEntityKind(type) {
+    if (type === objectType.OBJECT_TYPE) {
+      return openbis.EntityKind.SAMPLE
+    } else if (type === objectType.COLLECTION_TYPE) {
+      return openbis.EntityKind.EXPERIMENT
+    } else if (type === objectType.DATA_SET_TYPE) {
+      return openbis.EntityKind.DATA_SET
+    } else if (type === objectType.MATERIAL_TYPE) {
+      return openbis.EntityKind.MATERIAL
+    }
+  }
+
   isSystemUser() {
     return (
       this.context.getProps().session &&