Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add preview in details page #2756

Draft
wants to merge 14 commits into
base: refactor-search-engine
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions core/amber/node_modules/.yarn-integrity

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/amber/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@ fault-tolerance {
region-plan-generator {
enable-cost-based-region-plan-generator = false
use-global-search = false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package edu.uci.ics.texera.web.resource.dashboard.hub.test

import edu.uci.ics.texera.web.SqlServer
import edu.uci.ics.texera.web.auth.SessionUser
import org.jooq.types.UInteger

import java.util

import edu.uci.ics.texera.web.resource.dashboard.hub.test.TestHubResource.Workflow

import javax.ws.rs._
import javax.ws.rs.core.MediaType
import edu.uci.ics.texera.web.model.jooq.generated.Tables._
import edu.uci.ics.texera.web.resource.dashboard.hub.test.TestHubResource.getAllWorkflows
import io.dropwizard.auth.Auth
import scala.jdk.CollectionConverters.IterableHasAsScala

object TestHubResource {
final private lazy val context = SqlServer.createDSLContext()

case class Workflow(
workflowId: UInteger,
workflowName: String
)

def getAllWorkflows: List[Workflow] = {
val allWorkflowEntries = context
.select(
WORKFLOW.WID,
WORKFLOW.NAME
)
.from(
WORKFLOW
)
.fetch()

allWorkflowEntries
.map(workflowRecord => {
Workflow(
workflowRecord.get(WORKFLOW.WID),
workflowRecord.get(WORKFLOW.NAME)
)
})
.asScala
.toList
}
}


@Path("/hub")
class TestHubResource {
@GET
@Path("/get_all_workflows")
@Produces(Array(MediaType.APPLICATION_JSON))
def getCreatedWorkflow: List[Workflow] = {
getAllWorkflows
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import edu.uci.ics.texera.web.model.jooq.generated.Tables.{
PROJECT_USER_ACCESS,
USER,
WORKFLOW_OF_PROJECT,
WORKFLOW_USER_ACCESS
WORKFLOW_USER_ACCESS,
WORKFLOW
}
import edu.uci.ics.texera.web.model.jooq.generated.enums.WorkflowUserAccessPrivilege
import edu.uci.ics.texera.web.model.jooq.generated.tables.daos.{
Expand Down Expand Up @@ -36,7 +37,7 @@ object WorkflowAccessResource {
* @return boolean value indicating yes/no
*/
def hasReadAccess(wid: UInteger, uid: UInteger): Boolean = {
getPrivilege(wid, uid).eq(WorkflowUserAccessPrivilege.READ) || hasWriteAccess(wid, uid)
isPublic(wid) || getPrivilege(wid, uid).eq(WorkflowUserAccessPrivilege.READ) || hasWriteAccess(wid, uid)
}

/**
Expand Down Expand Up @@ -77,6 +78,14 @@ object WorkflowAccessResource {
access.getPrivilege
}
}

def isPublic(wid: UInteger): Boolean = {
context
.select(WORKFLOW.IS_PUBLISHED)
.from(WORKFLOW)
.where(WORKFLOW.WID.eq(wid))
.fetchOneInto(classOf[Boolean])
}
}

@Produces(Array(MediaType.APPLICATION_JSON))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,11 @@ import com.typesafe.scalalogging.LazyLogging
import edu.uci.ics.texera.web.SqlServer
import edu.uci.ics.texera.web.auth.SessionUser
import edu.uci.ics.texera.web.model.jooq.generated.Tables._
import edu.uci.ics.texera.web.model.jooq.generated.enums.WorkflowUserAccessPrivilege
import edu.uci.ics.texera.web.model.jooq.generated.tables.daos.{
EnvironmentOfWorkflowDao,
WorkflowDao,
WorkflowOfProjectDao,
WorkflowOfUserDao,
WorkflowUserAccessDao
}
import edu.uci.ics.texera.web.model.jooq.generated.tables.pojos._
import edu.uci.ics.texera.web.model.jooq.generated.enums.{UserRole, WorkflowUserAccessPrivilege}
import edu.uci.ics.texera.web.model.jooq.generated.tables.daos.{EnvironmentOfWorkflowDao, WorkflowDao, WorkflowOfProjectDao, WorkflowOfUserDao, WorkflowUserAccessDao}
import edu.uci.ics.texera.web.model.jooq.generated.tables.pojos.{User, _}
import edu.uci.ics.texera.web.resource.dashboard.user.environment.EnvironmentResource
import edu.uci.ics.texera.web.resource.dashboard.user.environment.EnvironmentResource.{
createEnvironment,
doesWorkflowHaveEnvironment,
copyEnvironment
}
import edu.uci.ics.texera.web.resource.dashboard.user.environment.EnvironmentResource.{copyEnvironment, createEnvironment, doesWorkflowHaveEnvironment}
import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowAccessResource.hasReadAccess
import edu.uci.ics.texera.web.resource.dashboard.user.workflow.WorkflowResource._
import io.dropwizard.auth.Auth
Expand Down Expand Up @@ -122,7 +112,6 @@ object WorkflowResource {

}
@Produces(Array(MediaType.APPLICATION_JSON))
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/workflow")
class WorkflowResource extends LazyLogging {

Expand All @@ -132,6 +121,7 @@ class WorkflowResource extends LazyLogging {
* @return WorkflowID[]
*/
@GET
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/user-workflow-ids")
def retrieveIDs(@Auth user: SessionUser): util.List[String] = {
context
Expand All @@ -147,6 +137,7 @@ class WorkflowResource extends LazyLogging {
* @return OwnerName[]
*/
@GET
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/user-workflow-owners")
def retrieveOwners(@Auth user: SessionUser): util.List[String] = {
context
Expand All @@ -166,6 +157,7 @@ class WorkflowResource extends LazyLogging {
* @return WorkflowID[]
*/
@GET
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/search-by-operators")
def searchWorkflowByOperator(
@QueryParam("operator") operator: String,
Expand Down Expand Up @@ -218,6 +210,7 @@ class WorkflowResource extends LazyLogging {
* @return Workflow[]
*/
@GET
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/list")
def retrieveWorkflowsBySessionUser(
@Auth sessionUser: SessionUser
Expand Down Expand Up @@ -276,6 +269,7 @@ class WorkflowResource extends LazyLogging {
* @return a json string representing an savedWorkflow
*/
@GET
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/{wid}")
def retrieveWorkflow(
@PathParam("wid") wid: UInteger,
Expand All @@ -298,6 +292,41 @@ class WorkflowResource extends LazyLogging {
}
}

/**
* This method handles the client request to get a specific workflow to be displayed in canvas
* at current design, it only takes the workflowID and searches within the database for the matching workflow
* for future design, it should also take userID as an parameter.
*
* @param wid workflow id, which serves as the primary key in the UserWorkflow database
* @return a json string representing an savedWorkflow
*/
@GET
@Path("/public/{wid}")
def retrievePublicWorkflow(
@PathParam("wid") wid: UInteger
): WorkflowWithPrivilege = {
val dummyUser = new User()
dummyUser.setRole(UserRole.REGULAR)
Console.println(WorkflowAccessResource.hasReadAccess(wid, new SessionUser(dummyUser).getUid))
if (WorkflowAccessResource.hasReadAccess(wid, new SessionUser(dummyUser).getUid)) {
Console.println("has read access")
val workflow = workflowDao.fetchOneByWid(wid)
WorkflowWithPrivilege(
workflow.getName,
workflow.getDescription,
workflow.getWid,
workflow.getContent,
workflow.getCreationTime,
workflow.getLastModifiedTime,
workflow.getIsPublished,
true
)
} else {
Console.println("no read access")
throw new ForbiddenException("No sufficient access privilege.")
}
}

/**
* This method persists the workflow into database
*
Expand All @@ -309,6 +338,7 @@ class WorkflowResource extends LazyLogging {
*/
@POST
@Consumes(Array(MediaType.APPLICATION_JSON))
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/persist")
def persistWorkflow(workflow: Workflow, @Auth sessionUser: SessionUser): Workflow = {
val user = sessionUser.getUser
Expand Down Expand Up @@ -349,6 +379,7 @@ class WorkflowResource extends LazyLogging {
*/
@POST
@Consumes(Array(MediaType.APPLICATION_JSON))
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/duplicate")
def duplicateWorkflow(
workflowIDs: WorkflowIDs,
Expand Down Expand Up @@ -414,7 +445,6 @@ class WorkflowResource extends LazyLogging {

@POST
@Consumes(Array(MediaType.APPLICATION_JSON))
@Produces(Array(MediaType.APPLICATION_JSON))
@Path("/clone/{wid}")
def cloneWorkflow(@PathParam("wid") wid: UInteger, @Auth sessionUser: SessionUser): UInteger = {
val workflow: Workflow = workflowDao.fetchOneByWid(wid)
Expand Down Expand Up @@ -442,6 +472,7 @@ class WorkflowResource extends LazyLogging {
@POST
@Consumes(Array(MediaType.APPLICATION_JSON))
@Produces(Array(MediaType.APPLICATION_JSON))
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/create")
def createWorkflow(workflow: Workflow, @Auth sessionUser: SessionUser): DashboardWorkflow = {
val user = sessionUser.getUser
Expand Down Expand Up @@ -469,6 +500,7 @@ class WorkflowResource extends LazyLogging {
* @return Response, deleted - 200, not exists - 400
*/
@POST
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/delete")
def deleteWorkflow(workflowIDs: WorkflowIDs, @Auth sessionUser: SessionUser): Unit = {
val user = sessionUser.getUser
Expand Down Expand Up @@ -497,6 +529,7 @@ class WorkflowResource extends LazyLogging {
@POST
@Consumes(Array(MediaType.APPLICATION_JSON))
@Produces(Array(MediaType.APPLICATION_JSON))
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/update/name")
def updateWorkflowName(
workflow: Workflow,
Expand All @@ -519,6 +552,7 @@ class WorkflowResource extends LazyLogging {
@POST
@Consumes(Array(MediaType.APPLICATION_JSON))
@Produces(Array(MediaType.APPLICATION_JSON))
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/update/description")
def updateWorkflowDescription(
workflow: Workflow,
Expand All @@ -540,6 +574,7 @@ class WorkflowResource extends LazyLogging {
}

@GET
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/{wid}/environment")
def retrieveWorkflowEnvironment(
@PathParam("wid") wid: UInteger,
Expand Down Expand Up @@ -577,6 +612,7 @@ class WorkflowResource extends LazyLogging {
}

@GET
@RolesAllowed(Array("REGULAR", "ADMIN"))
@Path("/type/{wid}")
def getWorkflowType(@PathParam("wid") wid: UInteger): String = {
val workflow: Workflow = workflowDao.fetchOneByWid(wid)
Expand Down
4 changes: 4 additions & 0 deletions core/amber/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const WORKFLOW_UPDATENAME_URL = WORKFLOW_BASE_URL + "/update/name";
export const WORKFLOW_UPDATEDESCRIPTION_URL = WORKFLOW_BASE_URL + "/update/description";
export const WORKFLOW_OWNER_URL = WORKFLOW_BASE_URL + "/user-workflow-owners";
export const WORKFLOW_ID_URL = WORKFLOW_BASE_URL + "/user-workflow-ids";
export const WORKFLOW_PUBLIC_URL = WORKFLOW_BASE_URL + "/public"

export const DEFAULT_WORKFLOW_NAME = "Untitled workflow";
export const WORKFLOW_ENVIRONMENT = "environment";
Expand Down Expand Up @@ -97,6 +98,13 @@ export class WorkflowPersistService {
);
}

public retrievePublicWorkflow(wid: number): Observable<Workflow> {
return this.http.get<Workflow>(`${AppSettings.getApiEndpoint()}/${WORKFLOW_PUBLIC_URL}/${wid}`).pipe(
filter((workflow: Workflow) => workflow != null),
map(WorkflowUtilService.parseWorkflowInfo)
);
}

private makeRequestAndFormatWorkflowResponse(url: string): Observable<DashboardWorkflow[]> {
return this.http.get<DashboardWorkflow[]>(url).pipe(
map((dashboardWorkflowEntries: DashboardWorkflow[]) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class ShareAccessComponent implements OnInit {
accessLevel: ["READ"],
});
this.currentEmail = this.userService.getCurrentUser()?.email;

}

ngOnInit(): void {
Expand Down Expand Up @@ -89,12 +89,12 @@ export class ShareAccessComponent implements OnInit {
this.gmailService.sendEmail(
"Texera: " + this.owner + " shared a " + this.type + " with you",
this.owner +
" shared a " +
this.type +
" with you, access the workflow at " +
location.origin +
"/workflow/" +
this.id,
" shared a " +
this.type +
" with you, access the workflow at " +
location.origin +
"/workflow/" +
this.id,
this.validateForm.value.email
);
},
Expand Down Expand Up @@ -138,7 +138,7 @@ export class ShareAccessComponent implements OnInit {
]
});
}

}
verifyUnpublish(): void {
if (this.isPublic) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ <h2>Created By</h2>
<p *ngIf="ownerUser">{{ ownerUser.name }}</p>
</div>
</div>
<h2>preview</h2>
<div class="preview-containers">
<texera-workflow-editor></texera-workflow-editor>
<texera-mini-map></texera-mini-map>
</div>
<ng-template #codeEditor></ng-template>
<div class="workflow-steps">
<h2>Steps</h2>
<div
Expand All @@ -39,3 +45,6 @@ <h3>{{ step.name }}</h3>
</div>
</div>
</div>



Loading