This commit adds a UI setting that was accidentally lost from an
earlier PR.
It introduces `$utils.setPref()|getPref()` to save arbitrary key/value
preferences in a JSON blob under the app's namespace in localStorage.
The `rate` field `/api/campaigns/running/stats` returned was computed
based on the total time spent from the start of the campaign to the
current time. This meant that for large campaigns, if there were
pauses or slowdowns in between, the rate would be skewed heavily
making it useless to figure out the current send rate.
This commit introduces a realtime running rate counter in the campaign
manager that returns accurate (running) send rates for the last minute.
The `rate` field in the API now shows the live running rate and a
new `net_rate` field shows the rate from the beginning of the campaign.
- Change `query-lists` query to aggregate the subscriber count by
status (confirmed, unsubscribed etc.) and expose them under a new
`subscriber_statuses: {}` field in the `GET /lists` API.
- Display the statuses and counts in the lists table on the UI.
Closes#616
The analytics page showed non-unique counts for views and clicks which
was misleading and source of confusion: #522, #561, #571, #676, #680
This commit changes this behaviour to pull unique views and clicks when
individual subscriber tracking is turned on in settings, and non-unique
counts when it is turned off (as `subscriber_id` in `campaign_views`
and `link_clicks` will be NULL, rendering unique queries dysfunctional).
This commit changes the stats SQL queries to use string interpolation
to either to SELECT `*` or `DISTINCT subscriber_id` on app boot based
on the setting in the DB. This involves significant changes to how
queries are read and prepared on init.
- Refactor `initQueries()` to `readQueries()` and `prepareQueries()`.
- Read queries first before preparing.
- Load settings from the DB using the read settings query.
- Prepare queries next. Use the privacy setting from the DB to apply
string interpolation to the analytics queries to pull
unique/non-unique before preparing the queries.
On the UI:
- Show a note on the analytics page about unique/non-unique counts.
- Hide the % donut charts on the analytics page in non-unique mode.
Closes#676, closes#680
- Updating a subscriber no longer triggers an opt-in confirmation mail
as `POST /api/subscribers/:id/optin` allows that.
- A "Send opt-in confirmation" option is added to the subscriber
update UI.
Closes#656.
- Add new `headers[]` column to the campain table.
- Add new headers box to the campaign UI that takes a JSON array of
custom headers like the headers on the SMTP settings UI.
- Headers are added to e-mails and messenger postback webhooks.
- Add cypress tests.
Closes#514.
- Remove `humps` lib dependency with a new util function.
- Replace hacky way of excluding certain fields in responses with
a proper key filtering mechanism.
- Add support for TLS in `smtppool` (v0.4.0) and upgrade the lib.
- Change `tls_enabled: bool` in the settings table to string
`tls_type: STARTTLS|TLS|none` and on the settings UI.
- Add DB migrations and schema changes to apply the field change.
Closes#504.
This feature was originally authored by @sweetppro in PR #438.
However, since the PR ended up in an unclean state with
multiple master merges (instead of rebase) from the upstream, there are
several commits that are out of order and can can no longer be be
squashed for a clean feature merge.
This commit aggregates the changes from the original PR and applies the
following fixes on top of it.
- Add custom admin JS box to appearance UI.
- Refactor i18n language strings.
- Add handlers and migrations for the new `appearance.admin.custom_js`
field.
- Fix migration version to `v2.1.0`
- Load custom appearance CSS/JS bytes into global constants during boot
instead of making a DB call on every request.
- Fix and canonicalize URIs from `/api/custom*` to `/public/*.css`
and `/admin/*.css`. Add proxy paths to yarn proxy config.
- Remove redundant HTTP handlers for different custom appearance files
and refactor into a single handler `serveCustomApperance()`
- Fix content-type and UTF8 encoding headers for different file types.
- Fix incorrect registration of public facing custom CSS/JS handlers
in the authenticated admin URI group.
- Fix merge conflicts in `Settings.vue`.
- Minor HTML and style fixes.
- Remove the `AppearanceEditor` component and use the existing
`HTMLEditor` component instead.
- Add `language` prop to the `HTMLEditor` component.
Co-authored-by: SweetPPro <sweetppro@users.noreply.github.com>
- echo is now on v4 with major changes including a few breaking changes
- bind() behaviour is now strict. JSON / form etc. unmarshalling of
request data need appropriate `json`, `form` tags. Missing tags for
the public subscription page is added in this commit.
- This also closes#602.
* improved mobile navbar/sidebar
Sidebar is hidden and all menu items moved to hamburger menu on mobile devices
* improvements to menu rendering
-removed redundant code
-fixed an issue with emitting data to App.vue
* Update Navigation.vue
fixed linting errors
* Add minor refactors to the mobile menu PR.
- Fix indentation and line lengths.
- Simplify prop definitions in the Navigation component.
- Remove redundant computed methods and use prop variables directly in
the Navigation compontent.
- Simplify menu rendering logic by:
removing isSidebar, showLogout and using simpler v-if / else
in the parent instead of the Navigation component.
* Update App.vue
removed orphaned isSideBar Boolean
Co-authored-by: Kailash Nadh <kailash@nadh.in>
BasicAuth without an explicit landing page or a logout option has
sometimes been confusing to users. This commit adds a static
landing page on / with a login link and a logout option in the admin
that "logs out" BasicAuth session by posting invalid credentials to
the server to obtain a 401.
- Refactor codeflask HTML editor into a standalone html-editor
component.
- Replace the plaintext box in the template editor with html-editor.
- Replace codeflask in the campaign editor with the new html-editor.
- Refactor templates Cypress tests to test the new editor.
- Refactor campaigns Cypress tests to test the new editor and also
test switching between different editors and content formats.