Skip to content

Conversation

@aerosol
Copy link
Member

@aerosol aerosol commented Nov 4, 2025

Changes

This PR integrates consolidated view life cycle with billing properties.
It relies on two migrations (included here still), extracted to separate PRs:

Main changes:

  • new feature flag: :consolidated_view - we no longer display anything based on super_admin role; flag is not setup on production yet, meaning existing consolidated views will disappear (and no CTAs will be shown).
  • new billing feature: ConsolidatedView
  • all existing plans are updated, so that business tier includes the newly added features - either through static definitions or database migration
  • whenever /sites is visited an attempt is made to create consolidated view. If the team is eligible, and the feature flag is raised, the consolidated view card is shown. Otherwise a CTA card is displayed (courtesy of @sanne-san)
    • CTA card has several variants, depending on the context, but eventually leads to upgrade. Once the upgrade is performed, /sites will include the consolidated view card.
    • CTA card can be permanently dismissed per user and team; because local storage and cookies turned out to be very difficult to work with in this setup, the decision was made to introduce a new postgres table capable of storing user preferences in a team context (it's almost a 1:1 copy of the existing site user preferences table)
    • When CTA is dismissed, the "New Site" button becomes a prima drop-down (courtesy of @ukutaht) from which the user may restore it (by selecting "+ New consolidated view" dropdown item)
    • CRM now presents a more elaborate alert on deleting consolidated view, as well as the availability status (whether upgrade is required)
    • some minor improvements BTW:
      • shared links enforce regular sites,
      • accessing a consolidated view via pre-existing URL, while ineligible, redirects to /sites
      • at least 2 sites are now required to create (or even suggest) a consolidated view
      • ConsolidatedView.enabled?/1 has been removed, since enabling doesn't mean availability

TODO:

  • staging preview is currently unavailable due to pending migrations
  • there are visual issues with card plots and overlapping dropdowns
record-2025-11-10-10-29-34-year.node.norm.mp4
  • the dropdown doesn't respect dark mode
image

Tests

  • Automated tests have been added
  • This PR does not require tests

Changelog

  • Entry has been added to changelog
  • This PR does not make a user-facing change

Documentation

  • Docs have been updated
  • This change does not need a documentation update

Dark mode

  • The UI has been tested both in dark and light mode
  • This PR does not change the UI

@aerosol aerosol force-pushed the consolidated-view-billing branch 2 times, most recently from ea6644d to b1e1b17 Compare November 10, 2025 10:10
@aerosol aerosol force-pushed the consolidated-view-billing branch from 2fa36cd to 1b9decd Compare November 10, 2025 12:40
aerosol and others added 5 commits November 10, 2025 13:46
 - add functions to manipulate user/team options (for CTA)
 - require at least two sites in order to create a consolidated view
 - require billing/plan compliance when computing eligibility
Co-authored-by: Sanne de Vries <[email protected]>
Co-authored-by: Uku Taht <[email protected]>
- require team-wise feature flag instead of super admin role
- redirect to /sites if the team isn't eligible any more
- enforce regular site in shared links controller
@aerosol aerosol force-pushed the consolidated-view-billing branch from 1b9decd to 87e593f Compare November 10, 2025 12:46
@aerosol aerosol force-pushed the consolidated-view-billing branch from 64760be to 2ae4797 Compare November 10, 2025 12:53
@aerosol aerosol changed the title [wip] Consolidated View: billing integration Consolidated View life cycle + billing integration Nov 10, 2025
@aerosol aerosol added preview and removed preview labels Nov 10, 2025
@plausible plausible deleted a comment from github-actions bot Nov 10, 2025
@aerosol aerosol marked this pull request as ready for review November 10, 2025 13:37
Copy link
Contributor

@RobertJoonas RobertJoonas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff, looks great overall! A few comments inline.

end

def upgrade_card(assigns) do
def consolidated_view_card_cta(assigns) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a slight UI annoyance I'm seeing locally. Try to hide the CTA card, then navigate to another page, e.g. click on one of the site cards to see a dashboard. Now, hit back in the browser history. The card flickers for a second and then disappears. Same happens when you've hidden it before and then restore it.

We should make sure that hiding/restoring the card also updates the entry in browser history stack.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

phoenixframework/phoenix_live_view#3508 looks like a similar issue and from what I see it was tricky to address and I'm not event sure it got fully resolved?

<div :if={@has_sites?}>
<ul class="my-6 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
<!-- Insert upgrade_card here -->
<.consolidated_view_card_cta
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see if I can extract this to a separate component and maybe even extract the state management out of here. It's getting really noisy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving conditional expressions to the start of render and assigning them to something like show_consolidated_view_cta? and show_consolidated_view? might help clean it up as well.

@sanne-san sanne-san force-pushed the consolidated-view-billing branch from 557d2e8 to f2b5a2d Compare November 11, 2025 11:46
Copy link
Contributor

@zoldar zoldar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

God's work 🙏 Left some feedback, most of it just nice-to-haves. Keeping preferences on membership instead of team/user combo makes more sense to me.

EDIT: Oh, and one more thing I've noted and then forgot about. Perhaps ConslidatedView.reset_if_enabled could be turned into an upsert? That would pair well with disable which is resilient to the view struct getting stale already.

<Heroicons.cog_6_tooth class="hidden group-hover:inline size-5 dark:text-gray-100 text-gray-900" />
</.unstyled_link>
</h2>
<.unstyled_link
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a good opportunity to use icon_button component, which was recently introduced? 😄 Though it might require introducing one more theme.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hrm @sanne-san do you think it's something we should do in this context?

<div :if={@has_sites?}>
<ul class="my-6 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
<!-- Insert upgrade_card here -->
<.consolidated_view_card_cta
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving conditional expressions to the start of render and assigning them to something like show_consolidated_view_cta? and show_consolidated_view? might help clean it up as well.

end

def upgrade_card(assigns) do
def consolidated_view_card_cta(assigns) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

phoenixframework/phoenix_live_view#3508 looks like a similar issue and from what I see it was tricky to address and I'm not event sure it got fully resolved?

@github-actions
Copy link

Preview environment👷🏼‍♀️🏗️
PR-5866

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants