diff --git a/db/v-2/tables/db.changelog-tables.xml b/db/v-2/tables/db.changelog-tables.xml
index 0f3a5d6335..a1c66fc672 100644
--- a/db/v-2/tables/db.changelog-tables.xml
+++ b/db/v-2/tables/db.changelog-tables.xml
@@ -58,6 +58,7 @@
+
diff --git a/db/v-2/tables/link-between-cosv-file-and-vulnerability-metadata.xml b/db/v-2/tables/link-between-cosv-file-and-vulnerability-metadata.xml
index 8eb4f75f89..152dbf20ec 100644
--- a/db/v-2/tables/link-between-cosv-file-and-vulnerability-metadata.xml
+++ b/db/v-2/tables/link-between-cosv-file-and-vulnerability-metadata.xml
@@ -28,4 +28,8 @@
referencedColumnNames="id"
onDelete="CASCADE"/>
+
+
+
\ No newline at end of file
diff --git a/db/v-2/tables/vulnerability-generated-id.xml b/db/v-2/tables/vulnerability-generated-id.xml
new file mode 100644
index 0000000000..929ecbef2d
--- /dev/null
+++ b/db/v-2/tables/vulnerability-generated-id.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/vulnerability/VulnerabilityService.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/vulnerability/VulnerabilityService.kt
index 328375eae9..3698baa4c2 100644
--- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/vulnerability/VulnerabilityService.kt
+++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/vulnerability/VulnerabilityService.kt
@@ -28,9 +28,7 @@ import reactor.kotlin.core.publisher.toMono
import javax.persistence.criteria.*
-import kotlin.random.Random
import kotlinx.datetime.LocalDateTime
-import kotlinx.datetime.toJavaLocalDateTime
/**
* A service that provides `Vulnerability`
@@ -48,6 +46,7 @@ class VulnerabilityService(
private val vulnerabilityMetadataRepository: VulnerabilityMetadataRepository,
private val lnkVulnerabilityMetadataTagRepository: LnkVulnerabilityMetadataTagRepository,
private val tagRepository: TagRepository,
+ private val vulnerabilityGeneratedIdRepository: VulnerabilityGeneratedIdRepository,
) {
private fun List.toTagMap() = lnkVulnerabilityMetadataTagRepository.findAllById(this.map { it.requiredId() })
.map { link -> link.vulnerabilityMetadata to link.tag }
@@ -121,7 +120,7 @@ class VulnerabilityService(
val namePredicate = if (identifierPrefix.isBlank()) {
cb.and()
} else {
- cb.like(root.get("cosvId"), "%$identifierPrefix%")
+ cb.like(root.get("identifier"), "%$identifierPrefix%")
}
val ownerPredicate = authentication?.let {
@@ -213,26 +212,7 @@ class VulnerabilityService(
authentication: Authentication,
): Mono = blockingToMono {
vulnerabilityDto.identifier.ifEmpty {
- val metadata = vulnerabilityMetadataRepository.saveAndFlush(
- VulnerabilityMetadata(
- identifier = "default-${Random.nextInt()}",
- summary = "STUB",
- details = "STUB",
- severityNum = 0f,
- submitted = getCurrentLocalDateTime().toJavaLocalDateTime(),
- modified = getCurrentLocalDateTime().toJavaLocalDateTime(),
- user = userRepository.getByIdOrNotFound(authentication.userId()),
- organization = null,
- language = VulnerabilityLanguage.OTHER,
- status = VulnerabilityStatus.PENDING_REVIEW,
- latestCosvFile = null,
- )
- )
- val newName = "SOTV-${getCurrentLocalDateTime().year}-${metadata.requiredId()}"
- vulnerabilityMetadataRepository.save(metadata.apply {
- identifier = newName
- })
- newName
+ vulnerabilityGeneratedIdRepository.saveAndFlush(VulnerabilityGeneratedId()).getIdentifier()
}
}
.flatMap { identifier ->
diff --git a/save-backend/src/test/kotlin/com/saveourtool/save/backend/DatabaseTest.kt b/save-backend/src/test/kotlin/com/saveourtool/save/backend/DatabaseTest.kt
index 70fcc4a603..05a2af2878 100644
--- a/save-backend/src/test/kotlin/com/saveourtool/save/backend/DatabaseTest.kt
+++ b/save-backend/src/test/kotlin/com/saveourtool/save/backend/DatabaseTest.kt
@@ -33,6 +33,7 @@ import org.springframework.context.annotation.Import
MockBean(RawCosvFileRepository::class),
MockBean(CosvFileRepository::class),
MockBean(BlockingBridge::class),
+ MockBean(VulnerabilityGeneratedIdRepository::class),
)
class DatabaseTest {
@Autowired
diff --git a/save-backend/src/test/kotlin/com/saveourtool/save/backend/DownloadFilesTest.kt b/save-backend/src/test/kotlin/com/saveourtool/save/backend/DownloadFilesTest.kt
index b533493fb6..2ae0baf586 100644
--- a/save-backend/src/test/kotlin/com/saveourtool/save/backend/DownloadFilesTest.kt
+++ b/save-backend/src/test/kotlin/com/saveourtool/save/backend/DownloadFilesTest.kt
@@ -78,6 +78,7 @@ import kotlin.io.path.*
MockBean(RawCosvFileRepository::class),
MockBean(CosvFileRepository::class),
MockBean(BlockingBridge::class),
+ MockBean(VulnerabilityGeneratedIdRepository::class),
)
class DownloadFilesTest {
private val organization = Organization.stub(2).apply {
diff --git a/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/JpaSpecificationTest.kt b/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/JpaSpecificationTest.kt
index 4b18b4f966..8b8bc0f226 100644
--- a/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/JpaSpecificationTest.kt
+++ b/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/JpaSpecificationTest.kt
@@ -30,6 +30,7 @@ import org.springframework.context.annotation.Import
MockBean(RawCosvFileRepository::class),
MockBean(CosvFileRepository::class),
MockBean(BlockingBridge::class),
+ MockBean(VulnerabilityGeneratedIdRepository::class),
)
class JpaSpecificationTest {
@Autowired
diff --git a/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/LnkUserOrganizationControllerTest.kt b/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/LnkUserOrganizationControllerTest.kt
index 36f09e93d8..cb58d5958a 100644
--- a/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/LnkUserOrganizationControllerTest.kt
+++ b/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/LnkUserOrganizationControllerTest.kt
@@ -43,6 +43,7 @@ import org.springframework.test.web.reactive.server.WebTestClient
MockBean(RawCosvFileRepository::class),
MockBean(CosvFileRepository::class),
MockBean(BlockingBridge::class),
+ MockBean(VulnerabilityGeneratedIdRepository::class),
)
@AutoConfigureWebTestClient
class LnkUserOrganizationControllerTest {
diff --git a/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/OrganizationControllerTest.kt b/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/OrganizationControllerTest.kt
index 0aceeb3945..554606b5d4 100644
--- a/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/OrganizationControllerTest.kt
+++ b/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/OrganizationControllerTest.kt
@@ -95,6 +95,7 @@ import java.util.concurrent.TimeUnit
MockBean(RawCosvFileRepository::class),
MockBean(CosvFileRepository::class),
MockBean(BlockingBridge::class),
+ MockBean(VulnerabilityGeneratedIdRepository::class),
)
@AutoConfigureWebTestClient
@Suppress("UnsafeCallOnNullableType")
diff --git a/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/PermissionControllerTest.kt b/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/PermissionControllerTest.kt
index d14c5fcdef..a2d1002b51 100644
--- a/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/PermissionControllerTest.kt
+++ b/save-backend/src/test/kotlin/com/saveourtool/save/backend/controller/PermissionControllerTest.kt
@@ -52,6 +52,7 @@ import reactor.util.function.Tuples
MockBean(RawCosvFileRepository::class),
MockBean(CosvFileRepository::class),
MockBean(BlockingBridge::class),
+ MockBean(VulnerabilityGeneratedIdRepository::class),
)
@AutoConfigureWebTestClient
class PermissionControllerTest {
diff --git a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/VulnerabilityGeneratedId.kt b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/VulnerabilityGeneratedId.kt
new file mode 100644
index 0000000000..035099ce4b
--- /dev/null
+++ b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/VulnerabilityGeneratedId.kt
@@ -0,0 +1,15 @@
+package com.saveourtool.save.entities.cosv
+
+import com.saveourtool.save.spring.entity.BaseEntityWithDate
+import javax.persistence.Entity
+
+/**
+ * Entity for generated id of vulnerability
+ */
+@Entity
+class VulnerabilityGeneratedId : BaseEntityWithDate() {
+ /**
+ * @return Vulnerability identifier for saved entity
+ */
+ fun getIdentifier(): String = "SOTV-${requiredCreateDate().year}-${requiredId()}"
+}
diff --git a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/VulnerabilityMetadata.kt b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/VulnerabilityMetadata.kt
index 4655eca389..23d25c0eb0 100644
--- a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/VulnerabilityMetadata.kt
+++ b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/VulnerabilityMetadata.kt
@@ -45,16 +45,8 @@ class VulnerabilityMetadata(
var organization: Organization?,
@OneToOne
@JoinColumn(name = "latest_cosv_file_id")
- var latestCosvFile: CosvFile?,
+ var latestCosvFile: CosvFile,
) : BaseEntityWithDto() {
- /**
- * @return [latestCosvFile] as not null with validating
- * @throws IllegalArgumentException when [latestCosvFile] is not set that means entity is created to generate a unique identifier
- */
- fun requiredLatestCosvFile(): CosvFile = requireNotNull(latestCosvFile) {
- "Entity is in internal state: $this"
- }
-
override fun toDto(): VulnerabilityMetadataDto = VulnerabilityMetadataDto(
identifier = identifier,
summary = summary,
diff --git a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/repository/VulnerabilityGeneratedIdRepository.kt b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/repository/VulnerabilityGeneratedIdRepository.kt
new file mode 100644
index 0000000000..88866b8216
--- /dev/null
+++ b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/repository/VulnerabilityGeneratedIdRepository.kt
@@ -0,0 +1,11 @@
+package com.saveourtool.save.cosv.repository
+
+import com.saveourtool.save.entities.cosv.VulnerabilityGeneratedId
+import com.saveourtool.save.spring.repository.BaseEntityRepository
+import org.springframework.stereotype.Repository
+
+/**
+ * Repository for [VulnerabilityGeneratedId]
+ */
+@Repository
+interface VulnerabilityGeneratedIdRepository : BaseEntityRepository
diff --git a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/CosvService.kt b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/CosvService.kt
index 3877d5f9e7..0561307e25 100644
--- a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/CosvService.kt
+++ b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/CosvService.kt
@@ -21,7 +21,6 @@ import org.springframework.stereotype.Service
import reactor.core.publisher.Mono
import reactor.kotlin.core.publisher.toFlux
-import kotlinx.serialization.SerializationException
import kotlinx.serialization.serializer
private typealias ManualCosvSchema = CosvSchema
@@ -65,17 +64,25 @@ class CosvService(
): Mono = rawCosvFileStorage.downloadById(rawCosvFileId)
.collectToInputStream()
.flatMap { inputStream ->
- val cosvListOpt = try {
+ val errorMessage by lazy {
+ "Failed to process raw COSV file with id: $rawCosvFileId"
+ }
+ Mono.fromCallable {
cosvProcessor.decode(inputStream)
- } catch (e: SerializationException) {
- val errorMessage: () -> String = { "Failed to process raw COSV file with id: $rawCosvFileId" }
- log.error(e, errorMessage)
- return@flatMap rawCosvFileStorage.update(rawCosvFileId, RawCosvFileStatus.FAILED, "$errorMessage is due to ${e.message}")
}
- cosvListOpt.toFlux()
- .flatMap { save(it, user, organization) }
+ .flatMapIterable { it }
+ .flatMap { save(it, user, organization, isAutoApprove = true) }
+ .onErrorResume { error ->
+ val cause = error.firstCauseOrThis()
+ rawCosvFileStorage.update(rawCosvFileId, RawCosvFileStatus.FAILED, "$errorMessage is due to ${cause.message}")
+ .then(Mono.error(error))
+ }
.collectList()
.flatMap { rawCosvFileStorage.update(rawCosvFileId, RawCosvFileStatus.PROCESSED, "Processed as ${it.map(VulnerabilityMetadataDto::identifier)}") }
+ .onErrorResume { error ->
+ log.error(error) { errorMessage }
+ Mono.just(Unit)
+ }
}
/**
@@ -154,10 +161,11 @@ class CosvService(
cosv: CosvSchema,
user: User,
organization: Organization?,
+ isAutoApprove: Boolean = false,
): Mono = cosvRepository.save(cosv, serializer())
.flatMap { key ->
blockingToMono {
- vulnerabilityMetadataService.createOrUpdate(key, cosv, user, organization).toDto()
+ vulnerabilityMetadataService.createOrUpdate(key, cosv, user, organization, isAutoApprove).toDto()
}
.onErrorResume { error ->
log.error(error) {
@@ -175,7 +183,7 @@ class CosvService(
*/
fun getVulnerabilityExt(identifier: String): Mono = blockingToMono { vulnerabilityMetadataService.findByIdentifier(identifier) }
.flatMap { metadata ->
- cosvRepository.download(metadata.requiredLatestCosvFile(), serializer()).blockingMap { content ->
+ cosvRepository.download(metadata.latestCosvFile, serializer()).blockingMap { content ->
VulnerabilityExt(
metadata = metadata.toDto(),
cosv = content,
@@ -187,5 +195,6 @@ class CosvService(
companion object {
private val log: Logger = getLogger()
+ private fun Throwable.firstCauseOrThis(): Throwable = generateSequence(this, Throwable::cause).last()
}
}
diff --git a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/VulnerabilityMetadataService.kt b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/VulnerabilityMetadataService.kt
index 6d872c5b52..2ed803b105 100644
--- a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/VulnerabilityMetadataService.kt
+++ b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/VulnerabilityMetadataService.kt
@@ -33,6 +33,7 @@ class VulnerabilityMetadataService(
* @param cosv
* @param user
* @param organization
+ * @param isAutoApprove
* @return updated [VulnerabilityMetadata]
*/
@Transactional
@@ -41,15 +42,16 @@ class VulnerabilityMetadataService(
cosv: AnyCosvSchema,
user: User,
organization: Organization?,
+ isAutoApprove: Boolean,
): VulnerabilityMetadata {
val metadata = vulnerabilityMetadataRepository.findByIdentifier(cosv.id)
?.let { existedMetadata ->
validateMetadata(existedMetadata, cosv, user, organization)
cosvFileS3KeyManager.setPrevCosvFile(cosvFile, existedMetadata)
- existedMetadata.updateBy(cosv, cosvFile)
+ existedMetadata.updateBy(cosv, cosvFile, isAutoApprove)
}
?: run {
- cosv.toNewMetadata(user, organization, cosvFile)
+ cosv.toNewMetadata(user, organization, cosvFile, isAutoApprove)
}
return vulnerabilityMetadataRepository.save(metadata)
}
@@ -67,6 +69,7 @@ class VulnerabilityMetadataService(
user: User,
organization: Organization?,
cosvFile: CosvFile,
+ isAutoApprove: Boolean,
) = VulnerabilityMetadata(
identifier = id,
summary = summary ?: "Summary not provided",
@@ -77,7 +80,7 @@ class VulnerabilityMetadataService(
user = user,
organization = organization,
language = getLanguage() ?: VulnerabilityLanguage.OTHER,
- status = VulnerabilityStatus.PENDING_REVIEW,
+ status = isAutoApprove.toVulnerabilityStatus(),
latestCosvFile = cosvFile,
)
@@ -117,6 +120,7 @@ class VulnerabilityMetadataService(
private fun VulnerabilityMetadata.updateBy(
entry: CosvSchema<*, *, *, *>,
cosvFile: CosvFile,
+ isAutoApprove: Boolean,
): VulnerabilityMetadata = apply {
summary = entry.summary ?: "Summary not provided"
details = entry.details ?: "Details not provided"
@@ -125,6 +129,9 @@ class VulnerabilityMetadataService(
?.toFloat() ?: 0f
modified = entry.modified.toJavaLocalDateTime()
latestCosvFile = cosvFile
+ status = isAutoApprove.toVulnerabilityStatus()
}
+
+ private fun Boolean.toVulnerabilityStatus() = if (this) VulnerabilityStatus.APPROVED else VulnerabilityStatus.PENDING_REVIEW
}
}
diff --git a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/storage/CosvFileS3KeyManager.kt b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/storage/CosvFileS3KeyManager.kt
index 61ec215c10..bb69c7e7ca 100644
--- a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/storage/CosvFileS3KeyManager.kt
+++ b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/storage/CosvFileS3KeyManager.kt
@@ -44,7 +44,7 @@ class CosvFileS3KeyManager(
vulnerabilityMetadata: VulnerabilityMetadata,
): CosvFile = repository.save(
cosvFile.apply {
- this.prevCosvFile = vulnerabilityMetadata.requiredLatestCosvFile()
+ this.prevCosvFile = vulnerabilityMetadata.latestCosvFile
}
)
}
diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/CosvFileManagerComponent.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/CosvFileManagerComponent.kt
index c6cd2cf5c3..283ae9b43d 100644
--- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/CosvFileManagerComponent.kt
+++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/CosvFileManagerComponent.kt
@@ -142,7 +142,7 @@ val cosvFileManagerComponent: FC = FC { _ ->
type = InputType.checkbox
id = "checkbox"
checked = file in selectedFiles
- disabled = file.status in setOf(RawCosvFileStatus.PROCESSED, RawCosvFileStatus.IN_PROGRESS)
+ disabled = file.isNotSelectable()
onChange = { event ->
if (event.target.checked) {
setSelectedFiles { it.plus(file) }
@@ -189,6 +189,7 @@ val cosvFileManagerComponent: FC = FC { _ ->
li {
className = ClassName("list-group-item p-0 d-flex bg-light")
dragAndDropForm {
+ isDisabled = selectedOrganization.isNullOrEmpty()
isMultipleFilesSupported = true
tooltipMessage = "Only JSON files"
onChangeEventHandler = { files ->
@@ -200,6 +201,9 @@ val cosvFileManagerComponent: FC = FC { _ ->
// SUBMIT to process
li {
className = ClassName("list-group-item p-0 d-flex bg-light justify-content-center")
+ buttonBuilder("Select all", isDisabled = availableFiles.isEmpty()) {
+ setSelectedFiles(availableFiles.filterNot { it.isNotSelectable() })
+ }
buttonBuilder("Submit", isDisabled = selectedFiles.isEmpty()) {
submitCosvFiles()
}
@@ -207,3 +211,5 @@ val cosvFileManagerComponent: FC = FC { _ ->
}
}
}
+
+private fun RawCosvFileDto.isNotSelectable() = status in setOf(RawCosvFileStatus.PROCESSED, RawCosvFileStatus.IN_PROGRESS)
diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/FileManagerComponent.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/FileManagerComponent.kt
index ac58c7db55..872ae129a4 100644
--- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/FileManagerComponent.kt
+++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/FileManagerComponent.kt
@@ -9,7 +9,6 @@ package com.saveourtool.save.frontend.components.basic.fileuploader
import com.saveourtool.save.domain.ProjectCoordinates
import com.saveourtool.save.entities.FileDto
import com.saveourtool.save.frontend.components.inputform.dragAndDropForm
-import com.saveourtool.save.frontend.externals.fontawesome.*
import com.saveourtool.save.frontend.http.postUploadFile
import com.saveourtool.save.frontend.utils.*
import com.saveourtool.save.frontend.utils.noopLoadingHandler
@@ -117,6 +116,7 @@ val fileManagerComponent: FC = FC { props ->
li {
className = ClassName("list-group-item p-0 d-flex bg-light")
dragAndDropForm {
+ isDisabled = false
isMultipleFilesSupported = true
tooltipMessage = "Regular files/Executable files/ZIP Archives"
onChangeEventHandler = { files ->
diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/SandboxFileUploader.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/SandboxFileUploader.kt
index bc03741d5c..e25899fb37 100644
--- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/SandboxFileUploader.kt
+++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/fileuploader/SandboxFileUploader.kt
@@ -9,7 +9,6 @@ package com.saveourtool.save.frontend.components.basic.fileuploader
import com.saveourtool.save.domain.*
import com.saveourtool.save.frontend.components.basic.codeeditor.FileType
import com.saveourtool.save.frontend.components.inputform.dragAndDropForm
-import com.saveourtool.save.frontend.externals.fontawesome.*
import com.saveourtool.save.frontend.http.postUploadFile
import com.saveourtool.save.frontend.utils.*
import com.saveourtool.save.frontend.utils.noopLoadingHandler
@@ -101,6 +100,7 @@ val sandboxFileUploader: FC = FC { props ->
li {
className = ClassName("list-group-item p-0 d-flex bg-light")
dragAndDropForm {
+ isDisabled = false
isMultipleFilesSupported = false
tooltipMessage = "upload your tested tool and all other needed files"
onChangeEventHandler = { files ->
diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/inputform/DragAndDropForm.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/inputform/DragAndDropForm.kt
index bea0c8e37f..454304cc84 100644
--- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/inputform/DragAndDropForm.kt
+++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/inputform/DragAndDropForm.kt
@@ -63,6 +63,7 @@ val dragAndDropForm: FC = FC { props ->
multiple = props.isMultipleFilesSupported
hidden = true
onChange = { props.onChangeEventHandler(it.target.files) }
+ disabled = props.isDisabled
}
strong { +" Click or drag'n'drop a file " }
onClick = { onButtonClick() }
@@ -91,4 +92,9 @@ external interface DragAndDropFormProps : Props {
* Tooltip message that should be displayed
*/
var tooltipMessage: String?
+
+ /**
+ * Flag that defines if the form is enabled
+ */
+ var isDisabled: Boolean
}