CRITICAL: - Membership: remove :role/:org_id/:user_id from mass-assignment cast; use explicit create_changeset/4 and role_update_changeset/2 - GraphQL member resolver: add authorize_invite/3 checking admin/owner role and role hierarchy - REST invitations controller: add auth check for invite creation HIGH: - ApiToken: remove :organization_id/:user_id from cast; use explicit create_changeset/4 MEDIUM: - Move 8 LiveView Ecto queries into context modules (Admin, Alerts, Coverages, OnCall, Snmp) - Replace Process.put/Process.get with socket assigns for unresolved_alert_count (user_auth + layouts + 50 templates) - Add batch get_utilization_for_interfaces/1 to eliminate N+1 capacity queries in device show - Replace Process.sleep with Process.monitor/assert_receive or Process.send_after in 5 test files LOW: - Add handle_params/3 to UserResetPasswordLive, UserRegistrationLive, StatusPageLive - Remove redundant Repo.preload calls; add preloads to list_site_devices/1 - Fix @impl annotations and credo nesting warnings
43 lines
1.6 KiB
Text
43 lines
1.6 KiB
Text
<Layouts.authenticated
|
|
flash={@flash}
|
|
current_scope={@current_scope}
|
|
unresolved_alert_count={assigns[:unresolved_alert_count] || 0}
|
|
>
|
|
<.header>
|
|
{@page_title}
|
|
<:subtitle>{t("Create a new organization to manage your sites and devices")}</:subtitle>
|
|
</.header>
|
|
|
|
<%= if not @can_create_free do %>
|
|
<div class="max-w-2xl mb-6 rounded-lg bg-orange-50 dark:bg-orange-900/20 p-4 border border-orange-200 dark:border-orange-800">
|
|
<div class="flex">
|
|
<.icon name="hero-exclamation-triangle" class="h-5 w-5 text-orange-400" />
|
|
<div class="ml-3">
|
|
<h3 class="text-sm font-medium text-orange-800 dark:text-orange-400">
|
|
{t("Free organization limit reached")}
|
|
</h3>
|
|
<p class="mt-1 text-sm text-orange-700 dark:text-orange-300">
|
|
You already have {@free_org_count} free {if @free_org_count == 1,
|
|
do: "organization",
|
|
else: "organizations"}. {t(
|
|
"To create additional organizations, you'll need to upgrade your existing organization to a paid plan."
|
|
)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<div class="max-w-2xl">
|
|
<.form for={@form} id="organization-form" phx-change="validate" phx-submit="save">
|
|
<.input field={@form[:name]} type="text" label={t("Organization Name")} required />
|
|
|
|
<div class="flex gap-3 mt-6">
|
|
<.button phx-disable-with={t("Creating...")} variant="primary">
|
|
Create Organization
|
|
</.button>
|
|
<.button navigate={~p"/orgs"}>{t("Cancel")}</.button>
|
|
</div>
|
|
</.form>
|
|
</div>
|
|
</Layouts.authenticated>
|