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

feat: add description to drip lists (closes #642) #643

Merged
merged 9 commits into from
Sep 6, 2023
561 changes: 353 additions & 208 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
"svelte": "^3.58.0",
"svelte-check": "^3.2.0",
"svelte-preprocess": "^5.0.3",
"tailwindcss": "^3.1.8",
"tslib": "^2.3.1",
"tailwindcss": "^3.3.3",
"typescript": "^4.9.0",
"vite": "^4.1.5",
"vite-plugin-node-polyfills": "^0.9.0",
Expand Down
22 changes: 20 additions & 2 deletions src/e2e-tests/top-up-create-stream.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,11 +457,15 @@ describe('app', async () => {
});

it('renames the drip list', async () => {
const titleField = page.locator('label:has-text("List Title*")');
const titleField = page.locator('label:has-text("Title*")');
await titleField.clear();
await titleField.fill('This is a Test Drip List');
});

it('gives a description', async () => {
await page.locator('label:has-text("Description")').fill('This is my list description.');
});

it('advances the flow', async () => {
await page.locator('button', { hasText: 'Continue' }).click();
});
Expand Down Expand Up @@ -493,6 +497,7 @@ describe('app', async () => {
it('navigates to the Drip List screen', async () => {
await page.locator('button', { hasText: 'View your Drip List' }).click();
await expect(page.locator('text=This is a Test Drip List')).toHaveCount(1);
await expect(page.locator('text=This is my list description.')).toHaveCount(1);
});

it('opens the drip list editor', async () => {
Expand All @@ -518,6 +523,18 @@ describe('app', async () => {
await page.locator('button', { hasText: 'Split evenly' }).click();
});

it('edits the title', async () => {
const titleField = page.locator('label:has-text("Title*")');
await titleField.clear();
await titleField.fill('This is an EDITED title');
});

it('edits the description', async () => {
const titleField = page.locator('label:has-text("Description")');
await titleField.clear();
await titleField.fill('This is an EDITED description.');
});

it('advances the flow', async () => {
await page.locator('button', { hasText: 'Confirm changes in wallet' }).click();
await page.locator('button', { hasText: 'Got it' }).click();
Expand All @@ -528,7 +545,8 @@ describe('app', async () => {

await page.reload();

await expect(page.locator('text=This is a Test Drip List')).toHaveCount(1);
await expect(page.locator('text=This is an EDITED title')).toHaveCount(1);
await expect(page.locator('text=This is an EDITED description.')).toHaveCount(1);
await expect(page.locator('text=0x43')).toHaveCount(0);
});

Expand Down
59 changes: 32 additions & 27 deletions src/lib/components/drip-list-card/drip-list-card.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import type { Stream } from '$lib/stores/streams/types';
import { fade } from 'svelte/transition';
import { browser } from '$app/environment';
import TextExpandable from '../text-expandable.svelte/text-expandable.svelte';

export let dripList: DripList;
export let representationalSplits: RepresentationalSplits;
Expand All @@ -45,7 +46,12 @@
modal.show(
Stepper,
undefined,
editDripListSteps(dripList.account.accountId, dripList.name, representationalSplits),
editDripListSteps(
dripList.account.accountId,
dripList.name,
dripList.description,
representationalSplits,
),
);
}

Expand Down Expand Up @@ -111,16 +117,31 @@
$: dripListUrl = `/app/drip-lists/${dripList.account.accountId}`;
</script>

<div class="card">
<div class="header">
<a href={dripListUrl}><h1>{dripList.name}</h1></a>
<div class="actions">
<ShareButton url="https://drips.network/app/drip-lists/{dripList.account.accountId}" />
{#if isOwnList}
<Button on:click={triggerEditModal} icon={Pen}>Edit list</Button>
{/if}
<section class="card">
<header class="px-6 pt-6 flex flex-col gap-4">
<div class="flex flex-wrap justify-between">
<h1 class="flex-1 min-w-0 truncate">
<a
href={dripListUrl}
class="focus-visible:outline-none focus-visible:bg-primary-level-1 rounded"
>
{dripList.name}
</a>
</h1>
<div class="flex items-center gap-4">
<ShareButton url="https://drips.network/app/drip-lists/{dripList.account.accountId}" />
{#if isOwnList}
<Button on:click={triggerEditModal} icon={Pen}>Edit list</Button>
{/if}
</div>
</div>
</div>
{#if (dripList.description ?? '').length > 0}
<TextExpandable>
{dripList.description}
</TextExpandable>
{/if}
</header>

<div class="list">
<div class="totals">
<div class="drip-icon">
Expand Down Expand Up @@ -150,7 +171,7 @@
</div>
<div class="splits-component"><Splits list={representationalSplits} /></div>
</div>
</div>
</section>

<style>
.card {
Expand All @@ -161,22 +182,6 @@
gap: 2rem;
}

.card > .header {
padding: 1.5rem 1.5rem 0 1.5rem;
display: flex;
justify-content: space-between;
}

.card > .header h1 {
white-space: nowrap;
}

.card > .header > .actions {
display: flex;
align-items: center;
gap: 1rem;
}

.totals {
display: flex;
align-items: center;
Expand Down
72 changes: 72 additions & 0 deletions src/lib/components/drip-list-editor/drip-list-editor.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<script lang="ts" context="module">
export interface DripListConfig {
items: Items;
percentages: Percentages;
title: string;
description: string | undefined;
}
</script>

<script lang="ts">
import type {
Items,
Percentages,
} from '$lib/components/drip-list-members-editor/drip-list-members-editor.svelte';
import ListEditor from '$lib/components/drip-list-members-editor/drip-list-members-editor.svelte';
import FormField from '../form-field/form-field.svelte';
import TextInput from '../text-input/text-input.svelte';
import TextArea from '../text-area/text-area.svelte';
import type { TextInputValidationState } from 'radicle-design-system/TextInput';

export let dripList: DripListConfig = {
title: 'My Drip List',
percentages: {},
items: {},
description: undefined,
};
export let showListFirst = false;
export let projectUrlToAdd: string | undefined = undefined;

// validation
let listValid = false;
$: titleValid = dripList.title.length > 0;
$: descriptionValid = textAreaValidationState.type === 'valid';

export let isValid = false;
$: isValid = listValid && titleValid && descriptionValid;

let textAreaValidationState: TextInputValidationState;
$: textAreaValidationState = !dripList.description
? { type: 'valid' }
: dripList.description.length >= 1000
? { type: 'invalid', message: `Cannot exceed ${Number(1000).toLocaleString()} characters.` }
: /<[^>]+>/gi.test(dripList.description)
? { type: 'invalid', message: 'HTML currently not allowed.' }
: { type: 'valid' };
</script>

<section class="flex flex-col gap-8">
<FormField title="Title*">
<TextInput bind:value={dripList.title} />
</FormField>

<FormField title="Description">
<TextArea
bind:value={dripList.description}
resizable={true}
validationState={textAreaValidationState}
/>
</FormField>

<div class:order-first={showListFirst}>
<FormField title="Members*">
<!-- TODO: This crashes when entering some non-valid github url -->
Copy link
Contributor

Choose a reason for hiding this comment

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

is that still a thing? 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

what is a non-valid github url?

<ListEditor
bind:percentages={dripList.percentages}
bind:items={dripList.items}
bind:valid={listValid}
addOnMount={projectUrlToAdd}
/>
</FormField>
</div>
</section>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ListItem } from '../list-editor.svelte';
import type { ListItem } from '../drip-list-members-editor.svelte';

const dripListItem = (listName: string, listId: string, owner: string): ListItem => ({
type: 'drip-list',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ListItem } from '../list-editor.svelte';
import type { ListItem } from '../drip-list-members-editor.svelte';

const ethAddressItem: (address: string) => ListItem = (address: string) => ({
type: 'address',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GitProject } from '$lib/utils/metadata/types';
import type { ListItem } from '../list-editor.svelte';
import type { ListItem } from '../drip-list-members-editor.svelte';

const projectItem: (project: GitProject) => ListItem = (project: GitProject) => ({
type: 'project',
Expand Down
5 changes: 4 additions & 1 deletion src/lib/components/splits/splits.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<script lang="ts" context="module">
import type { GitProject } from '$lib/utils/metadata/types';
import type { Items, Percentages } from '$lib/components/list-editor/list-editor.svelte';
import type {
Items,
Percentages,
} from '$lib/components/drip-list-members-editor/drip-list-members-editor.svelte';
import mapFilterUndefined from '$lib/utils/map-filter-undefined';

export interface ProjectSplit {
Expand Down
Loading
Loading