diff --git a/CHANGELOG.md b/CHANGELOG.md index 471a0501c812..cf2c9a54d9f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. - Removed the intermediate "Awaiting your first pageview" screen after site created. User is now taken straight to the dashboard from the installation instructions page. - Removed the standalone team switcher page; team switching is now done from the topbar dropdown only - Removed `Bamboo.SMTPAdapter` from supported e-mail adapters; the library is no longer in active developments and does not compile under Elixir 1.20+ +- Removed timezone selection field when creating a new site. Timezone is automatically detected and can still be changed in site settings. ### Changed @@ -39,6 +40,7 @@ All notable changes to this project will be documented in this file. - Improved site transfer UI - Redesigned authentication pages (register, sign in, 2FA, password reset, account activation) - Removed limitation that blocked users without owned sites from starting a subscription +- Redesigned onboarding pages (add site, installation) ### Fixed diff --git a/assets/js/app.js b/assets/js/app.js index f73084a96689..ca1143490f4a 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -3,11 +3,13 @@ import 'abortcontroller-polyfill/dist/polyfill-patch-fetch' import Alpine from 'alpinejs' import './liveview/live_socket' import comboBox from './liveview/combo-box' +import copySnippet from './liveview/copy-snippet' import dropdown from './liveview/dropdown' import './liveview/phx_events' Alpine.data('dropdown', dropdown) Alpine.data('comboBox', comboBox) +Alpine.data('copySnippet', copySnippet) Alpine.start() if (document.querySelectorAll('[data-modal]').length > 0) { diff --git a/assets/js/liveview/copy-snippet.js b/assets/js/liveview/copy-snippet.js new file mode 100644 index 000000000000..e3f6fdb3e7e8 --- /dev/null +++ b/assets/js/liveview/copy-snippet.js @@ -0,0 +1,34 @@ +// Copy-to-clipboard behaviour for a readonly textarea holding a code snippet. +// Expects an `x-ref="snippet"` textarea within the same `x-data` scope. + +const RESET_DELAY = 2000 + +const hasSelection = (el) => el.selectionStart !== el.selectionEnd + +const isFullySelected = (el) => + el.selectionStart === 0 && el.selectionEnd === el.value.length + +export default () => ({ + copied: false, + copyAll() { + const el = this.$refs.snippet + el.focus() + el.select() + document.execCommand('copy') + this.copied = true + + setTimeout(() => { + this.copied = false + + // Leave it alone if the user has highlighted their own text since. + if (isFullySelected(el)) { + el.setSelectionRange(0, 0) + el.blur() + } + }, RESET_DELAY) + }, + copyIfNoSelection() { + if (hasSelection(this.$refs.snippet)) return + this.copyAll() + } +}) diff --git a/e2e/tests/fixtures.ts b/e2e/tests/fixtures.ts index 34eeabc2c59c..f3022996ee37 100644 --- a/e2e/tests/fixtures.ts +++ b/e2e/tests/fixtures.ts @@ -115,9 +115,7 @@ export async function register({ await page.getByRole('button', { name: 'Activate' }).click() - await expect( - page.getByRole('button', { name: 'Install Plausible' }) - ).toBeVisible() + await expect(page.getByRole('button', { name: 'Add site' })).toBeVisible() } export async function login({ page, user }: { page: Page; user: User }) { @@ -149,19 +147,16 @@ export async function addSite({ }) { await page.goto('/sites/new', { waitUntil: 'commit' }) - await expect( - page.getByRole('button', { name: 'Install Plausible' }) - ).toBeVisible() + await expect(page.getByRole('button', { name: 'Add site' })).toBeVisible() await page.getByLabel('Domain').fill(domain) - await page.getByLabel('Reporting timezone').selectOption('Etc/UTC') - await page.getByRole('button', { name: 'Install Plausible' }).click() + await page.getByRole('button', { name: 'Add site' }).click() await expect(page).toHaveURL(/\/installation/) await expect( - page.getByRole('button', { name: /Verify .* installation/ }) + page.getByRole('button', { name: "I've installed it" }) ).toBeVisible() } diff --git a/lib/plausible/site.ex b/lib/plausible/site.ex index b4c5aaa2daca..33da11e57036 100644 --- a/lib/plausible/site.ex +++ b/lib/plausible/site.ex @@ -97,13 +97,9 @@ defmodule Plausible.Site do end on_ee do - @domain_unique_error """ - This domain cannot be registered. Perhaps one of your colleagues registered it? If that's not the case, please contact support@plausible.io - """ + @domain_unique_error "This domain is already registered. Ask the owner for access, or contact support@plausible.io" else - @domain_unique_error """ - This domain cannot be registered. Perhaps one of your colleagues registered it? - """ + @domain_unique_error "This domain is already registered. Ask the owner for access." end on_ee do @@ -116,7 +112,8 @@ defmodule Plausible.Site do site |> cast(attrs, @changeset_cast_fields) |> clean_domain() - |> validate_required([:domain, :timezone]) + |> validate_required([:domain], message: "Please enter a domain or subdomain") + |> validate_required([:timezone]) |> validate_timezone() |> validate_domain_format() |> validate_domain_reserved_characters() diff --git a/lib/plausible_web/components/flow_progress.ex b/lib/plausible_web/components/flow_progress.ex index 53288065fedd..705a00a2c725 100644 --- a/lib/plausible_web/components/flow_progress.ex +++ b/lib/plausible_web/components/flow_progress.ex @@ -1,8 +1,8 @@ defmodule PlausibleWeb.Components.FlowProgress do @moduledoc """ - Component for provisioning/registration flows displaying - progress status. See `PlausibleWeb.Flows` for the list of - flow definitions. + Dotted progress indicator shown during the registration flow. + One small dot per step in `PlausibleWeb.Flows.steps/1`, with completed + and current steps highlighted. """ use Phoenix.Component @@ -20,45 +20,24 @@ defmodule PlausibleWeb.Components.FlowProgress do ) ~H""" -