Skip to content

Commit

Permalink
refactor: welcome redirect flow (#5941)
Browse files Browse the repository at this point in the history
* simplify welcome redirect flow

* type fix

* workflow test fix

* img reference fixes and svelte-check tweaks

* left incorrect script

* update whitelist error
  • Loading branch information
briangregoryholmes authored and ericpgreen2 committed Oct 21, 2024
1 parent e19f8d1 commit 2f9f350
Show file tree
Hide file tree
Showing 15 changed files with 188 additions and 152 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/web-test-code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ jobs:
if: steps.filter.outputs.local == 'true'
run: |-
npx eslint web-local --quiet
npx svelte-check --workspace web-local --no-tsconfig
npm run check -w web-local
- name: lint and type checks for web admin
if: steps.filter.outputs.admin == 'true'
run: |-
npx eslint web-admin --quiet
npx svelte-check --workspace web-admin --no-tsconfig
- name: lint and type checks for web auth
- name: lint and type checks for web auth
if: steps.filter.outputs.auth == 'true'
run: |-
npx eslint web-auth --quiet
Expand Down
1 change: 1 addition & 0 deletions scripts/tsc-with-whitelist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ web-auth/vite.config.ts: error TS2322
web-local/vite.config.ts: error TS2345
web-common/src/features/dashboards/url-state/filters/expression.cjs: error TS1286
web-local/src/routes//dashboard/[name]/+page.ts: error TS2307
web-local/vite.config.ts: error TS2322
"

# Run TypeScript compiler and find all distinct error per file
Expand Down
6 changes: 1 addition & 5 deletions web-admin/src/features/projects/ProjectCard.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script lang="ts">
import { goto } from "$app/navigation";
import Card from "@rilldata/web-common/components/card/Card.svelte";
import Globe from "@rilldata/web-common/components/icons/Globe.svelte";
import Lock from "@rilldata/web-common/components/icons/Lock.svelte";
Expand All @@ -21,10 +20,7 @@
</script>

{#if $proj.data}
<Card
on:click={() => goto(`/${organization}/${project}`)}
bgClasses="bg-gradient-to-b from-white to-slate-50"
>
<Card href="/{organization}/{project}">
<!-- Project name -->
<h2
class="text-gray-700 font-medium text-lg text-center px-4 {doesProjectNameIncludeUnderscores(
Expand Down
52 changes: 40 additions & 12 deletions web-common/src/components/card/Card.svelte
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
<script lang="ts">
export let bgClasses = "";
import LoadingCircleOutline from "../icons/LoadingCircleOutline.svelte";
export let disabled = false;
export let isLoading = false;
export let redirect = false;
export let href = "/";
export let imageUrl = "";
</script>

<div
class="w-[240px] h-[240px] rounded-md
flex flex-col items-center justify-center gap-y-2
relative {bgClasses}
transition duration-300 ease-out custom-shadow custom-shadow-hover cursor-pointer"
<a
href={href + (redirect ? "?redirect=true" : "")}
class:gradient={!imageUrl}
on:click
on:keydown={(e) => e.key === "Enter" && e.currentTarget.click()}
role="button"
tabindex="0"
aria-disabled={disabled && !isLoading}
style:background-image={imageUrl ? `url('${imageUrl}')` : ""}
>
{#if isLoading}
<div
class="absolute z-10 inset-0 flex items-center justify-center backdrop-blur-sm"
>
<LoadingCircleOutline size="48px" color="var(--color-primary-600)" />
</div>
{/if}
<slot />
</div>
</a>

<style lang="postcss">
a {
@apply bg-no-repeat bg-center bg-cover;
@apply relative;
@apply size-60 rounded-md;
@apply flex flex-col items-center justify-center gap-y-2;
@apply transition duration-300 ease-out;
@apply cursor-pointer overflow-hidden;
<style>
.custom-shadow {
box-shadow:
0px 2px 3px rgba(15, 23, 42, 0.06),
0px 1px 3px rgba(15, 23, 42, 0.08),
0px 0px 0px 1px rgba(15, 23, 42, 0.12);
}
.custom-shadow-hover:hover {
.gradient {
@apply bg-gradient-to-b from-white to-slate-50;
}
a[aria-disabled="true"] {
cursor: not-allowed;
opacity: 0.4;
pointer-events: none;
}
a:hover {
box-shadow:
0px 2px 3px rgba(99, 102, 241, 0.2),
0px 1px 3px rgba(15, 23, 42, 0.08),
Expand Down
47 changes: 0 additions & 47 deletions web-common/src/features/welcome/EmptyProject.svelte

This file was deleted.

78 changes: 51 additions & 27 deletions web-common/src/features/welcome/ProjectCards.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script lang="ts">
import { goto } from "$app/navigation";
import Subheading from "@rilldata/web-common/components/typography/Subheading.svelte";
import Card from "../../components/card/Card.svelte";
import CardDescription from "../../components/card/CardDescription.svelte";
Expand All @@ -12,65 +11,90 @@
import { MetricsEventSpace } from "../../metrics/service/MetricsTypes";
import { createRuntimeServiceUnpackExample } from "../../runtime-client";
import { runtime } from "../../runtime-client/runtime-store";
import EmptyProject from "./EmptyProject.svelte";
import { EMPTY_PROJECT_TITLE } from "./constants";
import AddCircleOutline from "@rilldata/web-common/components/icons/AddCircleOutline.svelte";
import { createRuntimeServiceUnpackEmpty } from "../../runtime-client";
const unpackExampleProject = createRuntimeServiceUnpackExample();
const unpackEmptyProject = createRuntimeServiceUnpackEmpty();
const EXAMPLES = [
{
name: "rill-cost-monitoring",
title: "Cost Monitoring",
description: "Monitoring cloud infrastructure",
image:
"bg-[url('$img/welcome-bg-cost-monitoring.png')] bg-no-repeat bg-cover",
firstPage: "/files/dashboards/customer_margin_dash.yaml",
image: "/img/welcome-bg-cost-monitoring.png",
},
{
name: "rill-openrtb-prog-ads",
title: "OpenRTB Programmatic Ads",
description: "Real-time Bidding (RTB) advertising",
image: "bg-[url('$img/welcome-bg-openrtb.png')] bg-no-repeat bg-cover",
firstPage: "/files/dashboards/auction.yaml",
image: "/img/welcome-bg-openrtb.png",
},
{
name: "rill-github-analytics",
title: "Github Analytics",
description: "A Git project's commit activity",
image:
"bg-[url('$img/welcome-bg-github-analytics.png')] bg-no-repeat bg-cover",
firstPage: "/files/dashboards/duckdb_commits.yaml",
image: "/img/welcome-bg-github-analytics.png",
},
];
const unpackExampleProject = createRuntimeServiceUnpackExample();
let selectedProjectName: string | null = null;
$: ({ instanceId } = $runtime);
$: ({ mutateAsync: unpackExample } = $unpackExampleProject);
$: ({ mutateAsync: unpackEmpty } = $unpackEmptyProject);
async function unpackProject(example?: (typeof EXAMPLES)[number]) {
selectedProjectName = example ? example.name : EMPTY_PROJECT_TITLE;
async function startWithExampleProject(example: (typeof EXAMPLES)[number]) {
await behaviourEvent?.fireSplashEvent(
BehaviourEventAction.ExampleAdd,
example
? BehaviourEventAction.ExampleAdd
: BehaviourEventAction.ProjectEmpty,
BehaviourEventMedium.Card,
MetricsEventSpace.Workspace,
example.name,
example?.name,
);
const firstPage = example.firstPage;
await $unpackExampleProject.mutateAsync({
instanceId: $runtime.instanceId,
data: {
name: example.name,
force: true,
},
});
await goto(firstPage);
const mutationFunction = example ? unpackExample : unpackEmpty;
const key = example ? "name" : "title";
try {
await mutationFunction({
instanceId,
data: {
[key]: selectedProjectName,
force: true,
},
});
} catch {
selectedProjectName = null;
}
}
</script>

<section class="flex flex-col items-center gap-y-5">
<Subheading>Or jump right into a project.</Subheading>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
<EmptyProject />
{#each EXAMPLES as example}
<Card
disabled={!!selectedProjectName}
isLoading={selectedProjectName === EMPTY_PROJECT_TITLE}
on:click={() => unpackProject()}
>
<AddCircleOutline size="2em" className="text-slate-600" />
<CardTitle position="middle">Start with an empty project</CardTitle>
</Card>

{#each EXAMPLES as example (example.name)}
<Card
bgClasses={example.image}
redirect
imageUrl={example.image}
disabled={!!selectedProjectName}
isLoading={selectedProjectName === example.name}
on:click={async () => {
await startWithExampleProject(example);
await unpackProject(example);
}}
>
<CardTitle>{example.title}</CardTitle>
Expand Down
13 changes: 6 additions & 7 deletions web-common/src/features/welcome/is-project-initialized.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ export async function isProjectInitialized(instanceId: string) {
}
}

export async function handleUninitializedProject(
instanceId: string,
): Promise<boolean> {
export async function handleUninitializedProject(instanceId: string) {
// If the project is not initialized, determine what page to route to dependent on the OLAP connector
const instance = await runtimeServiceGetInstance(instanceId, {
sensitive: true,
Expand All @@ -38,14 +36,15 @@ export async function handleUninitializedProject(
}

// DuckDB-backed projects should head to the Welcome page for user-guided initialization
if (olapConnector === "duckdb") {
return true;
} else {
if (olapConnector !== "duckdb") {
// Clickhouse and Druid-backed projects should be initialized immediately
await runtimeServiceUnpackEmpty(instanceId, {
title: EMPTY_PROJECT_TITLE,
force: true,
});
return false;

return true;
}

return false;
}
4 changes: 2 additions & 2 deletions web-local/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"dev": "vite dev",
"build": "vite build",
"install-and-build": "npm install && npm run build",
"check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"check": "svelte-kit sync && svelte-check --no-tsconfig",
"check:watch": "svelte-check --no-ts-config --watch",
"lint": "eslint --ignore-path .gitignore .",
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. .",
"test": "npx playwright test",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<script lang="ts">
import Navigation from "@rilldata/web-common/layout/navigation/Navigation.svelte";
import type { LayoutData } from "../$types";
export let data: LayoutData;
</script>

<div class="flex size-full overflow-hidden">
<Navigation />
{#if data.initialized}
<Navigation />
{/if}

<section class="size-full overflow-hidden">
<slot />
Expand Down
36 changes: 35 additions & 1 deletion web-local/src/routes/(application)/(workspace)/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
<script lang="ts">
import OnboardingWorkspace from "@rilldata/web-common/features/onboarding/OnboardingWorkspace.svelte";
import ProjectCards from "@rilldata/web-common/features/welcome/ProjectCards.svelte";
import TitleContent from "@rilldata/web-common/features/welcome/TitleContent.svelte";
import UserTestCta from "@rilldata/web-common/features/welcome/UserTestCTA.svelte";
import { fly } from "svelte/transition";
import type { LayoutData } from "../$types";
export let data: LayoutData;
</script>

<svelte:head>
<title>Rill Developer</title>
</svelte:head>

<OnboardingWorkspace />
{#if data.initialized}
<OnboardingWorkspace />
{:else}
<div class="scroll" in:fly={{ duration: 1600, delay: 400, y: 8 }}>
<div class="wrapper column p-10 2xl:py-16">
<TitleContent />
<div class="column" in:fly={{ duration: 1600, delay: 1200, y: 4 }}>
<ProjectCards />
<UserTestCta />
</div>
</div>
</div>
{/if}

<style lang="postcss">
.scroll {
@apply size-full overflow-x-hidden overflow-y-auto;
}
.wrapper {
@apply w-full h-fit min-h-screen bg-no-repeat bg-cover;
background-image: url("/img/welcome-bg-art.png");
}
.column {
@apply flex flex-col items-center gap-y-6;
}
</style>
Loading

2 comments on commit 2f9f350

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Published on https://ui.rilldata.com as production
🚀 Deployed on https://6715e2d3e4d93eddd99d0b7f--rill-ui.netlify.app

Please sign in to comment.