Simplify asset building (#3459)
* Add tailwind and esbuild
* Remove unused images
* Move unprocessed assets to priv directory
* Fix applyTheme script
* Remove autoprefixer
* Update bundlemon
* Remove babel config
* Revert "Remove autoprefixer"
This reverts commit fc60c31c73
.
* Make dashboard react file work
* Fix app.css imports
* Remove autoprefixer
* Add back in robots.txt
* Go back to css/ and js/ folders as opposed to assets/
* Bundle embed.host.js and embed.content.js
* Add components folder to live reload paths
* Remove bundlemon
* Use mix assets task in Dockerfil
* Add assets setup to CONTRIBUTING.md
6
.github/workflows/node.yml
vendored
@ -28,10 +28,4 @@ jobs:
|
|||||||
- run: npm install --prefix ./tracker
|
- run: npm install --prefix ./tracker
|
||||||
- run: npm run lint --prefix ./assets
|
- run: npm run lint --prefix ./assets
|
||||||
- run: npm run check-format --prefix ./assets
|
- run: npm run check-format --prefix ./assets
|
||||||
- run: npm run deploy --prefix ./assets
|
|
||||||
- run: npm run deploy --prefix ./tracker
|
- run: npm run deploy --prefix ./tracker
|
||||||
- name: Run BundleMon
|
|
||||||
run: npm run bundlemon --prefix ./assets
|
|
||||||
env:
|
|
||||||
BUNDLEMON_PROJECT_ID: "619e0b6ad4a54a00089861ac"
|
|
||||||
CI_COMMIT_SHA: ${{github.event.pull_request.head.sha || github.sha}} # important!
|
|
||||||
|
3
.gitignore
vendored
@ -35,7 +35,8 @@ npm-debug.log
|
|||||||
# Since we are building assets from assets/,
|
# Since we are building assets from assets/,
|
||||||
# we ignore priv/static. You may want to comment
|
# we ignore priv/static. You may want to comment
|
||||||
# this depending on your deployment strategy.
|
# this depending on your deployment strategy.
|
||||||
/priv/static/
|
/priv/static/css
|
||||||
|
/priv/static/js
|
||||||
/priv/version.json
|
/priv/version.json
|
||||||
|
|
||||||
# Files matching config/*.secret.exs pattern contain sensitive
|
# Files matching config/*.secret.exs pattern contain sensitive
|
||||||
|
@ -18,8 +18,9 @@ Make sure Docker, Elixir, Erlang and Node.js are all installed on your developme
|
|||||||
4. Run `mix run priv/repo/seeds.exs` to seed the database. Check the [Seeds](#Seeds) section for more.
|
4. Run `mix run priv/repo/seeds.exs` to seed the database. Check the [Seeds](#Seeds) section for more.
|
||||||
5. Run `npm ci --prefix assets` to install the required client-side dependencies.
|
5. Run `npm ci --prefix assets` to install the required client-side dependencies.
|
||||||
6. Run `npm ci --prefix tracker` to install the required tracker dependencies.
|
6. Run `npm ci --prefix tracker` to install the required tracker dependencies.
|
||||||
7. Run `npm run deploy --prefix tracker` to generate tracker files in `priv/tracker/js`
|
7. Run `mix assets.setup` to install Tailwind and Esbuild
|
||||||
8. Run `mix download_country_database` to fetch geolocation database
|
8. Run `npm run deploy --prefix tracker` to generate tracker files in `priv/tracker/js`
|
||||||
|
9. Run `mix download_country_database` to fetch geolocation database
|
||||||
3. Run `make server` or `mix phx.server` to start the Phoenix server.
|
3. Run `make server` or `mix phx.server` to start the Phoenix server.
|
||||||
4. The system is now available on `localhost:8000`.
|
4. The system is now available on `localhost:8000`.
|
||||||
|
|
||||||
|
@ -19,8 +19,7 @@ WORKDIR /app
|
|||||||
|
|
||||||
# install build dependencies
|
# install build dependencies
|
||||||
RUN apk add --no-cache git nodejs yarn python3 npm ca-certificates wget gnupg make gcc libc-dev && \
|
RUN apk add --no-cache git nodejs yarn python3 npm ca-certificates wget gnupg make gcc libc-dev && \
|
||||||
npm install npm@latest -g && \
|
npm install npm@latest -g
|
||||||
npm install -g webpack
|
|
||||||
|
|
||||||
COPY mix.exs ./
|
COPY mix.exs ./
|
||||||
COPY mix.lock ./
|
COPY mix.lock ./
|
||||||
@ -41,8 +40,8 @@ COPY tracker ./tracker
|
|||||||
COPY priv ./priv
|
COPY priv ./priv
|
||||||
COPY lib ./lib
|
COPY lib ./lib
|
||||||
|
|
||||||
RUN npm run deploy --prefix ./assets && \
|
RUN npm run deploy --prefix ./tracker && \
|
||||||
npm run deploy --prefix ./tracker && \
|
mix assets.deploy && \
|
||||||
mix phx.digest priv/static && \
|
mix phx.digest priv/static && \
|
||||||
mix download_country_database && \
|
mix download_country_database && \
|
||||||
# https://hexdocs.pm/sentry/Sentry.Sources.html#module-source-code-storage
|
# https://hexdocs.pm/sentry/Sentry.Sources.html#module-source-code-storage
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
"@babel/preset-env",
|
|
||||||
"@babel/preset-react"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"baseDir": "../priv/",
|
|
||||||
"reportOutput": ["github"],
|
|
||||||
"files": [
|
|
||||||
{
|
|
||||||
"path": "static/js/*.js"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "static/css/app.css"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "tracker/js/plausible.js"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,12 +1,11 @@
|
|||||||
/* purgecss start ignore */
|
@import "tailwindcss/base";
|
||||||
@tailwind base;
|
@import "flatpickr/dist/flatpickr.min.css";
|
||||||
@tailwind components;
|
@import "./modal.css";
|
||||||
|
@import "./loader.css";
|
||||||
/* purgecss end ignore */
|
@import "./tooltip.css";
|
||||||
@import "modal.css";
|
@import "./flatpickr.css";
|
||||||
@import "loader.css";
|
@import "tailwindcss/components";
|
||||||
@import "tooltip.css";
|
@import "tailwindcss/utilities";
|
||||||
@import "flatpickr.css";
|
|
||||||
|
|
||||||
[x-cloak] { display: none; }
|
[x-cloak] { display: none; }
|
||||||
|
|
||||||
@ -65,8 +64,6 @@ blockquote {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@tailwind utilities;
|
|
||||||
|
|
||||||
|
|
||||||
.light-text {
|
.light-text {
|
||||||
color: #F0F4F8;
|
color: #F0F4F8;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import "../css/app.css"
|
|
||||||
import "flatpickr/dist/flatpickr.min.css"
|
|
||||||
import "./polyfills/closest"
|
import "./polyfills/closest"
|
||||||
|
import "./apply-theme"
|
||||||
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
|
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
|
||||||
import Alpine from 'alpinejs'
|
import Alpine from 'alpinejs'
|
||||||
import "./liveview/live_socket"
|
import "./liveview/live_socket"
|
||||||
|
@ -2,10 +2,10 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import 'url-search-params-polyfill';
|
import 'url-search-params-polyfill';
|
||||||
|
|
||||||
import Router from './router'
|
import Router from './dashboard/router'
|
||||||
import ErrorBoundary from './error-boundary'
|
import ErrorBoundary from './dashboard/error-boundary'
|
||||||
import * as api from './api'
|
import * as api from './dashboard/api'
|
||||||
import * as timer from './util/realtime-update-timer'
|
import * as timer from './dashboard/util/realtime-update-timer'
|
||||||
|
|
||||||
timer.start()
|
timer.start()
|
||||||
|
|
@ -12,7 +12,7 @@ import Devices from './stats/devices'
|
|||||||
import Behaviours from './stats/behaviours'
|
import Behaviours from './stats/behaviours'
|
||||||
import ComparisonInput from './comparison-input'
|
import ComparisonInput from './comparison-input'
|
||||||
import { withPinnedHeader } from './pinned-header-hoc';
|
import { withPinnedHeader } from './pinned-header-hoc';
|
||||||
import { statsBoxClass } from '.';
|
import { statsBoxClass } from './index';
|
||||||
|
|
||||||
function Historical(props) {
|
function Historical(props) {
|
||||||
const tooltipBoundary = React.useRef(null)
|
const tooltipBoundary = React.useRef(null)
|
||||||
|
@ -10,7 +10,7 @@ import Locations from './stats/locations'
|
|||||||
import Devices from './stats/devices'
|
import Devices from './stats/devices'
|
||||||
import Behaviours from './stats/behaviours'
|
import Behaviours from './stats/behaviours'
|
||||||
import { withPinnedHeader } from './pinned-header-hoc';
|
import { withPinnedHeader } from './pinned-header-hoc';
|
||||||
import { statsBoxClass } from '.';
|
import { statsBoxClass } from './index';
|
||||||
|
|
||||||
class Realtime extends React.Component {
|
class Realtime extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
|
12955
assets/package-lock.json
generated
@ -3,17 +3,12 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"deploy": "webpack --mode production",
|
|
||||||
"watch": "webpack --mode development --watch",
|
|
||||||
"format": "prettier --write {css,js}/**",
|
"format": "prettier --write {css,js}/**",
|
||||||
"check-format": "prettier --check {css,js}/**",
|
"check-format": "prettier --check {css,js}/**",
|
||||||
"lint": "eslint js/**",
|
"lint": "eslint js/**",
|
||||||
"bundlemon": "bundlemon"
|
"bundlemon": "bundlemon"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.14.3",
|
|
||||||
"@babel/preset-env": "^7.14.4",
|
|
||||||
"@babel/preset-react": "^7.13.13",
|
|
||||||
"@headlessui/react": "^1.7.10",
|
"@headlessui/react": "^1.7.10",
|
||||||
"@heroicons/react": "^2.0.11",
|
"@heroicons/react": "^2.0.11",
|
||||||
"@juggle/resize-observer": "^3.3.1",
|
"@juggle/resize-observer": "^3.3.1",
|
||||||
@ -24,24 +19,16 @@
|
|||||||
"@tailwindcss/typography": "^0.4.1",
|
"@tailwindcss/typography": "^0.4.1",
|
||||||
"abortcontroller-polyfill": "^1.7.3",
|
"abortcontroller-polyfill": "^1.7.3",
|
||||||
"alpinejs": "^3.13.1",
|
"alpinejs": "^3.13.1",
|
||||||
"autoprefixer": "^10.4.15",
|
|
||||||
"babel-loader": "^8.2.2",
|
|
||||||
"chart.js": "^3.3.2",
|
"chart.js": "^3.3.2",
|
||||||
"chartjs-plugin-datalabels": "^2.2.0",
|
"chartjs-plugin-datalabels": "^2.2.0",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"copy-webpack-plugin": "^9.0.0",
|
|
||||||
"css-loader": "^5.2.6",
|
|
||||||
"css-minimizer-webpack-plugin": "^3.2.0",
|
|
||||||
"datamaps": "^0.5.9",
|
"datamaps": "^0.5.9",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"debounce-promise": "^3.1.2",
|
"debounce-promise": "^3.1.2",
|
||||||
"iframe-resizer": "^4.3.2",
|
"iframe-resizer": "^4.3.2",
|
||||||
"mini-css-extract-plugin": "^1.6.0",
|
|
||||||
"phoenix": "^1.7.2",
|
"phoenix": "^1.7.2",
|
||||||
"phoenix_html": "^3.3.1",
|
"phoenix_html": "^3.3.1",
|
||||||
"phoenix_live_view": "^0.18.18",
|
"phoenix_live_view": "^0.18.18",
|
||||||
"postcss": "^8.4.31",
|
|
||||||
"postcss-loader": "^6.1.1",
|
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-flatpickr": "3.10.5",
|
"react-flatpickr": "3.10.5",
|
||||||
@ -50,15 +37,10 @@
|
|||||||
"react-popper": "^2.3.0",
|
"react-popper": "^2.3.0",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-transition-group": "^4.4.2",
|
"react-transition-group": "^4.4.2",
|
||||||
"tailwindcss": "^3.3.3",
|
"url-search-params-polyfill": "^8.1.1"
|
||||||
"terser-webpack-plugin": "^5.1.2",
|
|
||||||
"url-search-params-polyfill": "^8.1.1",
|
|
||||||
"webpack": "5.88.1",
|
|
||||||
"webpack-cli": "^4.7.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"bundlemon": "^1.4.0",
|
|
||||||
"eslint": "^7.2.0",
|
"eslint": "^7.2.0",
|
||||||
"eslint-config-prettier": "^7.0.0",
|
"eslint-config-prettier": "^7.0.0",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
@ -68,8 +50,7 @@
|
|||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.2.0",
|
||||||
"stylelint": "^14.1.0",
|
"stylelint": "^14.1.0",
|
||||||
"stylelint-config-prettier": "^9.0.3",
|
"stylelint-config-prettier": "^9.0.3",
|
||||||
"stylelint-config-standard": "^24.0.0",
|
"stylelint-config-standard": "^24.0.0"
|
||||||
"webpack-bundle-analyzer": "^4.4.2"
|
|
||||||
},
|
},
|
||||||
"name": "assets"
|
"name": "assets"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
plugins: {
|
|
||||||
tailwindcss: {},
|
|
||||||
autoprefixer: {},
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 8.1 KiB |
@ -3,11 +3,9 @@ const plugin = require('tailwindcss/plugin')
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: [
|
content: [
|
||||||
'./js/**/*.js',
|
"./js/**/*.js",
|
||||||
'../lib/plausible_web/templates/**/*.html.eex',
|
"../lib/*_web.ex",
|
||||||
'../lib/plausible_web/templates/**/*.html.heex',
|
"../lib/*_web/**/*.*ex"
|
||||||
'../lib/plausible_web/live/**/*.ex',
|
|
||||||
'../lib/plausible_web/components/**/*.ex',
|
|
||||||
],
|
],
|
||||||
safelist: [
|
safelist: [
|
||||||
// PlausibleWeb.StatsView.stats_container_class/1 uses this class
|
// PlausibleWeb.StatsView.stats_container_class/1 uses this class
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
const path = require('path');
|
|
||||||
const webpack = require('webpack');
|
|
||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
||||||
const TerserPlugin = require('terser-webpack-plugin');
|
|
||||||
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
|
|
||||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
||||||
|
|
||||||
module.exports = (env, options) => ({
|
|
||||||
optimization: {
|
|
||||||
minimizer: [
|
|
||||||
new TerserPlugin(),
|
|
||||||
new CssMinimizerWebpackPlugin()
|
|
||||||
]
|
|
||||||
},
|
|
||||||
entry: {
|
|
||||||
'app': ['./js/app.js'],
|
|
||||||
'dashboard': ['./js/dashboard/mount.js'],
|
|
||||||
'embed.host': ['./js/embed.host.js'],
|
|
||||||
'embed.content': ['./js/embed.content.js']
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
filename: '[name].js',
|
|
||||||
path: path.resolve(__dirname, '../priv/static/js')
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.(js|jsx)$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
use: {
|
|
||||||
loader: 'babel-loader'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.css$/,
|
|
||||||
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
externals: { moment: 'moment' },
|
|
||||||
plugins: [
|
|
||||||
new MiniCssExtractPlugin({filename: '../css/[name].css'}),
|
|
||||||
new CopyWebpackPlugin({patterns: [{from: 'static/', to: '../' }]}),
|
|
||||||
new webpack.ProvidePlugin({
|
|
||||||
ResizeObserver: ['@juggle/resize-observer', 'ResizeObserver'] // https://caniuse.com/?search=ResizeObserver
|
|
||||||
})
|
|
||||||
]
|
|
||||||
});
|
|
@ -21,6 +21,26 @@ config :logger, :console,
|
|||||||
# Use Jason for JSON parsing in Phoenix
|
# Use Jason for JSON parsing in Phoenix
|
||||||
config :phoenix, :json_library, Jason
|
config :phoenix, :json_library, Jason
|
||||||
|
|
||||||
|
config :esbuild,
|
||||||
|
version: "0.17.11",
|
||||||
|
default: [
|
||||||
|
args:
|
||||||
|
~w(js/app.js js/dashboard.js js/embed.host.js js/embed.content.js --bundle --target=es2017 --loader:.js=jsx --outdir=../priv/static/js),
|
||||||
|
cd: Path.expand("../assets", __DIR__),
|
||||||
|
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
|
||||||
|
]
|
||||||
|
|
||||||
|
config :tailwind,
|
||||||
|
version: "3.3.3",
|
||||||
|
default: [
|
||||||
|
args: ~w(
|
||||||
|
--config=tailwind.config.js
|
||||||
|
--input=css/app.css
|
||||||
|
--output=../priv/static/css/app.css
|
||||||
|
),
|
||||||
|
cd: Path.expand("../assets", __DIR__)
|
||||||
|
]
|
||||||
|
|
||||||
config :ua_inspector,
|
config :ua_inspector,
|
||||||
database_path: "priv/ua_inspector",
|
database_path: "priv/ua_inspector",
|
||||||
remote_release: "66d80de32fbb265941f4d7941fadc19097375097"
|
remote_release: "66d80de32fbb265941f4d7941fadc19097375097"
|
||||||
|
@ -6,14 +6,8 @@ config :plausible, PlausibleWeb.Endpoint,
|
|||||||
code_reloader: true,
|
code_reloader: true,
|
||||||
check_origin: false,
|
check_origin: false,
|
||||||
watchers: [
|
watchers: [
|
||||||
node: [
|
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]},
|
||||||
"node_modules/webpack/bin/webpack.js",
|
tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]},
|
||||||
"--mode",
|
|
||||||
"development",
|
|
||||||
"--watch",
|
|
||||||
"--watch-options-stdin",
|
|
||||||
cd: Path.expand("../assets", __DIR__)
|
|
||||||
],
|
|
||||||
npm: [
|
npm: [
|
||||||
"run",
|
"run",
|
||||||
"deploy",
|
"deploy",
|
||||||
@ -23,12 +17,7 @@ config :plausible, PlausibleWeb.Endpoint,
|
|||||||
live_reload: [
|
live_reload: [
|
||||||
patterns: [
|
patterns: [
|
||||||
~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
|
~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
|
||||||
~r{lib/plausible_web/views/.*(ex)$},
|
~r"lib/plausible_web/(controllers|live|components|templates|views|plugs)/.*(ex|heex)$"
|
||||||
~r{lib/plausible_web/templates/.*(eex)$},
|
|
||||||
~r{lib/plausible_web/templates/.*(heex)$},
|
|
||||||
~r{lib/plausible_web/controllers/.*(ex)$},
|
|
||||||
~r{lib/plausible_web/plugs/.*(ex)$},
|
|
||||||
~r{lib/plausible_web/live/.*(ex)$}
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ defmodule PlausibleWeb.Endpoint do
|
|||||||
at: "/",
|
at: "/",
|
||||||
from: :plausible,
|
from: :plausible,
|
||||||
gzip: false,
|
gzip: false,
|
||||||
only: ~w(css images js favicon.ico robots.txt)
|
only: ~w(css js images favicon.ico robots.txt)
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(Plug.Static,
|
plug(Plug.Static,
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
<title><%= assigns[:title] || "Plausible · Simple, privacy-friendly alternative to Google Analytics" %></title>
|
<title><%= assigns[:title] || "Plausible · Simple, privacy-friendly alternative to Google Analytics" %></title>
|
||||||
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
|
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
|
||||||
<%= render("_tracking.html", assigns) %>
|
<%= render("_tracking.html", assigns) %>
|
||||||
<script type="text/javascript" data-pref="<%= @conn.assigns[:theme] || (@conn.assigns[:current_user] && @conn.assigns[:current_user].theme) %>" src="<%= Routes.static_path(@conn, "/js/applyTheme.js") %>"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body class="flex flex-col bg-gray-50 dark:bg-gray-850" style="<%= if !@conn.assigns[:embedded], do: "height: 100%;" %> <%= if @conn.assigns[:background], do: "background-color: #{@conn.assigns[:background]}" %>">
|
<body class="flex flex-col bg-gray-50 dark:bg-gray-850" style="<%= if !@conn.assigns[:embedded], do: "height: 100%;" %> <%= if @conn.assigns[:background], do: "background-color: #{@conn.assigns[:background]}" %>">
|
||||||
<%= if !@conn.assigns[:embedded] do %>
|
<%= if !@conn.assigns[:embedded] do %>
|
||||||
@ -33,6 +32,6 @@
|
|||||||
<% else %>
|
<% else %>
|
||||||
<%= render("_footer.html", assigns) %>
|
<%= render("_footer.html", assigns) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
|
<script type="text/javascript" data-pref="<%= @conn.assigns[:theme] || (@conn.assigns[:current_user] && @conn.assigns[:current_user].theme) %>" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
<title><%= assigns[:title] || "Plausible · Web analytics" %></title>
|
<title><%= assigns[:title] || "Plausible · Web analytics" %></title>
|
||||||
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
|
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
|
||||||
<%= render("_tracking.html", assigns) %>
|
<%= render("_tracking.html", assigns) %>
|
||||||
<script type="text/javascript" data-pref="<%= @conn.assigns[:current_user] && @conn.assigns[:current_user].theme %>" src="<%= Routes.static_path(@conn, "/js/applyTheme.js") %>"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body class="flex flex-col h-full bg-gray-100 dark:bg-gray-900">
|
<body class="flex flex-col h-full bg-gray-100 dark:bg-gray-900">
|
||||||
<div class="w-full my-8 text-center">
|
<div class="w-full my-8 text-center">
|
||||||
@ -34,6 +33,6 @@
|
|||||||
© <%= DateTime.utc_now().year() %> Plausible Analytics. All rights reserved.
|
© <%= DateTime.utc_now().year() %> Plausible Analytics. All rights reserved.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
|
<script type="text/javascript" data-pref="<%= @conn.assigns[:theme] || (@conn.assigns[:current_user] && @conn.assigns[:current_user].theme) %>" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
10
mix.exs
@ -124,16 +124,22 @@ defmodule Plausible.MixProject do
|
|||||||
{:zxcvbn, git: "https://github.com/techgaun/zxcvbn-elixir.git"},
|
{:zxcvbn, git: "https://github.com/techgaun/zxcvbn-elixir.git"},
|
||||||
{:open_api_spex, "~> 3.18"},
|
{:open_api_spex, "~> 3.18"},
|
||||||
{:joken, "~> 2.5"},
|
{:joken, "~> 2.5"},
|
||||||
{:paginator, git: "https://github.com/duffelhq/paginator.git"}
|
{:paginator, git: "https://github.com/duffelhq/paginator.git"},
|
||||||
|
{:esbuild, "~> 0.7", runtime: Mix.env() == :dev},
|
||||||
|
{:tailwind, "~> 0.2.0", runtime: Mix.env() == :dev}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
defp aliases do
|
defp aliases do
|
||||||
[
|
[
|
||||||
|
setup: ["deps.get", "ecto.setup", "assets.setup", "assets.build"],
|
||||||
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
|
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
|
||||||
"ecto.reset": ["ecto.drop", "ecto.setup"],
|
"ecto.reset": ["ecto.drop", "ecto.setup"],
|
||||||
test: ["ecto.create --quiet", "ecto.migrate", "test", "clean_clickhouse"],
|
test: ["ecto.create --quiet", "ecto.migrate", "test", "clean_clickhouse"],
|
||||||
sentry_recompile: ["compile", "deps.compile sentry --force"]
|
sentry_recompile: ["compile", "deps.compile sentry --force"],
|
||||||
|
"assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"],
|
||||||
|
"assets.build": ["tailwind default", "esbuild default"],
|
||||||
|
"assets.deploy": ["tailwind default --minify", "esbuild default --minify", "phx.digest"]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
3
mix.lock
@ -36,6 +36,7 @@
|
|||||||
"elixir_make": {:hex, :elixir_make, "0.7.6", "67716309dc5d43e16b5abbd00c01b8df6a0c2ab54a8f595468035a50189f9169", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5a0569756b0f7873a77687800c164cca6dfc03a09418e6fcf853d78991f49940"},
|
"elixir_make": {:hex, :elixir_make, "0.7.6", "67716309dc5d43e16b5abbd00c01b8df6a0c2ab54a8f595468035a50189f9169", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5a0569756b0f7873a77687800c164cca6dfc03a09418e6fcf853d78991f49940"},
|
||||||
"envy": {:hex, :envy, "1.1.1", "0bc9bd654dec24fcdf203f7c5aa1b8f30620f12cfb28c589d5e9c38fe1b07475", [:mix], [], "hexpm", "7061eb1a47415fd757145d8dec10dc0b1e48344960265cb108f194c4252c3a89"},
|
"envy": {:hex, :envy, "1.1.1", "0bc9bd654dec24fcdf203f7c5aa1b8f30620f12cfb28c589d5e9c38fe1b07475", [:mix], [], "hexpm", "7061eb1a47415fd757145d8dec10dc0b1e48344960265cb108f194c4252c3a89"},
|
||||||
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
||||||
|
"esbuild": {:hex, :esbuild, "0.7.1", "fa0947e8c3c3c2f86c9bf7e791a0a385007ccd42b86885e8e893bdb6631f5169", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "66661cdf70b1378ee4dc16573fcee67750b59761b2605a0207c267ab9d19f13c"},
|
||||||
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
|
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
|
||||||
"ex_cldr": {:hex, :ex_cldr, "2.37.2", "c45041534ec60af367c4c1af02a608576118044fe3c441c782fd424061d6b517", [:mix], [{:cldr_utils, "~> 2.21", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.19", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: true]}], "hexpm", "c8467b1d5080716ace6621703b6656cb2f9545572a54b341da900791a0cf92ba"},
|
"ex_cldr": {:hex, :ex_cldr, "2.37.2", "c45041534ec60af367c4c1af02a608576118044fe3c441c782fd424061d6b517", [:mix], [{:cldr_utils, "~> 2.21", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.19", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: true]}], "hexpm", "c8467b1d5080716ace6621703b6656cb2f9545572a54b341da900791a0cf92ba"},
|
||||||
"ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.15.0", "aadd34e91cfac7ef6b03fe8f47f8c6fa8c5daf3f89b5d9fee64ec545ded839cf", [:mix], [{:ex_cldr, "~> 2.34", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "0521316396c66877a2d636219767560bb2397c583341fcb154ecf9f3000e6ff8"},
|
"ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.15.0", "aadd34e91cfac7ef6b03fe8f47f8c6fa8c5daf3f89b5d9fee64ec545ded839cf", [:mix], [{:ex_cldr, "~> 2.34", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "0521316396c66877a2d636219767560bb2397c583341fcb154ecf9f3000e6ff8"},
|
||||||
@ -131,6 +132,8 @@
|
|||||||
"siphash": {:hex, :siphash, "3.2.0", "ec03fd4066259218c85e2a4b8eec4bb9663bc02b127ea8a0836db376ba73f2ed", [:make, :mix], [], "hexpm", "ba3810701c6e95637a745e186e8a4899087c3b079ba88fb8f33df054c3b0b7c3"},
|
"siphash": {:hex, :siphash, "3.2.0", "ec03fd4066259218c85e2a4b8eec4bb9663bc02b127ea8a0836db376ba73f2ed", [:make, :mix], [], "hexpm", "ba3810701c6e95637a745e186e8a4899087c3b079ba88fb8f33df054c3b0b7c3"},
|
||||||
"sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"},
|
"sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"},
|
||||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
|
||||||
|
"tailwind": {:hex, :tailwind, "0.2.1", "83d8eadbe71a8e8f67861fe7f8d51658ecfb258387123afe4d9dc194eddc36b0", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "e8a13f6107c95f73e58ed1b4221744e1eb5a093cd1da244432067e19c8c9a277"},
|
||||||
|
|
||||||
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
||||||
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
|
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
|
||||||
"telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.1.0", "4e15f6d7dbedb3a4e3aed2262b7e1407f166fcb9c30ca3f96635dfbbef99965c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0dd10e7fe8070095df063798f82709b0a1224c31b8baf6278b423898d591a069"},
|
"telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.1.0", "4e15f6d7dbedb3a4e3aed2262b7e1407f166fcb9c30ca3f96635dfbbef99965c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0dd10e7fe8070095df063798f82709b0a1224c31b8baf6278b423898d591a069"},
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |