diff --git a/web-admin/src/features/branches/deployment-utils.ts b/web-admin/src/features/branches/deployment-utils.ts index d9cd7016ca9..226f263fd5f 100644 --- a/web-admin/src/features/branches/deployment-utils.ts +++ b/web-admin/src/features/branches/deployment-utils.ts @@ -77,7 +77,7 @@ export async function maybeRedirectToEditableDeployment( const isActiveEditableDeployment = editableDeployment && isActiveDeployment(editableDeployment); // Editable deployment is inactive as well, project is probably hibernating, skip redirect. - if (!isActiveEditableDeployment) return; + if (!isActiveEditableDeployment && prodDeployment) return; // If user is already in a specific deployment do not redirect. // This method is meant as a convenience for direct links to unpublished project. diff --git a/web-admin/src/features/projects/ProjectCard.svelte b/web-admin/src/features/projects/ProjectCard.svelte index 0122d8102ac..be0df9e94a8 100644 --- a/web-admin/src/features/projects/ProjectCard.svelte +++ b/web-admin/src/features/projects/ProjectCard.svelte @@ -7,12 +7,23 @@ import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte"; import { createAdminServiceGetProject } from "../../client"; import ProjectAccessControls from "./ProjectAccessControls.svelte"; + import ProjectCardActions from "@rilldata/web-admin/features/projects/ProjectCardActions.svelte"; + import GuardedDeleteProjectConfirmation from "@rilldata/web-admin/features/projects/settings/GuardedDeleteProjectConfirmation.svelte"; + import ProjectRenameDialog from "@rilldata/web-admin/features/projects/settings/ProjectRenameDialog.svelte"; + import EditBranchDialog from "@rilldata/web-admin/features/edit-session/EditBranchDialog.svelte"; - export let organization: string; - export let project: string; + let { organization, project }: { organization: string; project: string } = + $props(); // Check whether project is public or private - $: proj = createAdminServiceGetProject(organization, project); + let proj = $derived(createAdminServiceGetProject(organization, project)); + let primaryBranch = $derived($proj.data?.project?.primaryBranch); + + let hovering = $state(false); + let actionsOpen = $state(false); + let editProjectOpen = $state(false); + let renameProjectOpen = $state(false); + let deleteProjectOpen = $state(false); function doesProjectNameIncludeUnderscores(project: string) { return project.includes("_"); @@ -20,7 +31,7 @@ {#if $proj.data} - +

+ (editProjectOpen = true)} + onRename={() => (renameProjectOpen = true)} + onDelete={() => (deleteProjectOpen = true)} + /> + + {/if} @@ -60,3 +84,19 @@ {/if} + + + + + + diff --git a/web-admin/src/features/projects/ProjectCardActions.svelte b/web-admin/src/features/projects/ProjectCardActions.svelte new file mode 100644 index 00000000000..31b6951b0f9 --- /dev/null +++ b/web-admin/src/features/projects/ProjectCardActions.svelte @@ -0,0 +1,47 @@ + + + + + + + + + Edit + + + Rename + + + Share + + + Delete + + + diff --git a/web-admin/src/features/projects/ProjectCards.svelte b/web-admin/src/features/projects/ProjectCards.svelte index 33a643e77bc..a2c374fa1c0 100644 --- a/web-admin/src/features/projects/ProjectCards.svelte +++ b/web-admin/src/features/projects/ProjectCards.svelte @@ -5,9 +5,19 @@ import { listProjectsForOrgQueryOptions } from "@rilldata/web-admin/features/projects/list-projects-query-options"; import { createQuery } from "@tanstack/svelte-query"; - export let organization: string; + let { + organization, + createProjectsPermission, + }: { organization: string; createProjectsPermission: boolean } = $props(); - $: projs = createQuery(listProjectsForOrgQueryOptions(organization)); + let projectsQuery = $derived( + createQuery(listProjectsForOrgQueryOptions(organization)), + ); + let projects = $derived($projectsQuery.data?.projects ?? []); + + let showNewProject = $derived( + projectWelcomeEnabled && createProjectsPermission, + );
@@ -15,24 +25,22 @@ class="flex flex-row items-center text-fg-secondary text-base font-normal leading-normal" > Check out your projects below. - {#if projectWelcomeEnabled} - {/if} - {#if $projs.data && $projs.data.projects?.length === 0} -

- This organization has no projects yet. -

- {:else if $projs.data && $projs.data.projects?.length > 0} -
    - {#each $projs.data.projects as proj} -
  1. - -
  2. - {/each} -
- {/if} +
    + {#each projects as proj (proj.name)} +
  1. + +
  2. + {:else} +

    + This organization has no projects yet. +

    + {/each} +
diff --git a/web-admin/src/features/projects/settings/DeleteProject.svelte b/web-admin/src/features/projects/settings/DeleteProject.svelte index 5550a825066..c15689b8fbb 100644 --- a/web-admin/src/features/projects/settings/DeleteProject.svelte +++ b/web-admin/src/features/projects/settings/DeleteProject.svelte @@ -1,44 +1,9 @@ @@ -46,17 +11,6 @@ platform. This action is not reversible — please continue with caution. {#snippet action()} - - - + {/snippet} diff --git a/web-admin/src/features/projects/settings/GuardedDeleteProjectConfirmation.svelte b/web-admin/src/features/projects/settings/GuardedDeleteProjectConfirmation.svelte new file mode 100644 index 00000000000..d0f9434edfb --- /dev/null +++ b/web-admin/src/features/projects/settings/GuardedDeleteProjectConfirmation.svelte @@ -0,0 +1,68 @@ + + + + {#if button} + + {:else} + + {/if} + diff --git a/web-admin/src/features/projects/settings/ProjectNameSettings.svelte b/web-admin/src/features/projects/settings/ProjectNameSettings.svelte index 915c639fbe8..8db98c0d1ee 100644 --- a/web-admin/src/features/projects/settings/ProjectNameSettings.svelte +++ b/web-admin/src/features/projects/settings/ProjectNameSettings.svelte @@ -1,173 +1,37 @@ -
{ - e.preventDefault(); - submit(e); - }} - class="update-project-form" - use:enhance - > - - -
- {#if error?.message} -
- {error.message} -
- {/if} + {#snippet action()} {/snippet}
- - diff --git a/web-admin/src/features/projects/settings/ProjectRenameDialog.svelte b/web-admin/src/features/projects/settings/ProjectRenameDialog.svelte new file mode 100644 index 00000000000..029e2481033 --- /dev/null +++ b/web-admin/src/features/projects/settings/ProjectRenameDialog.svelte @@ -0,0 +1,37 @@ + + + + + + Rename Project + + + Cancel + + + + diff --git a/web-admin/src/features/projects/settings/ProjectRenameForm.svelte b/web-admin/src/features/projects/settings/ProjectRenameForm.svelte new file mode 100644 index 00000000000..af17d12d41d --- /dev/null +++ b/web-admin/src/features/projects/settings/ProjectRenameForm.svelte @@ -0,0 +1,165 @@ + + + + +
{ + e.preventDefault(); + submit(e); + }} + class="update-project-form" + use:enhance +> + + + {#if error?.message} +
+ {error.message} +
+ {/if} +
+ + diff --git a/web-admin/src/routes/[organization]/+page.svelte b/web-admin/src/routes/[organization]/+page.svelte index d7756a6b97f..5038ecf169c 100644 --- a/web-admin/src/routes/[organization]/+page.svelte +++ b/web-admin/src/routes/[organization]/+page.svelte @@ -6,9 +6,9 @@ import { createQuery } from "@tanstack/svelte-query"; import OrganizationHero from "../../features/organizations/OrganizationHero.svelte"; import ProjectCards from "../../features/projects/ProjectCards.svelte"; - import { Button } from "@rilldata/web-common/components/button"; - import { projectWelcomeEnabled } from "@rilldata/web-admin/features/welcome/project/welcome-status.ts"; + export let data; + $: ({ organizationPermissions } = data); $: ({ params: { organization: orgName }, } = $page); @@ -27,28 +27,9 @@ - {#if $org.data && $org.data.organization && $projs.data} - {#if $projs.data.projects?.length === 0} - - - This organization has no projects yet. See docs - - {#if projectWelcomeEnabled} -
- -
- {/if} - {:else} -
- - -
- {/if} - {/if} + +
diff --git a/web-common/src/components/card/Card.svelte b/web-common/src/components/card/Card.svelte index 40f6b0211e1..2a545559d0a 100644 --- a/web-common/src/components/card/Card.svelte +++ b/web-common/src/components/card/Card.svelte @@ -8,6 +8,7 @@ export let imageUrl = ""; export let onclick: ((e: MouseEvent) => void | Promise) | undefined = undefined; + export let hovering = false; e.key === "Enter" && e.currentTarget.click()} + onmouseenter={() => (hovering = true)} + onmouseleave={() => (hovering = false)} aria-disabled={disabled} class:loading={isLoading} style:background-image={imageUrl ? `url('${imageUrl}')` : ""} diff --git a/web-common/src/components/icons/FeatherEditIcon.svelte b/web-common/src/components/icons/FeatherEditIcon.svelte new file mode 100644 index 00000000000..1ac1550e61b --- /dev/null +++ b/web-common/src/components/icons/FeatherEditIcon.svelte @@ -0,0 +1,30 @@ + + + + + + + + + + + + + diff --git a/web-common/src/components/icons/PencilIcon.svelte b/web-common/src/components/icons/PencilIcon.svelte new file mode 100644 index 00000000000..2c9d41079ef --- /dev/null +++ b/web-common/src/components/icons/PencilIcon.svelte @@ -0,0 +1,23 @@ + + + + + +