Chunk 1 of the on-call/escalation redesign plan (docs/plans/2026-04-28-on-call-pagerduty-style-redesign.md): Schema - on_call.ex: list_devices_using_policy/2 (direct + org-default inheritance) - on_call.ex: move_escalation_rule/2 for up/down level reordering - list_escalation_policies/1 now preloads :rules Show page - Levels rendered as numbered cards with up/down/delete controls - "Notify the following users immediately and escalate after N minutes." - REPEAT footer surfaces repeat_count inline (no longer a standalone column) - Right-side Services sidebar lists devices using the policy - Header line shows the handoff notifications mode (when in use by a service / always / never) Edit form - Removed standalone Repeat Count input - Added handoff notifications mode select - Added inline "If no one acknowledges, repeat this policy N time(s)" block Index views (policies tab + standalone) - Replaced Repeat Count column with a Levels (rule count) column Other - rate_limit.ex: bind unmatched :ets.new/2 + schedule_clean/1 returns to fix dialyzer :unmatched_returns warning under the project's strict flags. All 10,191 tests pass; mix format clean; mix compile --warnings-as-errors clean; mix dialyzer passes.
57 lines
2 KiB
Text
57 lines
2 KiB
Text
<Layouts.authenticated
|
|
flash={@flash}
|
|
current_scope={@current_scope}
|
|
active_page="schedules"
|
|
>
|
|
<div class="flex items-center gap-3 mb-6">
|
|
<.link
|
|
navigate={~p"/schedules?tab=escalation-policies"}
|
|
class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
|
|
>
|
|
<.icon name="hero-arrow-left" class="h-5 w-5" />
|
|
</.link>
|
|
<h1 class="text-xl font-bold text-gray-900 dark:text-white">{@page_title}</h1>
|
|
</div>
|
|
|
|
<div class="max-w-2xl">
|
|
<.form for={@form} phx-change="validate" phx-submit="save" class="space-y-6">
|
|
<div>
|
|
<.input field={@form[:name]} type="text" label={t("Name")} required />
|
|
</div>
|
|
<div>
|
|
<.input field={@form[:description]} type="textarea" label={t("Description")} />
|
|
</div>
|
|
<div>
|
|
<.input
|
|
field={@form[:handoff_notifications_mode]}
|
|
type="select"
|
|
label={t("Send On-Call Handoff Notifications")}
|
|
options={[
|
|
{t("When in use by a service"), "when_in_use_by_service"},
|
|
{t("Always"), "always"},
|
|
{t("Never"), "never"}
|
|
]}
|
|
/>
|
|
</div>
|
|
<div class="rounded-lg border border-gray-200 dark:border-white/10 p-4 flex items-center gap-3">
|
|
<.icon name="hero-arrow-path" class="h-5 w-5 text-gray-500" />
|
|
<span class="text-sm text-gray-700 dark:text-gray-300">
|
|
{t("If no one acknowledges, repeat this policy")}
|
|
</span>
|
|
<.input field={@form[:repeat_count]} type="number" min="1" max="10" class="w-20" />
|
|
<span class="text-sm text-gray-700 dark:text-gray-300">{t("time(s).")}</span>
|
|
</div>
|
|
<div class="flex items-center gap-3">
|
|
<.button type="submit" phx-disable-with={t("Saving...")}>
|
|
{t("Save Policy")}
|
|
</.button>
|
|
<.link
|
|
navigate={~p"/schedules?tab=escalation-policies"}
|
|
class="text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"
|
|
>
|
|
{t("Cancel")}
|
|
</.link>
|
|
</div>
|
|
</.form>
|
|
</div>
|
|
</Layouts.authenticated>
|