diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 62008f5c9..9ec76def9 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -95,5 +95,5 @@ jobs: if: always() with: name: playwright-report - path: playwright-report/ + path: apps/e2e/playwright-report/ retention-days: 7 \ No newline at end of file diff --git a/apps/e2e/playwright.config.ts b/apps/e2e/playwright.config.ts index feb9be176..7f18f4e96 100644 --- a/apps/e2e/playwright.config.ts +++ b/apps/e2e/playwright.config.ts @@ -25,6 +25,9 @@ export default defineConfig({ /* Base URL to use in actions like `await page.goto('/')`. */ baseURL: 'http://localhost:3000', + // take a screenshot when a test fails + screenshot: "on", + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', }, diff --git a/apps/e2e/tests/account/account.spec.ts b/apps/e2e/tests/account/account.spec.ts index 770d531fa..c9654b7f7 100644 --- a/apps/e2e/tests/account/account.spec.ts +++ b/apps/e2e/tests/account/account.spec.ts @@ -55,7 +55,9 @@ test.describe('Account Deletion', () => { await account.setup(); await account.deleteAccount(); - await page.waitForURL('http://localhost:3000'); + await page.waitForURL('http://localhost:3000', { + timeout: 5000, + }); expect(page.url()).toEqual('http://localhost:3000/'); }); diff --git a/apps/e2e/tests/team-accounts/team-accounts.po.ts b/apps/e2e/tests/team-accounts/team-accounts.po.ts index 912f29884..b202650aa 100644 --- a/apps/e2e/tests/team-accounts/team-accounts.po.ts +++ b/apps/e2e/tests/team-accounts/team-accounts.po.ts @@ -38,7 +38,9 @@ export class TeamAccountsPageObject { await this.page.fill('[data-test="create-team-form"] input', teamName); await this.page.click('[data-test="create-team-form"] button:last-child'); - await this.page.waitForURL(`http://localhost:3000/home/${slug}`); + await this.page.waitForURL(`http://localhost:3000/home/${slug}`, { + timeout: 5000, + }); } async updateName(name: string) { @@ -56,7 +58,7 @@ export class TeamAccountsPageObject { } createTeamName() { - const random = (Math.random() * 1000000000).toFixed(0); + const random = (Math.random() * 10).toFixed(0); const teamName = `Team-Name-${random}`; const slug = `team-name-${random}`; diff --git a/apps/e2e/tests/team-accounts/team-accounts.spec.ts b/apps/e2e/tests/team-accounts/team-accounts.spec.ts index c9ba3e7f4..1d75c13d3 100644 --- a/apps/e2e/tests/team-accounts/team-accounts.spec.ts +++ b/apps/e2e/tests/team-accounts/team-accounts.spec.ts @@ -35,7 +35,9 @@ test.describe('Account Deletion', () => { await teamAccounts.deleteAccount(params.teamName); - await page.waitForURL('http://localhost:3000/home'); + await page.waitForURL('http://localhost:3000/home', { + timeout: 5000, + }); expect(page.url()).toEqual('http://localhost:3000/home'); diff --git a/apps/web/public/locales/en/teams.json b/apps/web/public/locales/en/teams.json index 30622aeee..22df75bb3 100644 --- a/apps/web/public/locales/en/teams.json +++ b/apps/web/public/locales/en/teams.json @@ -18,7 +18,7 @@ "billing": { "pageTitle": "Billing" }, - "yourTeams": "Your Teams", + "yourTeams": "Your Teams ({{teamsCount}})", "createTeam": "Create a Team", "personalAccount": "Personal Account", "searchAccount": "Search Account...", diff --git a/apps/web/supabase/migrations/20221215192558_schema.sql b/apps/web/supabase/migrations/20221215192558_schema.sql index 4e3080c34..815b773b9 100644 --- a/apps/web/supabase/migrations/20221215192558_schema.sql +++ b/apps/web/supabase/migrations/20221215192558_schema.sql @@ -16,8 +16,6 @@ create extension if not exists "unaccent"; -- Create a private Makerkit schema create schema if not exists kit; -grant USAGE on schema kit to authenticated, authenticated; - -- We remove all default privileges from public schema on functions to -- prevent public access to them alter default privileges revoke execute on functions from public; @@ -1595,6 +1593,8 @@ grant execute on function kit.slugify(text) to service_role, authenticated; create or replace function kit.set_slug_from_account_name() returns trigger language plpgsql + security definer + set search_path = public as $$ declare sql_string varchar; @@ -1616,7 +1616,7 @@ begin end if; - sql_string = format('select count(1) cnt from accounts where slug = ''' || tmp_slug || + sql_string = format('select count(1) cnt from public.accounts where slug = ''' || tmp_slug || '''; '); for tmp_row in execute (sql_string) diff --git a/package.json b/package.json index 81cbe3972..3cbb366e4 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "supabase:web:start": "pnpm --filter web supabase:start", "supabase:web:stop": "pnpm --filter web supabase:stop", "supabase:web:typegen": "pnpm --filter web supabase:typegen", + "supabase:web:reset": "pnpm --filter web supabase:reset", "stripe:listen": "pnpm --filter '@kit/stripe' start" }, "prettier": "@kit/prettier-config", diff --git a/packages/features/accounts/src/components/account-selector.tsx b/packages/features/accounts/src/components/account-selector.tsx index 1b2337dde..85e64b38b 100644 --- a/packages/features/accounts/src/components/account-selector.tsx +++ b/packages/features/accounts/src/components/account-selector.tsx @@ -18,6 +18,7 @@ import { } from '@kit/ui/command'; import { If } from '@kit/ui/if'; import { Popover, PopoverContent, PopoverTrigger } from '@kit/ui/popover'; +import { Separator } from '@kit/ui/separator'; import { Trans } from '@kit/ui/trans'; import { cn } from '@kit/ui/utils'; @@ -177,7 +178,14 @@ export function AccountSelector({ 0}> - }> + + } + > {(accounts ?? []).map((account) => ( ))} - - - - - - - - + + + + + + diff --git a/packages/features/accounts/src/components/personal-account-settings/account-danger-zone.tsx b/packages/features/accounts/src/components/personal-account-settings/account-danger-zone.tsx index 5e9f1f9bc..b97a5d935 100644 --- a/packages/features/accounts/src/components/personal-account-settings/account-danger-zone.tsx +++ b/packages/features/accounts/src/components/personal-account-settings/account-danger-zone.tsx @@ -5,7 +5,6 @@ import { useFormStatus } from 'react-dom'; import { zodResolver } from '@hookform/resolvers/zod'; import { ExclamationTriangleIcon } from '@radix-ui/react-icons'; import { useForm } from 'react-hook-form'; -import { z } from 'zod'; import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert'; import { @@ -23,6 +22,7 @@ import { Form, FormControl, FormItem, FormLabel } from '@kit/ui/form'; import { Input } from '@kit/ui/input'; import { Trans } from '@kit/ui/trans'; +import { DeletePersonalAccountSchema } from '../../schema/delete-personal-account.schema'; import { deletePersonalAccountAction } from '../../server/personal-accounts-server-actions'; export function AccountDangerZone() { @@ -71,11 +71,7 @@ function DeleteAccountModal() { function DeleteAccountForm() { const form = useForm({ - resolver: zodResolver( - z.object({ - confirmation: z.string().refine((value) => value === 'DELETE'), - }), - ), + resolver: zodResolver(DeletePersonalAccountSchema), defaultValues: { confirmation: '', }, @@ -140,11 +136,10 @@ function DeleteAccountSubmitButton() { return (