From d04677332812d1afea9ae130e247446b744cc9d0 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Fri, 6 Nov 2020 13:30:38 +0200 Subject: [PATCH 01/15] WIP --- assets/css/app.css | 10 +- assets/package-lock.json | 94 +++++++----- assets/package.json | 2 +- .../controllers/site_controller.ex | 18 ++- lib/plausible_web/router.ex | 3 +- .../templates/site/_settings_tab.html.eex | 5 + .../templates/site/settings.html.eex | 137 ++++++++++++++++++ .../templates/site/settings_goals.html.eex | 31 ++++ .../templates/site/settings_header.html.eex | 25 ++++ 9 files changed, 286 insertions(+), 39 deletions(-) create mode 100644 lib/plausible_web/templates/site/_settings_tab.html.eex create mode 100644 lib/plausible_web/templates/site/settings_goals.html.eex create mode 100644 lib/plausible_web/templates/site/settings_header.html.eex diff --git a/assets/css/app.css b/assets/css/app.css index 9b40219ef..990c187f1 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -7,15 +7,19 @@ @import "tooltip.css"; .button { - @apply inline-block bg-indigo-600 text-white text-center font-bold tracking-wide py-2 px-5 rounded no-underline; + @apply bg-indigo-600 border border-transparent rounded-md py-2 px-4 inline-flex justify-center text-sm leading-5 font-medium text-white transition-all duration-150 ease-in-out; } .button:hover { - @apply shadow; + @apply bg-gray-700; } .button:focus { - @apply outline-none; + @apply outline-none border-gray-900 shadow-outline-gray; +} + +.button:active { + @apply bg-gray-900; } .button-outline { diff --git a/assets/package-lock.json b/assets/package-lock.json index 78b1a6220..c82c27075 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -1160,11 +1160,6 @@ "postcss-selector-parser": "^6.0.2" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, "@types/d3": { "version": "3.5.38", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.38.tgz", @@ -1369,9 +1364,9 @@ }, "dependencies": { "acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==" + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" } } }, @@ -4159,6 +4154,11 @@ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" }, + "html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==" + }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -5081,6 +5081,11 @@ } } }, + "object-hash": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", + "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==" + }, "object-inspect": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", @@ -7108,7 +7113,7 @@ }, "pretty-hrtime": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" }, "process": { @@ -8193,9 +8198,9 @@ } }, "tailwindcss": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.6.2.tgz", - "integrity": "sha512-Cpa0kElG8Sg5sJSvTYi2frmIQZq0w37RLNNrYyy/W6HIWKspqSdTfb9tIN6X1gm4KV5a+TE/n7EKmn5Q9C7EUQ==", + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.9.6.tgz", + "integrity": "sha512-nY8WYM/RLPqGsPEGEV2z63riyQPcHYZUJpAwdyBzVpxQHOHqHE+F/fvbCeXhdF1+TA5l72vSkZrtYCB9hRcwkQ==", "requires": { "@fullhuman/postcss-purgecss": "^2.1.2", "autoprefixer": "^9.4.5", @@ -8205,43 +8210,46 @@ "color": "^3.1.2", "detective": "^5.2.0", "fs-extra": "^8.0.0", - "lodash": "^4.17.15", + "html-tags": "^3.1.0", + "lodash": "^4.17.20", "node-emoji": "^1.8.1", "normalize.css": "^8.0.1", + "object-hash": "^2.0.3", "postcss": "^7.0.11", "postcss-functions": "^3.0.0", "postcss-js": "^2.0.0", "postcss-nested": "^4.1.1", "postcss-selector-parser": "^6.0.0", + "postcss-value-parser": "^4.1.0", "pretty-hrtime": "^1.0.3", "reduce-css-calc": "^2.1.6", "resolve": "^1.14.2" }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "browserslist": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", - "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", + "version": "4.14.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.7.tgz", + "integrity": "sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ==", "requires": { - "caniuse-lite": "^1.0.30001111", - "electron-to-chromium": "^1.3.523", - "escalade": "^3.0.2", - "node-releases": "^1.1.60" + "caniuse-lite": "^1.0.30001157", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.591", + "escalade": "^3.1.1", + "node-releases": "^1.1.66" } }, "caniuse-lite": { - "version": "1.0.30001114", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001114.tgz", - "integrity": "sha512-ml/zTsfNBM+T1+mjglWRPgVsu2L76GAaADKX5f4t0pbhttEp0WMawJsHDYlFkVZkoA+89uvBRrVrEE4oqenzXQ==" + "version": "1.0.30001157", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001157.tgz", + "integrity": "sha512-gOerH9Wz2IRZ2ZPdMfBvyOi3cjaz4O4dgNwPGzx8EhqAs4+2IL/O+fJsbt+znSigujoZG8bVcIAUM/I/E5K3MA==" }, "chalk": { "version": "4.1.0", @@ -8265,20 +8273,40 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "electron-to-chromium": { + "version": "1.3.593", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.593.tgz", + "integrity": "sha512-GvO7G1ZxvffnMvPCr4A7+iQPVuvpyqMrx2VWSERAjG+pHK6tmO9XqYdBfMIq9corRyi4bNImSDEiDvIoDb8HrA==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, "node-releases": { - "version": "1.1.60", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", - "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==" + "version": "1.1.66", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.66.tgz", + "integrity": "sha512-JHEQ1iWPGK+38VLB2H9ef2otU4l8s3yAMt9Xf934r6+ojCYDMHPMqvCc9TnzfeFSP1QEOeU6YZEd3+De0LTCgg==" + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } diff --git a/assets/package.json b/assets/package.json index d84ee5dae..ec550d909 100644 --- a/assets/package.json +++ b/assets/package.json @@ -29,7 +29,7 @@ "react-flip-move": "^3.0.4", "react-router-dom": "^5.2.0", "react-transition-group": "^4.4.1", - "tailwindcss": "^1.6.2", + "tailwindcss": "^1.9.6", "uglifyjs-webpack-plugin": "^2.2.0", "url-search-params-polyfill": "^8.0.0", "webpack": "4.39.2", diff --git a/lib/plausible_web/controllers/site_controller.ex b/lib/plausible_web/controllers/site_controller.ex index b040fa609..d39ffa937 100644 --- a/lib/plausible_web/controllers/site_controller.ex +++ b/lib/plausible_web/controllers/site_controller.ex @@ -87,6 +87,10 @@ defmodule PlausibleWeb.SiteController do end def settings(conn, %{"website" => website}) do + redirect(conn, to: "/#{URI.encode_www_form(website)}/settings/general") + end + + def settings_general(conn, %{"website" => website}) do site = Sites.get_for_user!(conn.assigns[:current_user].id, website) |> Repo.preload(:google_auth) @@ -99,8 +103,8 @@ defmodule PlausibleWeb.SiteController do weekly_report = Repo.get_by(Plausible.Site.WeeklyReport, site_id: site.id) monthly_report = Repo.get_by(Plausible.Site.MonthlyReport, site_id: site.id) - goals = Goals.for_site(site.domain) shared_links = Repo.all(from l in Plausible.Site.SharedLink, where: l.site_id == ^site.id) + goals = Goals.for_site(site.domain) conn |> assign(:skip_plausible_tracking, true) @@ -115,6 +119,18 @@ defmodule PlausibleWeb.SiteController do ) end + def settings_goals(conn, %{"website" => website}) do + site = Sites.get_for_user!(conn.assigns[:current_user].id, website) + goals = Goals.for_site(site.domain) + + conn + |> assign(:skip_plausible_tracking, true) + |> render("settings_goals.html", + site: site, + goals: goals + ) + end + def update_google_auth(conn, %{"website" => website, "google_auth" => attrs}) do site = Sites.get_for_user!(conn.assigns[:current_user].id, website) diff --git a/lib/plausible_web/router.ex b/lib/plausible_web/router.ex index 295f3c0cf..006ffba8c 100644 --- a/lib/plausible_web/router.ex +++ b/lib/plausible_web/router.ex @@ -145,7 +145,8 @@ defmodule PlausibleWeb.Router do get "/:website/snippet", SiteController, :add_snippet get "/:website/settings", SiteController, :settings - get "/:website/goals", SiteController, :goals + get "/:website/settings/general", SiteController, :settings_general + get "/:website/settings/goals", SiteController, :settings_goals get "/:website/goals/new", SiteController, :new_goal post "/:website/goals", SiteController, :create_goal delete "/:website/goals/:id", SiteController, :delete_goal diff --git a/lib/plausible_web/templates/site/_settings_tab.html.eex b/lib/plausible_web/templates/site/_settings_tab.html.eex new file mode 100644 index 000000000..896ac8d10 --- /dev/null +++ b/lib/plausible_web/templates/site/_settings_tab.html.eex @@ -0,0 +1,5 @@ +<%= if @current_tab == @this_tab do %> + "><%= @text %> +<% else %> + "><%= @text %> +<% end %> diff --git a/lib/plausible_web/templates/site/settings.html.eex b/lib/plausible_web/templates/site/settings.html.eex index 66ae79b7f..b2da611b4 100644 --- a/lib/plausible_web/templates/site/settings.html.eex +++ b/lib/plausible_web/templates/site/settings.html.eex @@ -1,3 +1,140 @@ +
+
+ <%= render("settings_header.html", tab: "general", site: @site) %> + +
+ <%= form_for @changeset, "/#{URI.encode_www_form(@site.domain)}/settings", fn f -> %> +
+
+
+

General information

+

Update your billing information. Please note that updating your location could affect your tax rates.

+
+ +
+
+ <%= label f, :domain, class: "block text-sm font-medium leading-5 text-gray-700" %> + <%= text_input f, :domain, class: "form-input mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 transition duration-150 ease-in-out sm:text-sm sm:leading-5", disabled: "disabled" %> +
+ +
+ <%= label f, :timezone, "Reporting Timezone", class: "block text-sm font-medium leading-5 text-gray-700" %> + <%= select f, :timezone, Plausible.Timezones.options(), class: "form-select mt-1 block w-full bg-white border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 transition duration-150 ease-in-out sm:text-sm sm:leading-5" %> +
+
+
+
+ + <%= submit "Save", class: "bg-indigo-600 border border-transparent rounded-md py-2 px-4 inline-flex justify-center text-sm leading-5 font-medium text-white hover:bg-gray-700 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray active:bg-gray-900 transition duration-150 ease-in-out" %> + +
+
+ <% end %> + +
+
+

Dashboard visibility

+

Share your stats publicly or keep them private

+
+ +
+
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+
+
+ +
+
+

Shared links

+

You can share your stats privately by generating a shared link. The links are impossible to guess and you can add password protection for extra security.

+
+ +
+ <%= for link <- @shared_links do %> +
+ + + <%= button(to: "/sites/#{URI.encode_www_form(@site.domain)}/shared-links/#{link.slug}", method: :delete, class: "py-2 px-4 bg-gray-100 text-red-600 rounded-l-none", data: [confirm: "Are you sure you want to delete this shared link? The stats will not be accessible with this link anymore."]) do %> + + <% end %> +
+ <% end %> + + <%= link("+ New link", to: "/sites/#{URI.encode_www_form(@site.domain)}/shared-links/new", class: "button mt-4") %> +
+
+
+ +
+
+
+

Danger zone

+

Desctructive actions below can result in irrecoverable data loss. Be careful.

+
+
  • +
    +

    + Reset stats +

    +

    + Removes all pageviews but keeps the site configuration +

    +
    + <%= link("Reset #{@site.domain} stats", to: "/#{URI.encode_www_form(@site.domain)}/stats", method: :delete, class: "inline-block px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-red-700 bg-white hover:text-red-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-red-800 active:bg-gray-50 transition ease-in-out duration-150", data: [confirm: "Resetting the stats cannot be reversed. Are you sure?"]) %> +
  • +
    + +
  • +
    +

    + Delete site +

    +

    + Removes all stats along with the site configuration +

    +
    + <%= link "Delete #{@site.domain}", to: "/#{URI.encode_www_form(@site.domain)}", method: :delete, class: "inline-block px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-50 focus:outline-none focus:border-red-300 focus:shadow-outline-red active:bg-red-200 transition ease-in-out duration-150 sm:text-sm sm:leading-5", data: [confirm: "Deleting the site data cannot be reversed. Are you sure?"] %> +
  • +
    +
    +
    +
    +
    +

    Settings for <%= @site.domain %>

    diff --git a/lib/plausible_web/templates/site/settings_goals.html.eex b/lib/plausible_web/templates/site/settings_goals.html.eex new file mode 100644 index 000000000..03ea7c197 --- /dev/null +++ b/lib/plausible_web/templates/site/settings_goals.html.eex @@ -0,0 +1,31 @@ +
    +
    + <%= render("settings_header.html", tab: "goals", site: @site) %> + +
    +
    +
    +

    Goals

    +

    Define actions that you want your users to take like visiting a certain page, submitting a form, etc.

    +
    + + <%= if Enum.count(@goals) > 0 do %> +
    + <%= for goal <- @goals do %> +
    + <%= goal_name(goal) %> + <%= button(to: "/#{URI.encode_www_form(@site.domain)}/goals/#{goal.id}", method: :delete, class: "text-sm text-red-600", data: [confirm: "Are you sure you want to remove goal #{goal_name(goal)}? This will just affect the UI, all of your analytics data will stay intact."]) do %> + + <% end %> +
    + <% end %> +
    + <% else %> +
    No goals configured for this site yet
    + <% end %> + + <%= link("+ Add goal", to: "/#{URI.encode_www_form(@site.domain)}/goals/new", class: "button mt-6") %> +
    +
    +
    +
    diff --git a/lib/plausible_web/templates/site/settings_header.html.eex b/lib/plausible_web/templates/site/settings_header.html.eex new file mode 100644 index 000000000..d412a5d3c --- /dev/null +++ b/lib/plausible_web/templates/site/settings_header.html.eex @@ -0,0 +1,25 @@ +
    +
    + +
    + +
    From b0bd564b560e81592ce33dd3d76c6c3693d8b062 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Mon, 16 Nov 2020 15:38:44 +0200 Subject: [PATCH 02/15] Create unified template for settings --- assets/js/app.js | 9 +- assets/package-lock.json | 7 +- assets/package.json | 1 + .../controllers/site_controller.ex | 133 +++--- lib/plausible_web/router.ex | 4 + .../templates/billing/change_plan.html.eex | 1 - .../billing/change_plan_preview.html.eex | 1 - .../templates/billing/upgrade.html.eex | 1 - .../templates/layout/_flash.html.eex | 34 ++ .../templates/layout/_footer.html.eex | 2 +- .../{site => layout}/_settings_tab.html.eex | 2 +- .../templates/layout/app.html.eex | 8 +- .../templates/layout/site_settings.html.eex | 41 ++ .../templates/site/settings.html.eex | 395 ------------------ .../site/settings_custom_domain.html.eex | 14 + .../site/settings_email_reports.html.eex | 70 ++++ .../templates/site/settings_general.html.eex | 106 +++++ .../templates/site/settings_goals.html.eex | 48 +-- .../site/settings_search_console.html.eex | 48 +++ .../templates/site/settings_snippet.html.eex | 15 + lib/plausible_web/views/layout_view.ex | 9 + 21 files changed, 458 insertions(+), 491 deletions(-) create mode 100644 lib/plausible_web/templates/layout/_flash.html.eex rename lib/plausible_web/templates/{site => layout}/_settings_tab.html.eex (94%) create mode 100644 lib/plausible_web/templates/layout/site_settings.html.eex delete mode 100644 lib/plausible_web/templates/site/settings.html.eex create mode 100644 lib/plausible_web/templates/site/settings_custom_domain.html.eex create mode 100644 lib/plausible_web/templates/site/settings_email_reports.html.eex create mode 100644 lib/plausible_web/templates/site/settings_general.html.eex create mode 100644 lib/plausible_web/templates/site/settings_search_console.html.eex create mode 100644 lib/plausible_web/templates/site/settings_snippet.html.eex diff --git a/assets/js/app.js b/assets/js/app.js index 4305488da..ea7e58f3c 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -3,6 +3,7 @@ import "flatpickr/dist/flatpickr.min.css" import "./polyfills/closest" import 'abortcontroller-polyfill/dist/polyfill-patch-fetch' import "phoenix_html" +import 'alpinejs' const triggers = document.querySelectorAll('[data-dropdown-trigger]') @@ -33,14 +34,6 @@ if (triggers.length > 0) { }) } -const flash = document.getElementById('flash') - -if (flash) { - setTimeout(function() { - flash.style.display = 'none' - }, 2500) -} - const registerForm = document.getElementById('register-form') if (registerForm) { diff --git a/assets/package-lock.json b/assets/package-lock.json index c82c27075..90b774e30 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -1410,6 +1410,11 @@ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" }, + "alpinejs": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-2.7.3.tgz", + "integrity": "sha512-IRXnszk68s+FOGFMA1+K3rjLK44NqLShNpSy8aI6J3Ch9gss56FqlU6NVRP+mJes7LeQFCreH410luScVSkdfg==" + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -7113,7 +7118,7 @@ }, "pretty-hrtime": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" }, "process": { diff --git a/assets/package.json b/assets/package.json index ec550d909..7632125e4 100644 --- a/assets/package.json +++ b/assets/package.json @@ -12,6 +12,7 @@ "@fullhuman/postcss-purgecss": "^2.3.0", "@tailwindcss/ui": "^0.1.4", "abortcontroller-polyfill": "^1.5.0", + "alpinejs": "^2.7.3", "autoprefixer": "^9.8.6", "babel-loader": "^8.1.0", "chart.js": "^2.9.3", diff --git a/lib/plausible_web/controllers/site_controller.ex b/lib/plausible_web/controllers/site_controller.ex index d39ffa937..64690ef7b 100644 --- a/lib/plausible_web/controllers/site_controller.ex +++ b/lib/plausible_web/controllers/site_controller.ex @@ -65,7 +65,7 @@ defmodule PlausibleWeb.SiteController do {:ok, _} -> conn |> put_flash(:success, "Goal created succesfully") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/goals") {:error, :goal, changeset, _} -> conn @@ -83,7 +83,7 @@ defmodule PlausibleWeb.SiteController do conn |> put_flash(:success, "Goal deleted succesfully") - |> redirect(to: "/#{URI.encode_www_form(website)}/settings") + |> redirect(to: "/#{URI.encode_www_form(website)}/settings/goals") end def settings(conn, %{"website" => website}) do @@ -93,29 +93,16 @@ defmodule PlausibleWeb.SiteController do def settings_general(conn, %{"website" => website}) do site = Sites.get_for_user!(conn.assigns[:current_user].id, website) - |> Repo.preload(:google_auth) - |> Repo.preload(:custom_domain) - search_console_domains = - if site.google_auth do - Plausible.Google.Api.fetch_verified_properties(site.google_auth) - end - - weekly_report = Repo.get_by(Plausible.Site.WeeklyReport, site_id: site.id) - monthly_report = Repo.get_by(Plausible.Site.MonthlyReport, site_id: site.id) shared_links = Repo.all(from l in Plausible.Site.SharedLink, where: l.site_id == ^site.id) - goals = Goals.for_site(site.domain) conn |> assign(:skip_plausible_tracking, true) - |> render("settings.html", + |> render("settings_general.html", site: site, - weekly_report: weekly_report, - monthly_report: monthly_report, - search_console_domains: search_console_domains, - goals: goals, shared_links: shared_links, - changeset: Plausible.Site.changeset(site, %{}) + changeset: Plausible.Site.changeset(site, %{}), + layout: {PlausibleWeb.LayoutView, "site_settings.html"} ) end @@ -127,10 +114,60 @@ defmodule PlausibleWeb.SiteController do |> assign(:skip_plausible_tracking, true) |> render("settings_goals.html", site: site, - goals: goals + goals: goals, + layout: {PlausibleWeb.LayoutView, "site_settings.html"} ) end + def settings_search_console(conn, %{"website" => website}) do + site = Sites.get_for_user!(conn.assigns[:current_user].id, website) + |> Repo.preload(:google_auth) + + search_console_domains = + if site.google_auth do + Plausible.Google.Api.fetch_verified_properties(site.google_auth) + end + + conn + |> assign(:skip_plausible_tracking, true) + |> render("settings_search_console.html", + site: site, + search_console_domains: search_console_domains, + layout: {PlausibleWeb.LayoutView, "site_settings.html"} + ) + end + + def settings_email_reports(conn, %{"website" => website}) do + site = Sites.get_for_user!(conn.assigns[:current_user].id, website) + + conn + |> assign(:skip_plausible_tracking, true) + |> render("settings_email_reports.html", + site: site, + weekly_report: Repo.get_by(Plausible.Site.WeeklyReport, site_id: site.id), + monthly_report: Repo.get_by(Plausible.Site.MonthlyReport, site_id: site.id), + layout: {PlausibleWeb.LayoutView, "site_settings.html"} + ) + end + + def settings_custom_domain(conn, %{"website" => website}) do + site = Sites.get_for_user!(conn.assigns[:current_user].id, website) + |> Repo.preload(:custom_domain) + + conn + |> assign(:skip_plausible_tracking, true) + |> render("settings_custom_domain.html", site: site, layout: {PlausibleWeb.LayoutView, "site_settings.html"}) + end + + def settings_snippet(conn, %{"website" => website}) do + site = Sites.get_for_user!(conn.assigns[:current_user].id, website) + |> Repo.preload(:custom_domain) + + conn + |> assign(:skip_plausible_tracking, true) + |> render("settings_snippet.html", site: site, layout: {PlausibleWeb.LayoutView, "site_settings.html"}) + end + def update_google_auth(conn, %{"website" => website, "google_auth" => attrs}) do site = Sites.get_for_user!(conn.assigns[:current_user].id, website) @@ -141,7 +178,7 @@ defmodule PlausibleWeb.SiteController do conn |> put_flash(:success, "Google integration saved succesfully") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#google-auth") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/search-console") end def delete_google_auth(conn, %{"website" => website}) do @@ -152,8 +189,8 @@ defmodule PlausibleWeb.SiteController do Repo.delete!(site.google_auth) conn - |> put_flash(:success, "Google account unlinked succesfully") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#google-auth") + |> put_flash(:success, "Google account unlinked from Plausible") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/search-console") end def update_settings(conn, %{"website" => website, "site" => site_params}) do @@ -167,11 +204,11 @@ defmodule PlausibleWeb.SiteController do conn |> put_session(site_session_key, nil) - |> put_flash(:success, "Site settings saved succesfully") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings") + |> put_flash(:success, "Your site settings have been saved") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/general") {:error, changeset} -> - render("settings.html", site: site, changeset: changeset) + render("settings_general.html", site: site, changeset: changeset) end end @@ -181,7 +218,7 @@ defmodule PlausibleWeb.SiteController do conn |> put_flash(:success, "#{site.domain} stats will be reset in a few minutes") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/general") end def delete_site(conn, %{"website" => website}) do @@ -210,8 +247,8 @@ defmodule PlausibleWeb.SiteController do |> Repo.update!() conn - |> put_flash(:success, "Congrats! Stats for #{site.domain} are now public.") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings") + |> put_flash(:success, "Stats for #{site.domain} are now public.") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/general") end def make_private(conn, %{"website" => website}) do @@ -222,7 +259,7 @@ defmodule PlausibleWeb.SiteController do conn |> put_flash(:success, "Stats for #{site.domain} are now private.") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/general") end def enable_weekly_report(conn, %{"website" => website}) do @@ -235,8 +272,8 @@ defmodule PlausibleWeb.SiteController do |> Repo.insert!() conn - |> put_flash(:success, "Success! You will receive an email report every Monday going forward") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#email-reports") + |> put_flash(:success, "You will receive an email report every Monday going forward") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/email-reports") end def disable_weekly_report(conn, %{"website" => website}) do @@ -244,8 +281,8 @@ defmodule PlausibleWeb.SiteController do Repo.delete_all(from wr in Plausible.Site.WeeklyReport, where: wr.site_id == ^site.id) conn - |> put_flash(:success, "Success! You will not receive weekly email reports going forward") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#email-reports") + |> put_flash(:success, "You will not receive weekly email reports going forward") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/email-reports") end def add_weekly_report_recipient(conn, %{"website" => website, "recipient" => recipient}) do @@ -256,8 +293,8 @@ defmodule PlausibleWeb.SiteController do |> Repo.update!() conn - |> put_flash(:success, "Succesfully added #{recipient} as a recipient for the weekly report") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#email-reports") + |> put_flash(:success, "Added #{recipient} as a recipient for the weekly report") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/email-reports") end def remove_weekly_report_recipient(conn, %{"website" => website, "recipient" => recipient}) do @@ -270,9 +307,9 @@ defmodule PlausibleWeb.SiteController do conn |> put_flash( :success, - "Succesfully removed #{recipient} as a recipient for the weekly report" + "Removed #{recipient} as a recipient for the weekly report" ) - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#email-reports") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/email-reports") end def enable_monthly_report(conn, %{"website" => website}) do @@ -285,8 +322,8 @@ defmodule PlausibleWeb.SiteController do |> Repo.insert!() conn - |> put_flash(:success, "Success! You will receive an email report every month going forward") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#email-reports") + |> put_flash(:success, "You will receive an email report every month going forward") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/email-reports") end def disable_monthly_report(conn, %{"website" => website}) do @@ -294,8 +331,8 @@ defmodule PlausibleWeb.SiteController do Repo.delete_all(from mr in Plausible.Site.MonthlyReport, where: mr.site_id == ^site.id) conn - |> put_flash(:success, "Success! You will not receive monthly email reports going forward") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#email-reports") + |> put_flash(:success, "You will not receive monthly email reports going forward") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/email-reports") end def add_monthly_report_recipient(conn, %{"website" => website, "recipient" => recipient}) do @@ -306,8 +343,8 @@ defmodule PlausibleWeb.SiteController do |> Repo.update!() conn - |> put_flash(:success, "Succesfully added #{recipient} as a recipient for the monthly report") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#email-reports") + |> put_flash(:success, "Added #{recipient} as a recipient for the monthly report") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/email-reports") end def remove_monthly_report_recipient(conn, %{"website" => website, "recipient" => recipient}) do @@ -320,9 +357,9 @@ defmodule PlausibleWeb.SiteController do conn |> put_flash( :success, - "Succesfully removed #{recipient} as a recipient for the monthly report" + "Removed #{recipient} as a recipient for the monthly report" ) - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings#email-reports") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/email-reports") end def new_shared_link(conn, %{"website" => website}) do @@ -352,7 +389,7 @@ defmodule PlausibleWeb.SiteController do case Repo.insert(changes) do {:ok, _created} -> - redirect(conn, to: "/#{URI.encode_www_form(site.domain)}/settings#visibility") + redirect(conn, to: "/#{URI.encode_www_form(site.domain)}/settings/general") {:error, changeset} -> conn @@ -371,7 +408,7 @@ defmodule PlausibleWeb.SiteController do Repo.get_by(Plausible.Site.SharedLink, slug: slug) |> Repo.delete!() - redirect(conn, to: "/#{URI.encode_www_form(site.domain)}/settings#visibility") + redirect(conn, to: "/#{URI.encode_www_form(site.domain)}/settings/general") end def new_custom_domain(conn, %{"website" => website}) do @@ -440,7 +477,7 @@ defmodule PlausibleWeb.SiteController do conn |> put_flash(:success, "Custom domain deleted succesfully") - |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings") + |> redirect(to: "/#{URI.encode_www_form(site.domain)}/settings/custom-domain") end defp insert_site(user_id, params) do diff --git a/lib/plausible_web/router.ex b/lib/plausible_web/router.ex index 006ffba8c..951e70c3a 100644 --- a/lib/plausible_web/router.ex +++ b/lib/plausible_web/router.ex @@ -147,6 +147,10 @@ defmodule PlausibleWeb.Router do get "/:website/settings", SiteController, :settings get "/:website/settings/general", SiteController, :settings_general get "/:website/settings/goals", SiteController, :settings_goals + get "/:website/settings/search-console", SiteController, :settings_search_console + get "/:website/settings/email-reports", SiteController, :settings_email_reports + get "/:website/settings/custom-domain", SiteController, :settings_custom_domain + get "/:website/settings/js-snippet", SiteController, :settings_snippet get "/:website/goals/new", SiteController, :new_goal post "/:website/goals", SiteController, :create_goal delete "/:website/goals/:id", SiteController, :delete_goal diff --git a/lib/plausible_web/templates/billing/change_plan.html.eex b/lib/plausible_web/templates/billing/change_plan.html.eex index 3f9aea4d6..00db4be08 100644 --- a/lib/plausible_web/templates/billing/change_plan.html.eex +++ b/lib/plausible_web/templates/billing/change_plan.html.eex @@ -124,5 +124,4 @@
    - diff --git a/lib/plausible_web/templates/billing/change_plan_preview.html.eex b/lib/plausible_web/templates/billing/change_plan_preview.html.eex index 4cab63840..ff2330d04 100644 --- a/lib/plausible_web/templates/billing/change_plan_preview.html.eex +++ b/lib/plausible_web/templates/billing/change_plan_preview.html.eex @@ -82,5 +82,4 @@ - diff --git a/lib/plausible_web/templates/billing/upgrade.html.eex b/lib/plausible_web/templates/billing/upgrade.html.eex index 7a77d4679..d885de67c 100644 --- a/lib/plausible_web/templates/billing/upgrade.html.eex +++ b/lib/plausible_web/templates/billing/upgrade.html.eex @@ -128,5 +128,4 @@ - diff --git a/lib/plausible_web/templates/layout/_flash.html.eex b/lib/plausible_web/templates/layout/_flash.html.eex new file mode 100644 index 000000000..64ad10583 --- /dev/null +++ b/lib/plausible_web/templates/layout/_flash.html.eex @@ -0,0 +1,34 @@ +<%= if get_flash(@conn, :success) do %> +
    +
    +
    +
    +
    +
    + + + + +
    +
    +

    + <%= get_flash(@conn, :success_title) || "Success!" %> +

    +

    + <%= get_flash(@conn, :success) %> +

    +
    +
    + +
    +
    +
    +
    +
    +
    +<% end %> diff --git a/lib/plausible_web/templates/layout/_footer.html.eex b/lib/plausible_web/templates/layout/_footer.html.eex index 09cbf1648..8d84b9132 100644 --- a/lib/plausible_web/templates/layout/_footer.html.eex +++ b/lib/plausible_web/templates/layout/_footer.html.eex @@ -1,4 +1,4 @@ -
    +
    diff --git a/lib/plausible_web/templates/site/_settings_tab.html.eex b/lib/plausible_web/templates/layout/_settings_tab.html.eex similarity index 94% rename from lib/plausible_web/templates/site/_settings_tab.html.eex rename to lib/plausible_web/templates/layout/_settings_tab.html.eex index 896ac8d10..0b9312ab4 100644 --- a/lib/plausible_web/templates/site/_settings_tab.html.eex +++ b/lib/plausible_web/templates/layout/_settings_tab.html.eex @@ -1,4 +1,4 @@ -<%= if @current_tab == @this_tab do %> +<%= if is_current_tab(@conn, @this_tab) do %> "><%= @text %> <% else %> "><%= @text %> diff --git a/lib/plausible_web/templates/layout/app.html.eex b/lib/plausible_web/templates/layout/app.html.eex index ddecb7f22..2266fded9 100644 --- a/lib/plausible_web/templates/layout/app.html.eex +++ b/lib/plausible_web/templates/layout/app.html.eex @@ -80,11 +80,7 @@
    - <%= if get_flash(@conn, :success) do %> - - <% end %> + <%= render("_flash.html", assigns) %> <%= if get_flash(@conn, :error) do %>