Skip to content

Commit

Permalink
add trash bin function
Browse files Browse the repository at this point in the history
  • Loading branch information
tomokazu tantaka committed Oct 2, 2024
1 parent 16722ac commit d05bf05
Show file tree
Hide file tree
Showing 28 changed files with 1,085 additions and 19 deletions.
133 changes: 133 additions & 0 deletions server/e2e/gql_project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,3 +452,136 @@ func TestSortByUpdatedAt(t *testing.T) {
edges.Element(1).Object().Value("node").Object().Value("name").Equal("project3-test")
edges.Element(2).Object().Value("node").Object().Value("name").Equal("project1-test")
}

// go test -v -run TestArchiveProject ./e2e/...

func TestArchiveProject(t *testing.T) {

e := StartServer(t, &config.Config{
Origins: []string{"https://example.com"},
AuthSrv: config.AuthSrvConfig{
Disabled: true,
},
}, true, baseSeeder)

createProject(e, "project1-test")
project2ID := createProject(e, "project2-test")
createProject(e, "project3-test")

// Archive 'project2'
requestBody := GraphQLRequest{
OperationName: "ArchiveProject",
Query: `mutation ArchiveProject($projectId: ID!, $archived: Boolean!) {
updateProject(input: {projectId: $projectId, archived: $archived}) {
project {
id
isArchived
__typename
}
__typename
}
}`,
Variables: map[string]any{
"projectId": project2ID,
"archived": true,
},
}
e.POST("/api/graphql").
WithHeader("Origin", "https://example.com").
WithHeader("X-Reearth-Debug-User", uID.String()).
WithHeader("Content-Type", "application/json").
WithJSON(requestBody).
Expect().
Status(http.StatusOK).
JSON()

requestBody = GraphQLRequest{
OperationName: "GetProjects",
Query: `query GetProjects($teamId: ID!, $includeArchived: Boolean, $pagination: Pagination, $keyword: String, $sort: ProjectSort) {
projects(teamId: $teamId, includeArchived: $includeArchived, pagination: $pagination, keyword: $keyword, sort: $sort) {
edges {
node {
id
...ProjectFragment
scene {
id
__typename
}
__typename
}
__typename
}
nodes {
id
...ProjectFragment
scene {
id
__typename
}
__typename
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
__typename
}
totalCount
__typename
}
}
fragment ProjectFragment on Project {
id
name
description
imageUrl
isArchived
isBasicAuthActive
basicAuthUsername
basicAuthPassword
publicTitle
publicDescription
publicImage
alias
enableGa
trackingId
publishmentStatus
updatedAt
createdAt
coreSupport
starred
__typename
}`,
Variables: map[string]any{
"teamId": wID.String(),
"includeArchived": false,
"pagination": map[string]any{
"first": 16,
},
"sort": map[string]string{
"field": "UPDATEDAT",
"direction": "DESC",
},
},
}

edges := e.POST("/api/graphql").
WithHeader("Origin", "https://example.com").
WithHeader("X-Reearth-Debug-User", uID.String()).
WithHeader("Content-Type", "application/json").
WithJSON(requestBody).
Expect().
Status(http.StatusOK).
JSON().
Object().
Value("data").Object().
Value("projects").Object().
Value("edges").Array()

// `project2-test` is archived and will not be retrieved
edges.Length().Equal(3)
edges.Element(0).Object().Value("node").Object().Value("name").Equal("project3-test")
edges.Element(1).Object().Value("node").Object().Value("name").Equal("project1-test")
edges.Element(2).Object().Value("node").Object().Value("name").Equal("p1")
}
2 changes: 1 addition & 1 deletion server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (
github.com/kennygrant/sanitize v1.2.4
github.com/labstack/echo/v4 v4.11.4
github.com/mitchellh/mapstructure v1.5.0
github.com/oklog/ulid v1.3.1
github.com/paulmach/go.geojson v1.4.0
github.com/pkg/errors v0.9.1
github.com/ravilushqa/otelgqlgen v0.15.0
Expand Down Expand Up @@ -116,7 +117,6 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rs/cors v1.10.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions server/internal/adapter/gql/loader_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ func (c *ProjectLoader) Fetch(ctx context.Context, ids []gqlmodel.ID) ([]*gqlmod
return projects, nil
}

func (c *ProjectLoader) FindByWorkspace(ctx context.Context, wsID gqlmodel.ID, keyword *string, sort *project.SortType, pagination *gqlmodel.Pagination) (*gqlmodel.ProjectConnection, error) {
func (c *ProjectLoader) FindByWorkspace(ctx context.Context, wsID gqlmodel.ID, includeArchived *bool, keyword *string, sort *project.SortType, pagination *gqlmodel.Pagination) (*gqlmodel.ProjectConnection, error) {
tid, err := gqlmodel.ToID[accountdomain.Workspace](wsID)
if err != nil {
return nil, err
}

res, pi, err := c.usecase.FindByWorkspace(ctx, tid, keyword, sort, gqlmodel.ToPagination(pagination), getOperator(ctx))
res, pi, err := c.usecase.FindByWorkspace(ctx, tid, includeArchived, keyword, sort, gqlmodel.ToPagination(pagination), getOperator(ctx))
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion server/internal/adapter/gql/resolver_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func (r *queryResolver) Scene(ctx context.Context, projectID gqlmodel.ID) (*gqlm
}

func (r *queryResolver) Projects(ctx context.Context, teamID gqlmodel.ID, includeArchived *bool, pagination *gqlmodel.Pagination, keyword *string, sortType *gqlmodel.ProjectSort) (*gqlmodel.ProjectConnection, error) {
return loaders(ctx).Project.FindByWorkspace(ctx, teamID, keyword, gqlmodel.ProjectSortTypeFrom(sortType), pagination)
return loaders(ctx).Project.FindByWorkspace(ctx, teamID, includeArchived, keyword, gqlmodel.ProjectSortTypeFrom(sortType), pagination)
}

func (r *queryResolver) DatasetSchemas(ctx context.Context, sceneID gqlmodel.ID, first *int, last *int, after *usecasex.Cursor, before *usecasex.Cursor) (*gqlmodel.DatasetSchemaConnection, error) {
Expand Down
2 changes: 1 addition & 1 deletion server/internal/adapter/gql/resolver_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (r *teamResolver) Assets(ctx context.Context, obj *gqlmodel.Team, first *in
}

func (r *teamResolver) Projects(ctx context.Context, obj *gqlmodel.Team, includeArchived *bool, first *int, last *int, after *usecasex.Cursor, before *usecasex.Cursor) (*gqlmodel.ProjectConnection, error) {
return loaders(ctx).Project.FindByWorkspace(ctx, obj.ID, nil, nil, &gqlmodel.Pagination{
return loaders(ctx).Project.FindByWorkspace(ctx, obj.ID, includeArchived, nil, nil, &gqlmodel.Pagination{
First: first,
Last: last,
After: after,
Expand Down
7 changes: 7 additions & 0 deletions server/internal/infrastructure/memory/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ func (r *Project) FindByWorkspace(ctx context.Context, id accountdomain.Workspac
result := []*project.Project{}
for _, d := range r.data {
if d.Workspace() == id && (filter.Keyword == nil || strings.Contains(d.Name(), *filter.Keyword)) {
if filter.IncludeArchived != nil {
if !*filter.IncludeArchived {
if d.IsArchived() {
continue
}
}
}
result = append(result, d)
}
}
Expand Down
6 changes: 6 additions & 0 deletions server/internal/infrastructure/mongo/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ func (r *Project) FindByWorkspace(ctx context.Context, id accountdomain.Workspac
})
}

if uFilter.IncludeArchived != nil {
if !*uFilter.IncludeArchived {
filter = mongox.And(filter, "archived", false)
}
}

return r.paginate(ctx, filter, uFilter.Sort, uFilter.Pagination)
}

Expand Down
9 changes: 5 additions & 4 deletions server/internal/usecase/interactor/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ func (i *Project) Fetch(ctx context.Context, ids []id.ProjectID, _ *usecase.Oper
return i.projectRepo.FindByIDs(ctx, ids)
}

func (i *Project) FindByWorkspace(ctx context.Context, id accountdomain.WorkspaceID, keyword *string, sort *project.SortType, p *usecasex.Pagination, operator *usecase.Operator) ([]*project.Project, *usecasex.PageInfo, error) {
func (i *Project) FindByWorkspace(ctx context.Context, id accountdomain.WorkspaceID, includeArchived *bool, keyword *string, sort *project.SortType, p *usecasex.Pagination, operator *usecase.Operator) ([]*project.Project, *usecasex.PageInfo, error) {
return i.projectRepo.FindByWorkspace(ctx, id, repo.ProjectFilter{
Pagination: p,
Sort: sort,
Keyword: keyword,
IncludeArchived: includeArchived,
Pagination: p,
Sort: sort,
Keyword: keyword,
})
}

Expand Down
2 changes: 1 addition & 1 deletion server/internal/usecase/interfaces/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ var (

type Project interface {
Fetch(context.Context, []id.ProjectID, *usecase.Operator) ([]*project.Project, error)
FindByWorkspace(context.Context, accountdomain.WorkspaceID, *string, *project.SortType, *usecasex.Pagination, *usecase.Operator) ([]*project.Project, *usecasex.PageInfo, error)
FindByWorkspace(context.Context, accountdomain.WorkspaceID, *bool, *string, *project.SortType, *usecasex.Pagination, *usecase.Operator) ([]*project.Project, *usecasex.PageInfo, error)
FindStarredByWorkspace(context.Context, accountdomain.WorkspaceID, *usecase.Operator) ([]*project.Project, error)
Create(context.Context, CreateProjectParam, *usecase.Operator) (*project.Project, error)
Update(context.Context, UpdateProjectParam, *usecase.Operator) (*project.Project, error)
Expand Down
7 changes: 4 additions & 3 deletions server/internal/usecase/repo/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (
)

type ProjectFilter struct {
Sort *project.SortType
Keyword *string
Pagination *usecasex.Pagination
IncludeArchived *bool
Sort *project.SortType
Keyword *string
Pagination *usecasex.Pagination
}

type Project interface {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { Button, PopupMenu, TextInput } from "@reearth/beta/lib/reearth-ui";
import {
Button,
PopupMenu,
Typography,
TextInput,
Modal,
ModalPanel
} from "@reearth/beta/lib/reearth-ui";
import { useT } from "@reearth/services/i18n";
import { styled, useTheme } from "@reearth/services/theme";
import { FC } from "react";

Expand All @@ -10,6 +18,7 @@ const ProjectGridViewItem: FC<ProjectProps> = ({
selectedProjectId,
onProjectOpen,
onProjectSelect,
onArchiveProject,
onProjectUpdate
}) => {
const theme = useTheme();
Expand All @@ -21,18 +30,24 @@ const ProjectGridViewItem: FC<ProjectProps> = ({
isHovered,
isStarred,
hasMapOrStoryPublished,
archiveOpen,
handleProjectNameChange,
handleProjectNameBlur,
handleProjectHover,
handleProjectNameDoubleClick,
handleArchivedModal,
handleProjectArchived,
handleProjectStarClick
} = useHooks({
project,
selectedProjectId,
onProjectUpdate,
onArchiveProject,
onProjectSelect
});

const t = useT();

return (
<Card>
<CardImage
Expand Down Expand Up @@ -81,11 +96,52 @@ const ProjectGridViewItem: FC<ProjectProps> = ({
<Button icon="dotsThreeVertical" iconButton appearance="simple" />
}
/>
<Modal size="small" visible={archiveOpen}>
<ModalPanel
title={t("Remove")}
onCancel={() => handleArchivedModal(false)}
actions={
<>
<Button
key="cancel"
title={t("Cancel")}
appearance="secondary"
onClick={() => handleArchivedModal(false)}
size="normal"
/>
<Button
size="normal"
key="delete"
appearance="dangerous"
title={t("Delete")}
onClick={() => handleProjectArchived(true)}
disabled={!projectName}
/>
</>
}
>
<ModalContentWrapper>
<Typography size="body">
{t(
"This process will remove this project to Recycle bin. If the project was published, this also means websites and domains referencing the project will not be able to access it anymore."
)}
</Typography>
</ModalContentWrapper>
</ModalPanel>
</Modal>
</CardFooter>
</Card>
);
};

const ModalContentWrapper = styled("div")(({ theme }) => ({
display: "flex",
flexDirection: "column",
gap: theme.spacing.large,
padding: theme.spacing.large,
background: theme.bg[1]
}));

export default ProjectGridViewItem;

const Card = styled("div")(() => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const ProjectListViewItem: FC<ProjectProps> = ({
selectedProjectId,
onProjectOpen,
onProjectSelect,
onArchiveProject,
onProjectUpdate
}) => {
const theme = useTheme();
Expand Down Expand Up @@ -47,6 +48,7 @@ const ProjectListViewItem: FC<ProjectProps> = ({
project,
selectedProjectId,
onProjectUpdate,
onArchiveProject,
onProjectSelect
});

Expand Down
Loading

0 comments on commit d05bf05

Please sign in to comment.