Skip to content

Commit

Permalink
Merge branch 'refs/heads/staging' into NU-1826-comements-and-attachme…
Browse files Browse the repository at this point in the history
…nt-crud

# Conflicts:
#	designer/client/cypress/e2e/__image_snapshots__/electron/Linux/Activities should display activities #0.png
#	designer/client/cypress/e2e/__image_snapshots__/electron/Linux/Activities should display activities #1.png
#	designer/client/cypress/e2e/__image_snapshots__/electron/Linux/Activities should display activities #2.png
#	designer/client/cypress/e2e/__image_snapshots__/electron/Linux/Activities should display activities #3.png
#	designer/client/src/components/modals/AddCommentDialog.tsx
#	designer/client/src/components/toolbars/activities/ActivitiesPanelRow.tsx
#	designer/client/src/components/toolbars/activities/ActivityPanelRowItem/ActivityItem.tsx
#	designer/client/src/components/toolbars/activities/ActivityPanelRowItem/ActivityItemHeader.tsx
#	designer/client/src/components/toolbars/activities/types.ts
#	designer/client/src/components/toolbars/activities/useActivitiesSearch.ts
#	designer/client/src/http/HttpService.ts
#	designer/client/src/windowManager/ContentGetter.tsx
#	designer/client/src/windowManager/WindowKind.tsx
  • Loading branch information
Dzuming committed Oct 24, 2024
2 parents d3f9b8c + aece59e commit 53d1fde
Show file tree
Hide file tree
Showing 40 changed files with 1,151 additions and 554 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ package pl.touk.nussknacker.engine.api

import io.circe.{Decoder, Encoder}

final case class Comment(content: String) extends AnyVal {
final case class Comment private (content: String) extends AnyVal {
override def toString: String = content
}

object Comment {

def from(content: String): Option[Comment] = {
if (content.isEmpty) None else Some(Comment(content))
}

implicit val encoder: Encoder[Comment] = Encoder.encodeString.contramap(_.content)
implicit val decoder: Decoder[Comment] = Decoder.decodeString.map(Comment.apply)
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion designer/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@
"start-prod": "BACKEND_DOMAIN=http://localhost:${BE_PORT:-8080} node server.js",
"start:backend-docker": "npm run clean-translations && (! wait-on -t 250 tcp:localhost:${BE_PORT:-8080} 2> /dev/null || (echo \"Port: ${BE_PORT:-8080} already in use!\" && exit 1)) && start-server-and-test backend:docker http-get://localhost:${BE_PORT:-8080}/static/main.html start",
"start:backend-remote": "npm run clean-translations && webpack serve",
"start:backend-staging": "BACKEND_DOMAIN=https://staging.nussknacker.io npm run start:backend-remote",
"start:backend-staging": "BACKEND_DOMAIN=https://activities-demo.sandbox.nussknacker.io npm run start:backend-remote",
"start:backend-demo": "BACKEND_DOMAIN=https://demo.nussknacker.io npm run start:backend-remote",
"backend:docker": "docker-compose kill && docker-compose rm -f -v && docker-compose up --no-recreate",
"pretest": "npm run check",
Expand Down
6 changes: 3 additions & 3 deletions designer/client/src/components/modals/AddAttachmentDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ const AddAttachmentDialog = (props: WindowContentProps) => {
);
const results = await Promise.all(attachmentPromises);

if (results.every((result) => result === "success")) {
if (results.every(({ status }) => status === "success")) {
props.close();
}

if (results.some((result) => result === "success")) {
if (results.some(({ status }) => status === "success")) {
await dispatch(await getScenarioActivities(processName));
}
}, [attachments, processName, processVersionId, props]);
}, [attachments, dispatch, processName, processVersionId, props]);

const buttons: WindowButtonProps[] = useMemo(
() => [
Expand Down
2 changes: 2 additions & 0 deletions designer/server/src/main/resources/defaultDesignerConfig.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ db {
minimumIdle: 1
#has to be lower <= maxConnections
numThreads: 5
registerMbeans: true
poolName: "Nussknacker"
properties: {
# PostgreSQL specific
"ApplicationName": "Nussknacker"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ import pl.touk.nussknacker.security.Permission
import pl.touk.nussknacker.security.Permission.Permission
import pl.touk.nussknacker.ui.api.description.scenarioActivity.Dtos.ScenarioActivityError.{
NoActivity,
NoAttachment,
NoComment,
NoPermission,
NoScenario
}
import pl.touk.nussknacker.ui.api.description.scenarioActivity.Dtos._
import pl.touk.nussknacker.ui.api.description.scenarioActivity.{Dtos, Endpoints}
import pl.touk.nussknacker.ui.process.ProcessService.GetScenarioWithDetailsOptions
import pl.touk.nussknacker.ui.process.deployment.DeploymentManagerDispatcher
import pl.touk.nussknacker.ui.process.repository.DBIOActionRunner
import pl.touk.nussknacker.ui.process.repository.activities.ScenarioActivityRepository
import pl.touk.nussknacker.ui.process.repository.activities.ScenarioActivityRepository.DeleteAttachmentError
import pl.touk.nussknacker.ui.process.{ProcessService, ScenarioAttachmentService}
import pl.touk.nussknacker.ui.security.api.{AuthManager, LoggedUser}
import pl.touk.nussknacker.ui.server.HeadersSupport.ContentDisposition
Expand All @@ -29,6 +32,7 @@ import sttp.model.MediaType

import java.io.ByteArrayInputStream
import java.net.URLConnection
import java.time.ZoneId
import scala.concurrent.{ExecutionContext, Future}

class ScenarioActivityApiHttpService(
Expand All @@ -44,9 +48,11 @@ class ScenarioActivityApiHttpService(
extends BaseHttpService(authManager)
with LazyLogging {

private implicit val zoneId: ZoneId = ZoneId.systemDefault()

private val securityInput = authManager.authenticationEndpointInput()

private val endpoints = new Endpoints(securityInput, streamEndpointProvider)
private val endpoints = new Endpoints(securityInput, streamEndpointProvider, zoneId)

expose {
endpoints.deprecatedScenarioActivityEndpoint
Expand Down Expand Up @@ -96,6 +102,18 @@ class ScenarioActivityApiHttpService(
}
}

expose {
endpoints.deleteAttachmentEndpoint
.serverSecurityLogic(authorizeKnownUser[ScenarioActivityError])
.serverLogicEitherT { implicit loggedUser => request: DeleteAttachmentRequest =>
for {
scenarioId <- getScenarioIdByName(request.scenarioName)
_ <- isAuthorized(scenarioId, Permission.Write)
_ <- markAttachmentAsDeleted(request, scenarioId)
} yield ()
}
}

expose {
endpoints.downloadAttachmentEndpoint
.serverSecurityLogic(authorizeKnownUser[ScenarioActivityError])
Expand Down Expand Up @@ -140,7 +158,14 @@ class ScenarioActivityApiHttpService(
for {
scenarioId <- getScenarioIdByName(scenarioName)
_ <- isAuthorized(scenarioId, Permission.Read)
metadata = ScenarioActivitiesMetadata.default
scenarioWithDetails <- EitherT.right(
scenarioService.getLatestProcessWithDetails(
ProcessIdWithName(scenarioId, scenarioName),
GetScenarioWithDetailsOptions.detailsOnly
)
)
scenarioType = if (scenarioWithDetails.isFragment) ScenarioType.Fragment else ScenarioType.Scenario
metadata = ScenarioActivitiesMetadata.default(scenarioType)
} yield metadata
}
}
Expand Down Expand Up @@ -246,21 +271,19 @@ class ScenarioActivityApiHttpService(
} yield sortedResult
}

private def toDto(scenarioComment: ScenarioComment): Dtos.ScenarioActivityComment = {
scenarioComment match {
case ScenarioComment.Available(comment, lastModifiedByUserName, lastModifiedAt) =>
Dtos.ScenarioActivityComment(
content = Dtos.ScenarioActivityCommentContent.Available(comment),
lastModifiedBy = lastModifiedByUserName.value,
lastModifiedAt = lastModifiedAt,
)
case ScenarioComment.Deleted(deletedByUserName, deletedAt) =>
Dtos.ScenarioActivityComment(
content = Dtos.ScenarioActivityCommentContent.Deleted,
lastModifiedBy = deletedByUserName.value,
lastModifiedAt = deletedAt,
)
}
private def toDto(scenarioComment: ScenarioComment): Dtos.ScenarioActivityComment = scenarioComment match {
case ScenarioComment.WithContent(comment, _, _) =>
Dtos.ScenarioActivityComment(
content = Dtos.ScenarioActivityCommentContent.Available(comment),
lastModifiedBy = scenarioComment.lastModifiedByUserName.value,
lastModifiedAt = scenarioComment.lastModifiedAt,
)
case ScenarioComment.WithoutContent(_, _) =>
Dtos.ScenarioActivityComment(
content = Dtos.ScenarioActivityCommentContent.NotAvailable,
lastModifiedBy = scenarioComment.lastModifiedByUserName.value,
lastModifiedAt = scenarioComment.lastModifiedAt,
)
}

private def toDto(attachment: ScenarioAttachment): Dtos.ScenarioActivityAttachment = {
Expand Down Expand Up @@ -558,6 +581,15 @@ class ScenarioActivityApiHttpService(
)
}

private def markAttachmentAsDeleted(request: DeleteAttachmentRequest, scenarioId: ProcessId)(
implicit loggedUser: LoggedUser
): EitherT[Future, ScenarioActivityError, Unit] =
EitherT(
dbioActionRunner.run(
scenarioActivityRepository.markAttachmentAsDeleted(scenarioId, request.attachmentId)
)
).leftMap { case DeleteAttachmentError.CouldNotDeleteAttachment => NoAttachment(request.attachmentId) }

private def buildResponse(maybeAttachment: Option[(String, Array[Byte])]): GetAttachmentResponse =
maybeAttachment match {
case Some((fileName, content)) =>
Expand Down
Loading

0 comments on commit 53d1fde

Please sign in to comment.