deps: bump oban 2.22.0 → 2.22.1, oban_web (vendored) 2.12.1 → 2.12.3
Latest-version sweep across the Oban stack. Final state: oban 2.22.1 (hexpm) oban_pro 1.7.0 (vendored, latest in licensed repo) oban_met 1.1.0 (vendored, latest in licensed repo and hexpm) oban_web 2.12.3 (vendored from public hexpm) oban_web was re-vendored via `mix hex.package fetch oban_web 2.12.3 --unpack` and dropped into vendor/oban_web. No local mods to preserve — vendor commit history shows the dir was a vanilla import.
2
mix.lock
|
|
@ -41,7 +41,7 @@
|
||||||
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
||||||
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
|
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
|
||||||
"nx": {:hex, :nx, "0.11.0", "d37723dbd6cfa274a5def6d6664f5680c32e2eb8a1ce25ec6d91751967fa0abf", [:mix], [{:complex, "~> 0.6", [hex: :complex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "36157b21239aeb251d6cbac23eb0eb3495a5e1e0cbc2e6df16afd2ede1575205"},
|
"nx": {:hex, :nx, "0.11.0", "d37723dbd6cfa274a5def6d6664f5680c32e2eb8a1ce25ec6d91751967fa0abf", [:mix], [{:complex, "~> 0.6", [hex: :complex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "36157b21239aeb251d6cbac23eb0eb3495a5e1e0cbc2e6df16afd2ede1575205"},
|
||||||
"oban": {:hex, :oban, "2.22.0", "d50fb8be22a58ca8839dbc69610e271773d851b7deae01acd8b62e7197bcd318", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.20", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6675164c11eadd82044732dd7b6e448aa6d6f429a41a1e7d6dbf5fd358f52f26"},
|
"oban": {:hex, :oban, "2.22.1", "9d2a38cec95070b31c1e274fae55f3925089f62159d8f3facabee0454d55b257", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.20", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "af2508c156c5b0ec30b21b0883babf7e2716af35ed5d264095896103fe3cea37"},
|
||||||
"octo_fetch": {:hex, :octo_fetch, "0.5.0", "f50701568b9fc752656367f82cc134d5fbefff37c5a0e8ddfcceb02ceee3f5fc", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "6226cc3c14ca948ee9f25fb0446322e5c288e215da9beba7899b6b5f4cd3ccb0"},
|
"octo_fetch": {:hex, :octo_fetch, "0.5.0", "f50701568b9fc752656367f82cc134d5fbefff37c5a0e8ddfcceb02ceee3f5fc", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "6226cc3c14ca948ee9f25fb0446322e5c288e215da9beba7899b6b5f4cd3ccb0"},
|
||||||
"owl": {:hex, :owl, "0.13.0", "26010e066d5992774268f3163506972ddac0a7e77bfe57fa42a250f24d6b876e", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "59bf9d11ce37a4db98f57cb68fbfd61593bf419ec4ed302852b6683d3d2f7475"},
|
"owl": {:hex, :owl, "0.13.0", "26010e066d5992774268f3163506972ddac0a7e77bfe57fa42a250f24d6b876e", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "59bf9d11ce37a4db98f57cb68fbfd61593bf419ec4ed302852b6683d3d2f7475"},
|
||||||
"peep": {:hex, :peep, "3.5.0", "9f6ead7b0f2c684494200c8fc02e7e62e8c459afe861b29bd859e4c96f402ed8", [:mix], [{:nimble_options, "~> 1.1", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:plug, "~> 1.16", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry_metrics, "~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5a73a99c6e60062415efeb7e536a663387146463a3d3df1417da31fd665ac210"},
|
"peep": {:hex, :peep, "3.5.0", "9f6ead7b0f2c684494200c8fc02e7e62e8c459afe861b29bd859e4c96f402ed8", [:mix], [{:nimble_options, "~> 1.1", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:plug, "~> 1.16", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry_metrics, "~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5a73a99c6e60062415efeb7e536a663387146463a3d3df1417da31fd665ac210"},
|
||||||
|
|
|
||||||
BIN
vendor/oban_web/.hex
vendored
43
vendor/oban_web/CHANGELOG.md
vendored
|
|
@ -15,7 +15,8 @@ workflow progress, activity counts, duration, and nested sub-workflows. Workflow
|
||||||
by properties like name, workers, or status.
|
by properties like name, workers, or status.
|
||||||
|
|
||||||
<video autoplay loop muted playsinline loading="lazy" preload="none" style="width: 100%; border-radius: 12px;">
|
<video autoplay loop muted playsinline loading="lazy" preload="none" style="width: 100%; border-radius: 12px;">
|
||||||
<source src="https://media.oban.pro/web-2-12-workflows-av1.mp4" type="video/mp4">
|
<source src="https://media.oban.pro/web-2-12-workflows-av1.mp4" type="video/mp4" codecs="av01">
|
||||||
|
<source src="https://media.oban.pro/web-2-12-workflows.mp4" type="video/mp4">
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
Clicking into a workflow brings you to a detail view with an interactive graph showing jobs as
|
Clicking into a workflow brings you to a detail view with an interactive graph showing jobs as
|
||||||
|
|
@ -34,7 +35,8 @@ There's also a new page for viewing and managing cron entries. The table display
|
||||||
dynamic entries with history sparklines and activity details.
|
dynamic entries with history sparklines and activity details.
|
||||||
|
|
||||||
<video autoplay loop muted playsinline loading="lazy" preload="none" style="width: 100%; border-radius: 12px;">
|
<video autoplay loop muted playsinline loading="lazy" preload="none" style="width: 100%; border-radius: 12px;">
|
||||||
<source src="https://media.oban.pro/web-2-12-crons-av1.mp4" type="video/mp4">
|
<source src="https://media.oban.pro/web-2-12-crons-av1.mp4" type="video/mp4" codecs="av01">
|
||||||
|
<source src="https://media.oban.pro/web-2-12-crons.mp4" type="video/mp4">
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
The cron detail view includes natural language expressions like "Daily at 8:00 and 9:00" or
|
The cron detail view includes natural language expressions like "Daily at 8:00 and 9:00" or
|
||||||
|
|
@ -49,7 +51,8 @@ The job detail page is rebuilt with a full-width layout and a new timeline compo
|
||||||
the job state machine as a branching diagram rather than a linear progression.
|
the job state machine as a branching diagram rather than a linear progression.
|
||||||
|
|
||||||
<video autoplay loop muted playsinline loading="lazy" preload="none" style="width: 100%; border-radius: 12px;">
|
<video autoplay loop muted playsinline loading="lazy" preload="none" style="width: 100%; border-radius: 12px;">
|
||||||
<source src="https://media.oban.pro/web-2-12-jobs-details-av1.mp4" type="video/mp4">
|
<source src="https://media.oban.pro/web-2-12-jobs-details-av1.mp4" type="video/mp4" codecs="av01">
|
||||||
|
<source src="https://media.oban.pro/web-2-12-jobs-details.mp4" type="video/mp4">
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
A scoped chart displays execution history for that worker's previous jobs and jobs in an
|
A scoped chart displays execution history for that worker's previous jobs and jobs in an
|
||||||
|
|
@ -66,13 +69,45 @@ throughput for each queue. The queue sidebar provided minimal value, and it was
|
||||||
room for the additional data displayed per-row.
|
room for the additional data displayed per-row.
|
||||||
|
|
||||||
<video autoplay loop muted playsinline loading="lazy" preload="none" style="width: 100%; border-radius: 12px;">
|
<video autoplay loop muted playsinline loading="lazy" preload="none" style="width: 100%; border-radius: 12px;">
|
||||||
<source src="https://media.oban.pro/web-2-12-queues-av1.mp4" type="video/mp4">
|
<source src="https://media.oban.pro/web-2-12-queues-av1.mp4" type="video/mp4" codecs="av01">
|
||||||
|
<source src="https://media.oban.pro/web-2-12-queues.mp4" type="video/mp4">
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
The queue detail page adds status badges for paused, partial, and terminating states, with
|
The queue detail page adds status badges for paused, partial, and terminating states, with
|
||||||
pause/resume, stop, and edit buttons in the header. Partitioning controls are expanded with meta
|
pause/resume, stop, and edit buttons in the header. Partitioning controls are expanded with meta
|
||||||
options and burst mode configuration.
|
options and burst mode configuration.
|
||||||
|
|
||||||
|
## v2.12.3 - 2026-04-15
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- [Dashboard] Switch icons from inline SVG to CSS masks
|
||||||
|
|
||||||
|
CSP doesn't allow inline styles, which includes the url-masks that our app was using for icons.
|
||||||
|
This removes the icons/asset pipeline in favor of the standard Tailwind plugin approach used by
|
||||||
|
modern Phoenix apps
|
||||||
|
|
||||||
|
## v2.12.2 - 2026-03-31
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
- [Jobs] Allow editing jobs in any state except `executing`
|
||||||
|
|
||||||
|
`Oban.update_job/3` allows editing any non-executing job, so the detail component's edit form
|
||||||
|
should as well.
|
||||||
|
|
||||||
|
- [Standalone] Ship inetrc in standalone Docker image for native DNS resolution (#173)
|
||||||
|
|
||||||
|
The BEAM VM's built-in DNS resolver ignores `/etc/resolv.conf`, which prevents the standalone
|
||||||
|
image from resolving internal hostnames on platforms like Fly.io and Kubernetes with CoreDNS.
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- [Query] Prevent table check with non-PostgreSQL engines
|
||||||
|
|
||||||
|
The crons and workflows table checks only apply to Pro, and only Postgres engines should check
|
||||||
|
whether the tables exist.
|
||||||
|
|
||||||
## v2.12.1 - 2026-03-25
|
## v2.12.1 - 2026-03-25
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
|
||||||
78
vendor/oban_web/hex_metadata.config
vendored
|
|
@ -4,7 +4,7 @@
|
||||||
<<"https://github.com/oban-bg/oban_web/blob/main/CHANGELOG.md">>},
|
<<"https://github.com/oban-bg/oban_web/blob/main/CHANGELOG.md">>},
|
||||||
{<<"GitHub">>,<<"https://github.com/oban-bg/oban_web">>}]}.
|
{<<"GitHub">>,<<"https://github.com/oban-bg/oban_web">>}]}.
|
||||||
{<<"name">>,<<"oban_web">>}.
|
{<<"name">>,<<"oban_web">>}.
|
||||||
{<<"version">>,<<"2.12.1">>}.
|
{<<"version">>,<<"2.12.3">>}.
|
||||||
{<<"description">>,<<"Dashboard for the Oban job orchestration framework">>}.
|
{<<"description">>,<<"Dashboard for the Oban job orchestration framework">>}.
|
||||||
{<<"elixir">>,<<"~> 1.15">>}.
|
{<<"elixir">>,<<"~> 1.15">>}.
|
||||||
{<<"files">>,
|
{<<"files">>,
|
||||||
|
|
@ -65,79 +65,9 @@
|
||||||
<<"lib/oban/web/helpers/queue_helper.ex">>,<<"lib/oban/web/assets.ex">>,
|
<<"lib/oban/web/helpers/queue_helper.ex">>,<<"lib/oban/web/assets.ex">>,
|
||||||
<<"lib/oban/web/search.ex">>,<<"lib/oban/web/exceptions.ex">>,
|
<<"lib/oban/web/search.ex">>,<<"lib/oban/web/exceptions.ex">>,
|
||||||
<<"lib/oban/web.ex">>,<<"priv/static">>,<<"priv/static/app.css">>,
|
<<"lib/oban/web.ex">>,<<"priv/static">>,<<"priv/static/app.css">>,
|
||||||
<<"priv/static/icons">>,<<"priv/static/icons/solid">>,
|
<<"priv/static/fonts">>,<<"priv/static/fonts/Inter.woff2">>,
|
||||||
<<"priv/static/icons/solid/pause-circle.svg">>,
|
<<"priv/static/app.js">>,<<"priv/timezones.txt">>,<<".formatter.exs">>,
|
||||||
<<"priv/static/icons/solid/play-circle.svg">>,
|
<<"mix.exs">>,<<"README.md">>,<<"CHANGELOG.md">>,<<"LICENSE.txt">>]}.
|
||||||
<<"priv/static/icons/solid/crossbones-circle.svg">>,
|
|
||||||
<<"priv/static/icons/special">>,<<"priv/static/icons/special/spinner.svg">>,
|
|
||||||
<<"priv/static/icons/outline">>,
|
|
||||||
<<"priv/static/icons/outline/arrow-top-right-on-square.svg">>,
|
|
||||||
<<"priv/static/icons/outline/queue-list.svg">>,
|
|
||||||
<<"priv/static/icons/outline/pause-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/computer-desktop.svg">>,
|
|
||||||
<<"priv/static/icons/outline/cog.svg">>,
|
|
||||||
<<"priv/static/icons/outline/play-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/x-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/square-2x2.svg">>,
|
|
||||||
<<"priv/static/icons/outline/no-symbol.svg">>,
|
|
||||||
<<"priv/static/icons/outline/chevron-down.svg">>,
|
|
||||||
<<"priv/static/icons/outline/adjustments-horizontal.svg">>,
|
|
||||||
<<"priv/static/icons/outline/power.svg">>,
|
|
||||||
<<"priv/static/icons/outline/cog-8-tooth.svg">>,
|
|
||||||
<<"priv/static/icons/outline/sparkles.svg">>,
|
|
||||||
<<"priv/static/icons/outline/chevron-up.svg">>,
|
|
||||||
<<"priv/static/icons/outline/table-cells.svg">>,
|
|
||||||
<<"priv/static/icons/outline/arrow-path.svg">>,
|
|
||||||
<<"priv/static/icons/outline/ellipsis-horizontal-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/chevron-right.svg">>,
|
|
||||||
<<"priv/static/icons/outline/clipboard.svg">>,
|
|
||||||
<<"priv/static/icons/outline/link.svg">>,
|
|
||||||
<<"priv/static/icons/outline/bars-arrow-down.svg">>,
|
|
||||||
<<"priv/static/icons/outline/arrow-right.svg">>,
|
|
||||||
<<"priv/static/icons/outline/pencil-square.svg">>,
|
|
||||||
<<"priv/static/icons/outline/bolt-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/arrow-turn-down-right.svg">>,
|
|
||||||
<<"priv/static/icons/outline/arrow-path-rounded.svg">>,
|
|
||||||
<<"priv/static/icons/outline/indeterminate.svg">>,
|
|
||||||
<<"priv/static/icons/outline/check.svg">>,
|
|
||||||
<<"priv/static/icons/outline/percent-square.svg">>,
|
|
||||||
<<"priv/static/icons/outline/rectangle-group.svg">>,
|
|
||||||
<<"priv/static/icons/outline/x-mark.svg">>,
|
|
||||||
<<"priv/static/icons/outline/info-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/arrow-right-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/check-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/camera.svg">>,
|
|
||||||
<<"priv/static/icons/outline/life-buoy.svg">>,
|
|
||||||
<<"priv/static/icons/outline/view-columns.svg">>,
|
|
||||||
<<"priv/static/icons/outline/bolt-slash.svg">>,
|
|
||||||
<<"priv/static/icons/outline/exclamation-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/play-pause-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/trash.svg">>,
|
|
||||||
<<"priv/static/icons/outline/hashtag.svg">>,
|
|
||||||
<<"priv/static/icons/outline/sun.svg">>,
|
|
||||||
<<"priv/static/icons/outline/bars-arrow-up.svg">>,
|
|
||||||
<<"priv/static/icons/outline/plus-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/user-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/user-group.svg">>,
|
|
||||||
<<"priv/static/icons/outline/clock.svg">>,
|
|
||||||
<<"priv/static/icons/outline/command-line.svg">>,
|
|
||||||
<<"priv/static/icons/outline/adjustments-vertical.svg">>,
|
|
||||||
<<"priv/static/icons/outline/question-mark-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/map-pin.svg">>,
|
|
||||||
<<"priv/static/icons/outline/globe.svg">>,
|
|
||||||
<<"priv/static/icons/outline/arrow-left.svg">>,
|
|
||||||
<<"priv/static/icons/outline/magnifying-glass.svg">>,
|
|
||||||
<<"priv/static/icons/outline/minus-circle.svg">>,
|
|
||||||
<<"priv/static/icons/outline/lock-closed.svg">>,
|
|
||||||
<<"priv/static/icons/outline/arrow-trending-down.svg">>,
|
|
||||||
<<"priv/static/icons/outline/chevron-left.svg">>,
|
|
||||||
<<"priv/static/icons/outline/moon.svg">>,
|
|
||||||
<<"priv/static/icons/outline/chart-bar-square.svg">>,
|
|
||||||
<<"priv/static/icons/outline/square-stack.svg">>,
|
|
||||||
<<"priv/static/icons/outline/calendar-days.svg">>,<<"priv/static/fonts">>,
|
|
||||||
<<"priv/static/fonts/Inter.woff2">>,<<"priv/static/app.js">>,
|
|
||||||
<<"priv/timezones.txt">>,<<".formatter.exs">>,<<"mix.exs">>,<<"README.md">>,
|
|
||||||
<<"CHANGELOG.md">>,<<"LICENSE.txt">>]}.
|
|
||||||
{<<"app">>,<<"oban_web">>}.
|
{<<"app">>,<<"oban_web">>}.
|
||||||
{<<"licenses">>,[<<"Apache-2.0">>]}.
|
{<<"licenses">>,[<<"Apache-2.0">>]}.
|
||||||
{<<"requirements">>,
|
{<<"requirements">>,
|
||||||
|
|
|
||||||
29
vendor/oban_web/lib/oban/web/assets.ex
vendored
|
|
@ -7,20 +7,6 @@ defmodule Oban.Web.Assets do
|
||||||
|
|
||||||
@static_path Application.app_dir(:oban_web, ["priv", "static"])
|
@static_path Application.app_dir(:oban_web, ["priv", "static"])
|
||||||
|
|
||||||
# Icons
|
|
||||||
|
|
||||||
icon_files =
|
|
||||||
for dir <- ["outline", "solid", "special"],
|
|
||||||
base = Path.join([@static_path, "icons", dir]),
|
|
||||||
file <- File.ls!(base),
|
|
||||||
String.ends_with?(file, ".svg") do
|
|
||||||
path = Path.join(base, file)
|
|
||||||
Module.put_attribute(__MODULE__, :external_resource, path)
|
|
||||||
{Path.join(dir, file), File.read!(path)}
|
|
||||||
end
|
|
||||||
|
|
||||||
@icons Map.new(icon_files)
|
|
||||||
|
|
||||||
# Font
|
# Font
|
||||||
|
|
||||||
@external_resource font_path = Path.join(@static_path, "fonts/Inter.woff2")
|
@external_resource font_path = Path.join(@static_path, "fonts/Inter.woff2")
|
||||||
|
|
@ -65,21 +51,6 @@ defmodule Oban.Web.Assets do
|
||||||
serve_asset(conn, @font, "font/woff2")
|
serve_asset(conn, @font, "font/woff2")
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(conn, :icon) do
|
|
||||||
icon_path = Enum.join(conn.path_params["path"], "/")
|
|
||||||
|
|
||||||
case Map.get(@icons, icon_path) do
|
|
||||||
nil ->
|
|
||||||
conn
|
|
||||||
|> put_resp_header("content-type", "text/plain")
|
|
||||||
|> send_resp(404, "Icon not found")
|
|
||||||
|> halt()
|
|
||||||
|
|
||||||
contents ->
|
|
||||||
serve_asset(conn, contents, "image/svg+xml")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp serve_asset(conn, contents, content_type) do
|
defp serve_asset(conn, contents, content_type) do
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", content_type)
|
|> put_resp_header("content-type", content_type)
|
||||||
|
|
|
||||||
51
vendor/oban_web/lib/oban/web/components/core.ex
vendored
|
|
@ -106,7 +106,7 @@ defmodule Oban.Web.Components.Core do
|
||||||
phx-value-choice={@value}
|
phx-value-choice={@value}
|
||||||
>
|
>
|
||||||
<%= if to_string(@value) == to_string(@selected) do %>
|
<%= if to_string(@value) == to_string(@selected) do %>
|
||||||
<Icons.check class="w-5 h-5" />
|
<Icons.icon name="icon-check" class="w-5 h-5" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<span class="block w-5 h-5"></span>
|
<span class="block w-5 h-5"></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
@ -142,7 +142,7 @@ defmodule Oban.Web.Components.Core do
|
||||||
rel="check"
|
rel="check"
|
||||||
>
|
>
|
||||||
<div class={["w-4 h-4 flex items-center justify-center rounded border", @style]}>
|
<div class={["w-4 h-4 flex items-center justify-center rounded border", @style]}>
|
||||||
<Icons.check class="w-3 h-3 text-white dark:text-gray-900" />
|
<Icons.icon name="icon-check" class="w-3 h-3 text-white dark:text-gray-900" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
"""
|
"""
|
||||||
|
|
@ -174,9 +174,9 @@ defmodule Oban.Web.Components.Core do
|
||||||
>
|
>
|
||||||
<div class={["w-4 h-4 flex items-center justify-center rounded border", @style]}>
|
<div class={["w-4 h-4 flex items-center justify-center rounded border", @style]}>
|
||||||
<%= if @checked == :some do %>
|
<%= if @checked == :some do %>
|
||||||
<Icons.indeterminate class="w-3 h-3 text-white dark:text-gray-900" />
|
<Icons.icon name="icon-indeterminate" class="w-3 h-3 text-white dark:text-gray-900" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<Icons.check class="w-3 h-3 text-white dark:text-gray-900" />
|
<Icons.icon name="icon-check" class="w-3 h-3 text-white dark:text-gray-900" />
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -203,40 +203,41 @@ defmodule Oban.Web.Components.Core do
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
defp badge_icon(%{name: "camera"} = assigns), do: ~H[<Icons.camera class="h-4 w-4 shrink-0" />]
|
defp badge_icon(%{name: "camera"} = assigns),
|
||||||
|
do: ~H[<Icons.icon name="icon-camera" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "life_buoy"} = assigns),
|
defp badge_icon(%{name: "life_buoy"} = assigns),
|
||||||
do: ~H[<Icons.life_buoy class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-life-buoy" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "lock_closed"} = assigns),
|
defp badge_icon(%{name: "lock_closed"} = assigns),
|
||||||
do: ~H[<Icons.lock_closed class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-lock-closed" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "sparkles"} = assigns),
|
defp badge_icon(%{name: "sparkles"} = assigns),
|
||||||
do: ~H[<Icons.sparkles class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-sparkles" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "table_cells"} = assigns),
|
defp badge_icon(%{name: "table_cells"} = assigns),
|
||||||
do: ~H[<Icons.table_cells class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-table-cells" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "square_2x2"} = assigns),
|
defp badge_icon(%{name: "square_2x2"} = assigns),
|
||||||
do: ~H[<Icons.square_2x2 class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-square-2x2" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "rectangle_group"} = assigns),
|
defp badge_icon(%{name: "rectangle_group"} = assigns),
|
||||||
do: ~H[<Icons.rectangle_group class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-rectangle-group" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "user_group"} = assigns),
|
defp badge_icon(%{name: "user_group"} = assigns),
|
||||||
do: ~H[<Icons.user_group class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-user-group" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "link"} = assigns),
|
defp badge_icon(%{name: "link"} = assigns),
|
||||||
do: ~H[<Icons.link class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-link" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "power"} = assigns),
|
defp badge_icon(%{name: "power"} = assigns),
|
||||||
do: ~H[<Icons.power class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-power" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "pause_circle"} = assigns),
|
defp badge_icon(%{name: "pause_circle"} = assigns),
|
||||||
do: ~H[<Icons.pause_circle class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-pause-circle" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
defp badge_icon(%{name: "play_pause_circle"} = assigns),
|
defp badge_icon(%{name: "play_pause_circle"} = assigns),
|
||||||
do: ~H[<Icons.play_pause_circle class="h-4 w-4 shrink-0" />]
|
do: ~H[<Icons.icon name="icon-play-pause-circle" class="h-4 w-4 shrink-0" />]
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
An icon-only button that expands to show label on hover. Supports disabled state.
|
An icon-only button that expands to show label on hover. Supports disabled state.
|
||||||
|
|
@ -309,17 +310,23 @@ defmodule Oban.Web.Components.Core do
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
defp button_icon(%{name: "arrow_path"} = assigns), do: ~H[<Icons.arrow_path class={@class} />]
|
defp button_icon(%{name: "arrow_path"} = assigns),
|
||||||
|
do: ~H[<Icons.icon name="icon-arrow-path" class={@class} />]
|
||||||
|
|
||||||
defp button_icon(%{name: "pause_circle"} = assigns),
|
defp button_icon(%{name: "pause_circle"} = assigns),
|
||||||
do: ~H[<Icons.pause_circle class={@class} />]
|
do: ~H[<Icons.icon name="icon-pause-circle" class={@class} />]
|
||||||
|
|
||||||
defp button_icon(%{name: "pencil_square"} = assigns),
|
defp button_icon(%{name: "pencil_square"} = assigns),
|
||||||
do: ~H[<Icons.pencil_square class={@class} />]
|
do: ~H[<Icons.icon name="icon-pencil-square" class={@class} />]
|
||||||
|
|
||||||
defp button_icon(%{name: "play_circle"} = assigns), do: ~H[<Icons.play_circle class={@class} />]
|
defp button_icon(%{name: "play_circle"} = assigns),
|
||||||
defp button_icon(%{name: "trash"} = assigns), do: ~H[<Icons.trash class={@class} />]
|
do: ~H[<Icons.icon name="icon-play-circle" class={@class} />]
|
||||||
defp button_icon(%{name: "x_circle"} = assigns), do: ~H[<Icons.x_circle class={@class} />]
|
|
||||||
|
defp button_icon(%{name: "trash"} = assigns),
|
||||||
|
do: ~H[<Icons.icon name="icon-trash" class={@class} />]
|
||||||
|
|
||||||
|
defp button_icon(%{name: "x_circle"} = assigns),
|
||||||
|
do: ~H[<Icons.icon name="icon-x-circle" class={@class} />]
|
||||||
|
|
||||||
# Sparkline
|
# Sparkline
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ defmodule Oban.Web.FormComponents do
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
class="translate-y-px"
|
class="translate-y-px"
|
||||||
>
|
>
|
||||||
<Icons.info_circle class="w-4 h-4 text-gray-400 dark:text-gray-500" />
|
<Icons.icon name="icon-info-circle" class="w-4 h-4 text-gray-400 dark:text-gray-500" />
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<%= if @type == "textarea" do %>
|
<%= if @type == "textarea" do %>
|
||||||
|
|
@ -110,7 +110,10 @@ defmodule Oban.Web.FormComponents do
|
||||||
class="sr-only peer"
|
class="sr-only peer"
|
||||||
/>
|
/>
|
||||||
<span class="block w-4 h-4 rounded border border-gray-300 dark:border-gray-600 peer-checked:border-blue-500 peer-checked:bg-blue-500" />
|
<span class="block w-4 h-4 rounded border border-gray-300 dark:border-gray-600 peer-checked:border-blue-500 peer-checked:bg-blue-500" />
|
||||||
<Icons.check class="w-3 h-3 text-white absolute top-0.5 left-0.5 hidden peer-checked:block" />
|
<Icons.icon
|
||||||
|
name="icon-check"
|
||||||
|
class="w-3 h-3 text-white absolute top-0.5 left-0.5 hidden peer-checked:block"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{@label}
|
{@label}
|
||||||
<span
|
<span
|
||||||
|
|
@ -120,7 +123,7 @@ defmodule Oban.Web.FormComponents do
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
class="ml-1 translate-y-px"
|
class="ml-1 translate-y-px"
|
||||||
>
|
>
|
||||||
<Icons.info_circle class="w-4 h-4 text-gray-400 dark:text-gray-500" />
|
<Icons.icon name="icon-info-circle" class="w-4 h-4 text-gray-400 dark:text-gray-500" />
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
94
vendor/oban_web/lib/oban/web/components/icons.ex
vendored
|
|
@ -3,60 +3,17 @@ defmodule Oban.Web.Components.Icons do
|
||||||
|
|
||||||
use Phoenix.Component
|
use Phoenix.Component
|
||||||
|
|
||||||
@icons_path Application.app_dir(:oban_web, ["priv", "static", "icons"])
|
attr :name, :string, required: true
|
||||||
|
attr :class, :any, default: nil
|
||||||
|
attr :rest, :global
|
||||||
|
|
||||||
@outline_path Path.join(@icons_path, "outline")
|
def icon(assigns) do
|
||||||
@solid_path Path.join(@icons_path, "solid")
|
~H"""
|
||||||
|
<span class={[@name, @class]} aria-hidden="true" {@rest} />
|
||||||
@outline_icons @outline_path
|
"""
|
||||||
|> File.ls!()
|
|
||||||
|> Enum.filter(&String.ends_with?(&1, ".svg"))
|
|
||||||
|> Enum.map(&String.trim_trailing(&1, ".svg"))
|
|
||||||
|
|
||||||
@solid_icons @solid_path
|
|
||||||
|> File.ls!()
|
|
||||||
|> Enum.filter(&String.ends_with?(&1, ".svg"))
|
|
||||||
|> Enum.map(&String.trim_trailing(&1, ".svg"))
|
|
||||||
|
|
||||||
for icon <- @outline_icons do
|
|
||||||
@external_resource Path.join(@outline_path, "#{icon}.svg")
|
|
||||||
|
|
||||||
func_name = icon |> String.replace("-", "_") |> String.to_atom()
|
|
||||||
|
|
||||||
@doc false
|
|
||||||
attr :class, :any, default: "w-6 h-6"
|
|
||||||
attr :rest, :global
|
|
||||||
|
|
||||||
def unquote(func_name)(assigns) do
|
|
||||||
assigns = assign(assigns, :icon_path, "outline/#{unquote(icon)}.svg")
|
|
||||||
|
|
||||||
render_icon(assigns)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
for icon <- @solid_icons do
|
attr :rest, :global, default: %{class: "size-6"}
|
||||||
@external_resource Path.join(@solid_path, "#{icon}.svg")
|
|
||||||
|
|
||||||
func_name =
|
|
||||||
icon
|
|
||||||
|> String.replace("-", "_")
|
|
||||||
|> Kernel.<>("_solid")
|
|
||||||
|> String.to_atom()
|
|
||||||
|
|
||||||
@doc false
|
|
||||||
attr :class, :any, default: "w-6 h-6"
|
|
||||||
attr :rest, :global
|
|
||||||
|
|
||||||
def unquote(func_name)(assigns) do
|
|
||||||
assigns = assign(assigns, :icon_path, "solid/#{unquote(icon)}.svg")
|
|
||||||
|
|
||||||
render_icon(assigns)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Inline Icons
|
|
||||||
|
|
||||||
attr :rest, :global, default: %{class: "w-6 h-6"}
|
|
||||||
|
|
||||||
def oban_pro_logo(assigns) do
|
def oban_pro_logo(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
|
@ -116,7 +73,7 @@ defmodule Oban.Web.Components.Icons do
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
attr :rest, :global, default: %{class: "w-6 h-6"}
|
attr :rest, :global, default: %{class: "size-6"}
|
||||||
|
|
||||||
def spinner(assigns) do
|
def spinner(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
|
@ -126,37 +83,4 @@ defmodule Oban.Web.Components.Icons do
|
||||||
</svg>
|
</svg>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
defp render_icon(assigns) do
|
|
||||||
icon_url = icon_url(assigns.icon_path)
|
|
||||||
class = normalize_class(assigns.class)
|
|
||||||
assigns = assigns |> assign(:icon_url, icon_url) |> assign(:normalized_class, class)
|
|
||||||
|
|
||||||
~H"""
|
|
||||||
<span
|
|
||||||
class={["block bg-current", @normalized_class]}
|
|
||||||
style={"mask-image: url(#{@icon_url}); -webkit-mask-image: url(#{@icon_url}); mask-size: contain; mask-repeat: no-repeat; mask-position: center;"}
|
|
||||||
aria-hidden="true"
|
|
||||||
{@rest}
|
|
||||||
/>
|
|
||||||
"""
|
|
||||||
end
|
|
||||||
|
|
||||||
defp icon_url(path) do
|
|
||||||
case Process.get(:routing) do
|
|
||||||
{socket, prefix} ->
|
|
||||||
Phoenix.VerifiedRoutes.unverified_path(
|
|
||||||
socket,
|
|
||||||
socket.router,
|
|
||||||
"#{prefix}/icons/#{path}"
|
|
||||||
)
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
"/icons/#{path}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp normalize_class(class) when is_binary(class), do: class
|
|
||||||
defp normalize_class(class) when is_list(class), do: class
|
|
||||||
defp normalize_class(nil), do: "w-6 h-6"
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ defmodule Oban.Web.Layouts do
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="flex-shrink-0 text-green-400">
|
<div class="flex-shrink-0 text-green-400">
|
||||||
<Icons.check_circle />
|
<Icons.icon name="icon-check-circle" />
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3 w-0 flex-1">
|
<div class="ml-3 w-0 flex-1">
|
||||||
<p class="text-sm leading-5 font-medium text-gray-900 dark:text-gray-100">
|
<p class="text-sm leading-5 font-medium text-gray-900 dark:text-gray-100">
|
||||||
|
|
@ -133,7 +133,7 @@ defmodule Oban.Web.Layouts do
|
||||||
phx-click="lv:clear-flash"
|
phx-click="lv:clear-flash"
|
||||||
class="inline-flex text-gray-400 dark:text-gray-500 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 focus:text-gray-500 transition ease-in-out duration-150"
|
class="inline-flex text-gray-400 dark:text-gray-500 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 focus:text-gray-500 transition ease-in-out duration-150"
|
||||||
>
|
>
|
||||||
<Icons.x_mark class="w-5 h-5" />
|
<Icons.icon name="icon-x-mark" class="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,10 @@ defmodule Oban.Web.SidebarComponents do
|
||||||
phx-click={toggle(@name)}
|
phx-click={toggle(@name)}
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
>
|
>
|
||||||
<Icons.chevron_right class="w-4 h-4 mt-1 mr-1 transition-transform rotate-90" />
|
<Icons.icon
|
||||||
|
name="icon-chevron-right"
|
||||||
|
class="w-4 h-4 mt-1 mr-1 transition-transform rotate-90"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<h3 class="dark:text-gray-200 font-bold">{String.capitalize(@name)}</h3>
|
<h3 class="dark:text-gray-200 font-bold">{String.capitalize(@name)}</h3>
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ defmodule Oban.Web.SortComponent do
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<%= if @params.sort_dir == "asc" do %>
|
<%= if @params.sort_dir == "asc" do %>
|
||||||
<Icons.bars_arrow_down class="w-4 h-4" />
|
<Icons.icon name="icon-bars-arrow-down" class="w-4 h-4" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<Icons.bars_arrow_up class="w-4 h-4" />
|
<Icons.icon name="icon-bars-arrow-up" class="w-4 h-4" />
|
||||||
<% end %>
|
<% end %>
|
||||||
<span class="ml-1 block capitalize">
|
<span class="ml-1 block capitalize">
|
||||||
{String.replace(@params.sort_by, "_", " ")}
|
{String.replace(@params.sort_by, "_", " ")}
|
||||||
|
|
@ -71,7 +71,7 @@ defmodule Oban.Web.SortComponent do
|
||||||
role="option"
|
role="option"
|
||||||
>
|
>
|
||||||
<%= if @value == @selected do %>
|
<%= if @value == @selected do %>
|
||||||
<Icons.check class="w-4 h-4 text-blue-500" />
|
<Icons.icon name="icon-check" class="w-4 h-4 text-blue-500" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<span class="block w-4 h-4"></span>
|
<span class="block w-4 h-4"></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ defmodule Oban.Web.DashboardLive do
|
||||||
page = resolve_page(params)
|
page = resolve_page(params)
|
||||||
|
|
||||||
Process.put(:routing, {socket, prefix})
|
Process.put(:routing, {socket, prefix})
|
||||||
|
Process.put(:csp_nonce_style, csp_nonces.style)
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,15 @@ defmodule Oban.Web.ConnectivityComponent do
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div id="connectivity" data-title={@title} phx-hook="Tippy">
|
<div id="connectivity" data-title={@title} phx-hook="Tippy">
|
||||||
<Icons.bolt_circle :if={@status == :solitary} class="w-6 h-6 text-yellow-500" />
|
<Icons.icon :if={@status == :solitary} name="icon-bolt-circle" class="w-6 h-6 text-yellow-500" />
|
||||||
<Icons.bolt_slash :if={@status == :isolated} class="w-6 h-6 animate-pulse text-red-500" />
|
<Icons.icon
|
||||||
<Icons.exclamation_circle
|
:if={@status == :isolated}
|
||||||
|
name="icon-bolt-slash"
|
||||||
|
class="w-6 h-6 animate-pulse text-red-500"
|
||||||
|
/>
|
||||||
|
<Icons.icon
|
||||||
:if={@status == :disconnected}
|
:if={@status == :disconnected}
|
||||||
|
name="icon-exclamation-circle"
|
||||||
class="w-6 h-6 animate-pulse text-red-500"
|
class="w-6 h-6 animate-pulse text-red-500"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ defmodule Oban.Web.Crons.DetailComponent do
|
||||||
data-title="Back to crons"
|
data-title="Back to crons"
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
>
|
>
|
||||||
<Icons.arrow_left class="w-5 h-5" />
|
<Icons.icon name="icon-arrow-left" class="w-5 h-5" />
|
||||||
<span class="text-lg font-bold ml-2">
|
<span class="text-lg font-bold ml-2">
|
||||||
{@cron.worker}
|
{@cron.worker}
|
||||||
<span :if={show_name?(@cron)} class="font-normal text-gray-500 dark:text-gray-400">
|
<span :if={show_name?(@cron)} class="font-normal text-gray-500 dark:text-gray-400">
|
||||||
|
|
@ -140,7 +140,7 @@ defmodule Oban.Web.Crons.DetailComponent do
|
||||||
|
|
||||||
<div class="px-3 py-6 border-t border-gray-200 dark:border-gray-700">
|
<div class="px-3 py-6 border-t border-gray-200 dark:border-gray-700">
|
||||||
<h3 class="flex font-semibold mb-3 space-x-2 text-gray-400">
|
<h3 class="flex font-semibold mb-3 space-x-2 text-gray-400">
|
||||||
<Icons.pencil_square />
|
<Icons.icon name="icon-pencil-square" />
|
||||||
<span>Edit Configuration</span>
|
<span>Edit Configuration</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
|
@ -230,7 +230,7 @@ defmodule Oban.Web.Crons.DetailComponent do
|
||||||
class="text-xs text-gray-500 dark:text-gray-400 hover:underline"
|
class="text-xs text-gray-500 dark:text-gray-400 hover:underline"
|
||||||
>
|
>
|
||||||
Editing requires DynamicCron
|
Editing requires DynamicCron
|
||||||
<Icons.arrow_top_right_on_square class="w-3 h-3 inline-block" />
|
<Icons.icon name="icon-arrow-top-right-on-square" class="w-3 h-3 inline-block" />
|
||||||
</a>
|
</a>
|
||||||
<.save_button disabled={not @changed?} />
|
<.save_button disabled={not @changed?} />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -257,7 +257,7 @@ defmodule Oban.Web.Crons.DetailComponent do
|
||||||
navigate={oban_path(:jobs, %{meta: [["cron_name"], @cron.name], state: "completed"})}
|
navigate={oban_path(:jobs, %{meta: [["cron_name"], @cron.name], state: "completed"})}
|
||||||
class="absolute right-4 top-4 flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300 hover:bg-blue-100 hover:text-blue-600 dark:hover:bg-blue-900 dark:hover:text-blue-300 opacity-0 group-hover:opacity-100 transition-opacity"
|
class="absolute right-4 top-4 flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300 hover:bg-blue-100 hover:text-blue-600 dark:hover:bg-blue-900 dark:hover:text-blue-300 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||||
>
|
>
|
||||||
View all jobs <Icons.arrow_right class="w-3 h-3" />
|
View all jobs <Icons.icon name="icon-arrow-right" class="w-3 h-3" />
|
||||||
</.link>
|
</.link>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ defmodule Oban.Web.Crons.Helpers do
|
||||||
|
|
||||||
def state_icon(%{paused: true} = assigns) do
|
def state_icon(%{paused: true} = assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Icons.pause_circle class="w-5 h-5 text-gray-400" />
|
<Icons.icon name="icon-pause-circle" class="w-5 h-5 text-gray-400" />
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -21,21 +21,21 @@ defmodule Oban.Web.Crons.Helpers do
|
||||||
~H"""
|
~H"""
|
||||||
<%= case @state do %>
|
<%= case @state do %>
|
||||||
<% "available" -> %>
|
<% "available" -> %>
|
||||||
<Icons.ellipsis_horizontal_circle class={["w-5 h-5", @color_class]} />
|
<Icons.icon name="icon-ellipsis-horizontal-circle" class={["w-5 h-5", @color_class]} />
|
||||||
<% "cancelled" -> %>
|
<% "cancelled" -> %>
|
||||||
<Icons.x_circle class={["w-5 h-5", @color_class]} />
|
<Icons.icon name="icon-x-circle" class={["w-5 h-5", @color_class]} />
|
||||||
<% "completed" -> %>
|
<% "completed" -> %>
|
||||||
<Icons.check_circle class={["w-5 h-5", @color_class]} />
|
<Icons.icon name="icon-check-circle" class={["w-5 h-5", @color_class]} />
|
||||||
<% "discarded" -> %>
|
<% "discarded" -> %>
|
||||||
<Icons.exclamation_circle class={["w-5 h-5", @color_class]} />
|
<Icons.icon name="icon-exclamation-circle" class={["w-5 h-5", @color_class]} />
|
||||||
<% "executing" -> %>
|
<% "executing" -> %>
|
||||||
<Icons.play_circle class={["w-5 h-5", @color_class]} />
|
<Icons.icon name="icon-play-circle" class={["w-5 h-5", @color_class]} />
|
||||||
<% "retryable" -> %>
|
<% "retryable" -> %>
|
||||||
<Icons.arrow_path class={["w-5 h-5", @color_class]} />
|
<Icons.icon name="icon-arrow-path" class={["w-5 h-5", @color_class]} />
|
||||||
<% "scheduled" -> %>
|
<% "scheduled" -> %>
|
||||||
<Icons.clock class={["w-5 h-5", @color_class]} />
|
<Icons.icon name="icon-clock" class={["w-5 h-5", @color_class]} />
|
||||||
<% _ -> %>
|
<% _ -> %>
|
||||||
<Icons.minus_circle class="w-5 h-5 text-gray-400" />
|
<Icons.icon name="icon-minus-circle" class="w-5 h-5 text-gray-400" />
|
||||||
<% end %>
|
<% end %>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ defmodule Oban.Web.Crons.NewComponent do
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
>
|
>
|
||||||
<Icons.x_mark class="h-6 w-6" />
|
<Icons.icon name="icon-x-mark" class="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ defmodule Oban.Web.Crons.TableComponent do
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div :if={Enum.empty?(@crontab)} class="py-16 px-6 text-center">
|
<div :if={Enum.empty?(@crontab)} class="py-16 px-6 text-center">
|
||||||
<Icons.clock class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
<Icons.icon name="icon-clock" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
||||||
<h3 class="mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100">No crons</h3>
|
<h3 class="mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100">No crons</h3>
|
||||||
<p class="mt-2 text-base text-gray-500 dark:text-gray-400 max-w-md mx-auto">
|
<p class="mt-2 text-base text-gray-500 dark:text-gray-400 max-w-md mx-auto">
|
||||||
Crons run jobs on a schedule. Configure them in your Oban supervisor or create them dynamically.
|
Crons run jobs on a schedule. Configure them in your Oban supervisor or create them dynamically.
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ defmodule Oban.Web.HelpComponent do
|
||||||
phx-click={JS.toggle(to: "#help-menu")}
|
phx-click={JS.toggle(to: "#help-menu")}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<Icons.question_mark_circle />
|
<Icons.icon name="icon-question-mark-circle" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
|
|
@ -35,7 +35,7 @@ defmodule Oban.Web.HelpComponent do
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="flex items-center space-x-2 w-full"
|
class="flex items-center space-x-2 w-full"
|
||||||
>
|
>
|
||||||
<Icons.arrow_top_right_on_square class="w-5 h-5" />
|
<Icons.icon name="icon-arrow-top-right-on-square" class="w-5 h-5" />
|
||||||
<span class="text-gray-800 dark:text-gray-200">Documentation</span>
|
<span class="text-gray-800 dark:text-gray-200">Documentation</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -45,7 +45,7 @@ defmodule Oban.Web.HelpComponent do
|
||||||
phx-click={JS.hide(to: "#help-menu") |> JS.exec("data-shortcut", to: "#shortcuts")}
|
phx-click={JS.hide(to: "#help-menu") |> JS.exec("data-shortcut", to: "#shortcuts")}
|
||||||
role="option"
|
role="option"
|
||||||
>
|
>
|
||||||
<Icons.command_line class="w-5 h-5" />
|
<Icons.icon name="icon-command-line" class="w-5 h-5" />
|
||||||
<span class="text-gray-800 dark:text-gray-200">Keyboard shortcuts</span>
|
<span class="text-gray-800 dark:text-gray-200">Keyboard shortcuts</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ defmodule Oban.Web.InstancesComponent do
|
||||||
phx-value-name={name}
|
phx-value-name={name}
|
||||||
>
|
>
|
||||||
<%= if name == @active do %>
|
<%= if name == @active do %>
|
||||||
<Icons.check class="w-4 h-4 text-blue-500" />
|
<Icons.icon name="icon-check" class="w-4 h-4 text-blue-500" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<span class="block w-4 h-4"></span>
|
<span class="block w-4 h-4"></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,13 @@ defmodule Oban.Web.Jobs.ChartComponent do
|
||||||
phx-click={toggle_chart(@myself)}
|
phx-click={toggle_chart(@myself)}
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
>
|
>
|
||||||
<Icons.chevron_right class={[
|
<Icons.icon
|
||||||
"w-5 h-5 mr-2 transition-transform",
|
name="icon-chevron-right"
|
||||||
if(@visible, do: "rotate-90")
|
class={[
|
||||||
]} />
|
"w-5 h-5 mr-2 transition-transform",
|
||||||
|
if(@visible, do: "rotate-90")
|
||||||
|
]}
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<h3 class="text-base font-semibold">
|
<h3 class="text-base font-semibold">
|
||||||
|
|
@ -89,7 +92,7 @@ defmodule Oban.Web.Jobs.ChartComponent do
|
||||||
target={@myself}
|
target={@myself}
|
||||||
title="Change metric series"
|
title="Change metric series"
|
||||||
>
|
>
|
||||||
<Icons.chart_bar_square />
|
<Icons.icon name="icon-chart-bar-square" />
|
||||||
</Core.dropdown_button>
|
</Core.dropdown_button>
|
||||||
|
|
||||||
<Core.dropdown_button
|
<Core.dropdown_button
|
||||||
|
|
@ -100,7 +103,7 @@ defmodule Oban.Web.Jobs.ChartComponent do
|
||||||
target={@myself}
|
target={@myself}
|
||||||
title="Change slice period"
|
title="Change slice period"
|
||||||
>
|
>
|
||||||
<Icons.clock />
|
<Icons.icon name="icon-clock" />
|
||||||
</Core.dropdown_button>
|
</Core.dropdown_button>
|
||||||
|
|
||||||
<Core.dropdown_button
|
<Core.dropdown_button
|
||||||
|
|
@ -111,7 +114,7 @@ defmodule Oban.Web.Jobs.ChartComponent do
|
||||||
target={@myself}
|
target={@myself}
|
||||||
title="Change metric grouping"
|
title="Change metric grouping"
|
||||||
>
|
>
|
||||||
<Icons.rectangle_group />
|
<Icons.icon name="icon-rectangle-group" />
|
||||||
</Core.dropdown_button>
|
</Core.dropdown_button>
|
||||||
|
|
||||||
<Core.dropdown_button
|
<Core.dropdown_button
|
||||||
|
|
@ -122,7 +125,7 @@ defmodule Oban.Web.Jobs.ChartComponent do
|
||||||
target={@myself}
|
target={@myself}
|
||||||
title="Change percentile"
|
title="Change percentile"
|
||||||
>
|
>
|
||||||
<Icons.percent_square />
|
<Icons.icon name="icon-percent-square" />
|
||||||
</Core.dropdown_button>
|
</Core.dropdown_button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
phx-hook="HistoryBack"
|
phx-hook="HistoryBack"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<Icons.arrow_left class="w-5 h-5" />
|
<Icons.icon name="icon-arrow-left" class="w-5 h-5" />
|
||||||
<span class="text-lg font-bold ml-2">{job_title(@job)}</span>
|
<span class="text-lg font-bold ml-2">{job_title(@job)}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
label="Edit"
|
label="Edit"
|
||||||
color="violet"
|
color="violet"
|
||||||
tooltip="Edit this job"
|
tooltip="Edit this job"
|
||||||
disabled={not editable?(@job)}
|
disabled={executing?(@job)}
|
||||||
phx-click={scroll_to_edit()}
|
phx-click={scroll_to_edit()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -223,7 +223,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
Workflow
|
Workflow
|
||||||
</span>
|
</span>
|
||||||
<span class="text-base text-gray-800 dark:text-gray-200 flex items-center">
|
<span class="text-base text-gray-800 dark:text-gray-200 flex items-center">
|
||||||
<Icons.rectangle_group class="w-4 h-4 mr-1.5 text-violet-500" />
|
<Icons.icon name="icon-rectangle-group" class="w-4 h-4 mr-1.5 text-violet-500" />
|
||||||
<span class="truncate">{workflow_display_name(@job)}</span>
|
<span class="truncate">{workflow_display_name(@job)}</span>
|
||||||
</span>
|
</span>
|
||||||
</.link>
|
</.link>
|
||||||
|
|
@ -241,7 +241,8 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
phx-click="toggle-diagnostics"
|
phx-click="toggle-diagnostics"
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right
|
<Icons.icon
|
||||||
|
name="icon-chevron-right"
|
||||||
id="diagnostics-chevron"
|
id="diagnostics-chevron"
|
||||||
class={["w-5 h-5 transition-transform", if(@diagnostics_open?, do: "rotate-90")]}
|
class={["w-5 h-5 transition-transform", if(@diagnostics_open?, do: "rotate-90")]}
|
||||||
/>
|
/>
|
||||||
|
|
@ -324,7 +325,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
phx-click={copy_to_clipboard(@diagnostics["info"]["current_stacktrace"])}
|
phx-click={copy_to_clipboard(@diagnostics["info"]["current_stacktrace"])}
|
||||||
>
|
>
|
||||||
<Icons.clipboard class="w-4 h-4" />
|
<Icons.icon name="icon-clipboard" class="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<%= if @diagnostics["info"]["current_stacktrace"] do %>
|
<%= if @diagnostics["info"]["current_stacktrace"] do %>
|
||||||
|
|
@ -345,7 +346,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<div class="flex items-center space-x-2 px-2 text-gray-400 dark:text-gray-500">
|
<div class="flex items-center space-x-2 px-2 text-gray-400 dark:text-gray-500">
|
||||||
<Icons.clock class="w-5 h-5" />
|
<Icons.icon name="icon-clock" class="w-5 h-5" />
|
||||||
<span class="text-sm">
|
<span class="text-sm">
|
||||||
<%= if executing?(@job) do %>
|
<%= if executing?(@job) do %>
|
||||||
Waiting for diagnostics...
|
Waiting for diagnostics...
|
||||||
|
|
@ -374,7 +375,8 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
||||||
phx-click={toggle_errors()}
|
phx-click={toggle_errors()}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right
|
<Icons.icon
|
||||||
|
name="icon-chevron-right"
|
||||||
id="errors-chevron"
|
id="errors-chevron"
|
||||||
class={["w-5 h-5 transition-transform", if(Enum.any?(@job.errors), do: "rotate-90")]}
|
class={["w-5 h-5 transition-transform", if(Enum.any?(@job.errors), do: "rotate-90")]}
|
||||||
/>
|
/>
|
||||||
|
|
@ -440,7 +442,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
)
|
)
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Icons.chevron_left class="w-5 h-5" />
|
<Icons.icon name="icon-chevron-left" class="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400 tabular min-w-[4rem] text-center">
|
<span class="text-sm text-gray-500 dark:text-gray-400 tabular min-w-[4rem] text-center">
|
||||||
{@error_index + 1} of {length(@job.errors)}
|
{@error_index + 1} of {length(@job.errors)}
|
||||||
|
|
@ -460,7 +462,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
)
|
)
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right class="w-5 h-5" />
|
<Icons.icon name="icon-chevron-right" class="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -468,7 +470,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
<.error_entry errors={@job.errors} index={@error_index} sort={@error_sort} />
|
<.error_entry errors={@job.errors} index={@error_index} sort={@error_sort} />
|
||||||
<% else %>
|
<% else %>
|
||||||
<div class="flex items-center space-x-2 px-2 text-gray-400 dark:text-gray-500">
|
<div class="flex items-center space-x-2 px-2 text-gray-400 dark:text-gray-500">
|
||||||
<Icons.check_circle class="w-5 h-5" />
|
<Icons.icon name="icon-check-circle" class="w-5 h-5" />
|
||||||
<span class="text-sm">No errors recorded</span>
|
<span class="text-sm">No errors recorded</span>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
@ -482,24 +484,25 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
||||||
phx-click={toggle_edit()}
|
phx-click={toggle_edit()}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right
|
<Icons.icon
|
||||||
|
name="icon-chevron-right"
|
||||||
id="edit-chevron"
|
id="edit-chevron"
|
||||||
class={["w-5 h-5 transition-transform", if(editable?(@job), do: "rotate-90")]}
|
class={["w-5 h-5 transition-transform", if(not executing?(@job), do: "rotate-90")]}
|
||||||
/>
|
/>
|
||||||
<span class="font-semibold">Edit Job</span>
|
<span class="font-semibold">Edit Job</span>
|
||||||
<span
|
<span
|
||||||
:if={not editable?(@job)}
|
:if={executing?(@job)}
|
||||||
id="edit-hint"
|
id="edit-hint"
|
||||||
class="flex items-center"
|
class="flex items-center"
|
||||||
data-title="Only available, scheduled, and retryable jobs can be edited"
|
data-title="Executing jobs can't be edited"
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
>
|
>
|
||||||
<Icons.info_circle class="w-4 h-4 text-gray-400" />
|
<Icons.icon name="icon-info-circle" class="w-4 h-4 text-gray-400" />
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div id="edit-content" class={["mt-3", unless(editable?(@job), do: "hidden")]}>
|
<div id="edit-content" class={["mt-3", if(executing?(@job), do: "hidden")]}>
|
||||||
<fieldset disabled={not editable?(@job)}>
|
<fieldset disabled={executing?(@job)}>
|
||||||
<form
|
<form
|
||||||
id="job-edit-form"
|
id="job-edit-form"
|
||||||
class="grid grid-cols-4 gap-4 bg-gray-50 dark:bg-gray-800 rounded-md p-4"
|
class="grid grid-cols-4 gap-4 bg-gray-50 dark:bg-gray-800 rounded-md p-4"
|
||||||
|
|
@ -626,7 +629,11 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
||||||
phx-click={toggle_job_data()}
|
phx-click={toggle_job_data()}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right id="job-data-chevron" class="w-5 h-5 transition-transform rotate-90" />
|
<Icons.icon
|
||||||
|
name="icon-chevron-right"
|
||||||
|
id="job-data-chevron"
|
||||||
|
class="w-5 h-5 transition-transform rotate-90"
|
||||||
|
/>
|
||||||
<span class="font-semibold">Job Data</span>
|
<span class="font-semibold">Job Data</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -645,7 +652,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
phx-click={copy_to_clipboard(format_args(@job, @resolver))}
|
phx-click={copy_to_clipboard(format_args(@job, @resolver))}
|
||||||
>
|
>
|
||||||
<Icons.clipboard class="w-4 h-4" />
|
<Icons.icon name="icon-clipboard" class="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<pre class="font-mono text-sm text-gray-600 dark:text-gray-400 whitespace-pre-wrap break-all">{format_args(@job, @resolver)}</pre>
|
<pre class="font-mono text-sm text-gray-600 dark:text-gray-400 whitespace-pre-wrap break-all">{format_args(@job, @resolver)}</pre>
|
||||||
|
|
@ -664,7 +671,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
phx-click={copy_to_clipboard(format_meta(@job, @resolver))}
|
phx-click={copy_to_clipboard(format_meta(@job, @resolver))}
|
||||||
>
|
>
|
||||||
<Icons.clipboard class="w-4 h-4" />
|
<Icons.icon name="icon-clipboard" class="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<pre class="font-mono text-sm text-gray-500 dark:text-gray-400 whitespace-pre-wrap break-all">{format_meta(@job, @resolver)}</pre>
|
<pre class="font-mono text-sm text-gray-500 dark:text-gray-400 whitespace-pre-wrap break-all">{format_meta(@job, @resolver)}</pre>
|
||||||
|
|
@ -688,7 +695,7 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
phx-click={copy_to_clipboard(format_recorded(@job, @resolver))}
|
phx-click={copy_to_clipboard(format_recorded(@job, @resolver))}
|
||||||
>
|
>
|
||||||
<Icons.clipboard class="w-4 h-4" />
|
<Icons.icon name="icon-clipboard" class="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<pre class="font-mono text-sm text-gray-600 dark:text-gray-400 whitespace-pre-wrap break-all">{format_recorded(@job, @resolver)}</pre>
|
<pre class="font-mono text-sm text-gray-600 dark:text-gray-400 whitespace-pre-wrap break-all">{format_recorded(@job, @resolver)}</pre>
|
||||||
|
|
@ -919,10 +926,6 @@ defmodule Oban.Web.Jobs.DetailComponent do
|
||||||
JS.dispatch("phx:copy-to-clipboard", detail: %{text: text})
|
JS.dispatch("phx:copy-to-clipboard", detail: %{text: text})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp editable?(%{state: state}) do
|
|
||||||
state in ~w(scheduled retryable available)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp executing?(%{state: state}), do: state == "executing"
|
defp executing?(%{state: state}), do: state == "executing"
|
||||||
|
|
||||||
defp format_bytes(nil), do: "—"
|
defp format_bytes(nil), do: "—"
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,11 @@ defmodule Oban.Web.Jobs.HistoryChartComponent do
|
||||||
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
||||||
phx-click={toggle_section()}
|
phx-click={toggle_section()}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right id="history-chevron" class="w-5 h-5 transition-transform rotate-90" />
|
<Icons.icon
|
||||||
|
name="icon-chevron-right"
|
||||||
|
id="history-chevron"
|
||||||
|
class="w-5 h-5 transition-transform rotate-90"
|
||||||
|
/>
|
||||||
<span class="font-semibold">Recent Executions</span>
|
<span class="font-semibold">Recent Executions</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -28,7 +32,7 @@ defmodule Oban.Web.Jobs.HistoryChartComponent do
|
||||||
navigate={all_jobs_path(@job)}
|
navigate={all_jobs_path(@job)}
|
||||||
class="absolute right-4 top-4 flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300 hover:bg-blue-100 hover:text-blue-600 dark:hover:bg-blue-900 dark:hover:text-blue-300 opacity-0 group-hover:opacity-100 transition-opacity"
|
class="absolute right-4 top-4 flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300 hover:bg-blue-100 hover:text-blue-600 dark:hover:bg-blue-900 dark:hover:text-blue-300 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||||
>
|
>
|
||||||
View all jobs <Icons.arrow_right class="w-3 h-3" />
|
View all jobs <Icons.icon name="icon-arrow-right" class="w-3 h-3" />
|
||||||
</.link>
|
</.link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ defmodule Oban.Web.Jobs.NewComponent do
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
>
|
>
|
||||||
<Icons.x_mark class="h-6 w-6" />
|
<Icons.icon name="icon-x-mark" class="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ defmodule Oban.Web.Jobs.TableComponent do
|
||||||
|
|
||||||
<div :if={Enum.empty?(@jobs)} class="text-lg text-center py-12">
|
<div :if={Enum.empty?(@jobs)} class="text-lg text-center py-12">
|
||||||
<div class="flex items-center justify-center space-x-2 text-gray-600 dark:text-gray-300">
|
<div class="flex items-center justify-center space-x-2 text-gray-600 dark:text-gray-300">
|
||||||
<Icons.no_symbol /> <span>No jobs match the current set of filters.</span>
|
<Icons.icon name="icon-no-symbol" /> <span>No jobs match the current set of filters.</span>
|
||||||
</div>
|
</div>
|
||||||
<p :if={is_integer(@query_limit)} class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
<p :if={is_integer(@query_limit)} class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||||
Filtering limited to latest {integer_to_delimited(@query_limit)} jobs. See <a
|
Filtering limited to latest {integer_to_delimited(@query_limit)} jobs. See <a
|
||||||
|
|
@ -111,16 +111,18 @@ defmodule Oban.Web.Jobs.TableComponent do
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ml-auto flex items-center space-x-1">
|
<div class="ml-auto flex items-center space-x-1">
|
||||||
<Icons.life_buoy
|
<Icons.icon
|
||||||
:if={Map.has_key?(@job.meta, "rescued")}
|
:if={Map.has_key?(@job.meta, "rescued")}
|
||||||
|
name="icon-life-buoy"
|
||||||
class="h-5 w-5 text-gray-500 dark:text-gray-300"
|
class="h-5 w-5 text-gray-500 dark:text-gray-300"
|
||||||
id={"job-rescued-#{assigns.job.id}"}
|
id={"job-rescued-#{assigns.job.id}"}
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
data-title="Rescued by lifeline"
|
data-title="Rescued by lifeline"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Icons.crossbones_circle_solid
|
<Icons.icon
|
||||||
:if={orphaned?(@job, @producers)}
|
:if={orphaned?(@job, @producers)}
|
||||||
|
name="icon-crossbones-circle-solid"
|
||||||
class="h-5 w-5 text-gray-500 dark:text-gray-300"
|
class="h-5 w-5 text-gray-500 dark:text-gray-300"
|
||||||
id={"job-orphaned-#{assigns.job.id}"}
|
id={"job-orphaned-#{assigns.job.id}"}
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ defmodule Oban.Web.Jobs.TimelineComponent do
|
||||||
|
|
||||||
defp state_icon(%{icon: :pending} = assigns) do
|
defp state_icon(%{icon: :pending} = assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Icons.ellipsis_horizontal_circle class="w-5 h-5" />
|
<Icons.icon name="icon-ellipsis-horizontal-circle" class="w-5 h-5" />
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ defmodule Oban.Web.Jobs.TimelineComponent do
|
||||||
|
|
||||||
defp state_icon(%{icon: :done} = assigns) do
|
defp state_icon(%{icon: :done} = assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Icons.check_circle class="w-5 h-5" />
|
<Icons.icon name="icon-check-circle" class="w-5 h-5" />
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
phx-hook="HistoryBack"
|
phx-hook="HistoryBack"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<Icons.arrow_left class="w-5 h-5" />
|
<Icons.icon name="icon-arrow-left" class="w-5 h-5" />
|
||||||
<span class="text-lg capitalize font-bold ml-2">{@queue} Queue</span>
|
<span class="text-lg capitalize font-bold ml-2">{@queue} Queue</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -210,7 +210,7 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
navigate={oban_path(:jobs, %{queues: @queue, state: "completed"})}
|
navigate={oban_path(:jobs, %{queues: @queue, state: "completed"})}
|
||||||
class="absolute right-4 top-4 flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300 hover:bg-blue-100 hover:text-blue-600 dark:hover:bg-blue-900 dark:hover:text-blue-300 opacity-0 group-hover:opacity-100 transition-opacity"
|
class="absolute right-4 top-4 flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-300 hover:bg-blue-100 hover:text-blue-600 dark:hover:bg-blue-900 dark:hover:text-blue-300 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||||
>
|
>
|
||||||
View all jobs <Icons.arrow_right class="w-3 h-3" />
|
View all jobs <Icons.icon name="icon-arrow-right" class="w-3 h-3" />
|
||||||
</.link>
|
</.link>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
@ -339,7 +339,8 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
||||||
phx-click={toggle_instances(@myself)}
|
phx-click={toggle_instances(@myself)}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right
|
<Icons.icon
|
||||||
|
name="icon-chevron-right"
|
||||||
id="instances-chevron"
|
id="instances-chevron"
|
||||||
class={["w-5 h-5 transition-transform", if(@instances_open?, do: "rotate-90")]}
|
class={["w-5 h-5 transition-transform", if(@instances_open?, do: "rotate-90")]}
|
||||||
/>
|
/>
|
||||||
|
|
@ -421,7 +422,8 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
class="flex items-center w-full space-x-2 px-2 py-1.5 rounded-md text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
|
||||||
phx-click={toggle_config(@myself)}
|
phx-click={toggle_config(@myself)}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right
|
<Icons.icon
|
||||||
|
name="icon-chevron-right"
|
||||||
id="config-chevron"
|
id="config-chevron"
|
||||||
class={["w-5 h-5 transition-transform", if(@config_open?, do: "rotate-90")]}
|
class={["w-5 h-5 transition-transform", if(@config_open?, do: "rotate-90")]}
|
||||||
/>
|
/>
|
||||||
|
|
@ -437,7 +439,7 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
phx-submit="local-submit"
|
phx-submit="local-submit"
|
||||||
>
|
>
|
||||||
<h3 class="flex items-center mb-4">
|
<h3 class="flex items-center mb-4">
|
||||||
<Icons.map_pin class="w-5 h-5 mr-1 text-gray-500" />
|
<Icons.icon name="icon-map-pin" class="w-5 h-5 mr-1 text-gray-500" />
|
||||||
<span class="text-base font-medium">Local Limit</span>
|
<span class="text-base font-medium">Local Limit</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
|
@ -467,7 +469,7 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<h3 class="flex items-center">
|
<h3 class="flex items-center">
|
||||||
<Icons.globe class="w-5 h-5 mr-1 text-gray-500" />
|
<Icons.icon name="icon-globe" class="w-5 h-5 mr-1 text-gray-500" />
|
||||||
<span class="text-base font-medium">Global Limit</span>
|
<span class="text-base font-medium">Global Limit</span>
|
||||||
<span
|
<span
|
||||||
id="global-limit-info"
|
id="global-limit-info"
|
||||||
|
|
@ -475,7 +477,10 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
class="ml-1"
|
class="ml-1"
|
||||||
>
|
>
|
||||||
<Icons.info_circle class="w-4 h-4 text-gray-400 dark:text-gray-500" />
|
<Icons.icon
|
||||||
|
name="icon-info-circle"
|
||||||
|
class="w-4 h-4 text-gray-400 dark:text-gray-500"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
|
@ -565,7 +570,7 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
class="text-xs text-gray-500 dark:text-gray-400 hover:underline"
|
class="text-xs text-gray-500 dark:text-gray-400 hover:underline"
|
||||||
>
|
>
|
||||||
Requires Smart Engine
|
Requires Smart Engine
|
||||||
<Icons.arrow_top_right_on_square class="w-3 h-3 inline-block" />
|
<Icons.icon name="icon-arrow-top-right-on-square" class="w-3 h-3 inline-block" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -579,7 +584,7 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<h3 class="flex items-center">
|
<h3 class="flex items-center">
|
||||||
<Icons.arrow_trending_down class="w-5 h-5 mr-1 text-gray-500" />
|
<Icons.icon name="icon-arrow-trending-down" class="w-5 h-5 mr-1 text-gray-500" />
|
||||||
<span class="text-base font-medium">Rate Limit</span>
|
<span class="text-base font-medium">Rate Limit</span>
|
||||||
<span
|
<span
|
||||||
id="rate-limit-info"
|
id="rate-limit-info"
|
||||||
|
|
@ -587,7 +592,10 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
class="ml-1"
|
class="ml-1"
|
||||||
>
|
>
|
||||||
<Icons.info_circle class="w-4 h-4 text-gray-400 dark:text-gray-500" />
|
<Icons.icon
|
||||||
|
name="icon-info-circle"
|
||||||
|
class="w-4 h-4 text-gray-400 dark:text-gray-500"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
|
@ -677,7 +685,7 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
class="text-xs text-gray-500 dark:text-gray-400 hover:underline"
|
class="text-xs text-gray-500 dark:text-gray-400 hover:underline"
|
||||||
>
|
>
|
||||||
Requires Smart Engine
|
Requires Smart Engine
|
||||||
<Icons.arrow_top_right_on_square class="w-3 h-3 inline-block" />
|
<Icons.icon name="icon-arrow-top-right-on-square" class="w-3 h-3 inline-block" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -913,13 +921,13 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
class={"#{if @enabled, do: "opacity-0 ease-out duration-100", else: "opacity-100 ease-in duration-200"} absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"}
|
class={"#{if @enabled, do: "opacity-0 ease-out duration-100", else: "opacity-100 ease-in duration-200"} absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<Icons.x_mark class="h-3 w-3 text-gray-400" />
|
<Icons.icon name="icon-x-mark" class="h-3 w-3 text-gray-400" />
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class={"#{if @enabled, do: "opacity-100 ease-in duration-200", else: "opacity-0 ease-out duration-100"} absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"}
|
class={"#{if @enabled, do: "opacity-100 ease-in duration-200", else: "opacity-0 ease-out duration-100"} absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<Icons.check class="h-3 w-3 text-blue-500" />
|
<Icons.icon name="icon-check" class="h-3 w-3 text-blue-500" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -930,7 +938,7 @@ defmodule Oban.Web.Queues.DetailComponent do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="flex items-center justify-end mt-4 space-x-2">
|
<div class="flex items-center justify-end mt-4 space-x-2">
|
||||||
<%= if @locked do %>
|
<%= if @locked do %>
|
||||||
<Icons.lock_closed class="w-5 h-5 text-gray-600 dark:text-gray-400" />
|
<Icons.icon name="icon-lock-closed" class="w-5 h-5 text-gray-600 dark:text-gray-400" />
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -115,13 +115,13 @@ defmodule Oban.Web.Queues.DetailInstanceComponent do
|
||||||
:if={@terminating?}
|
:if={@terminating?}
|
||||||
class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300"
|
class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300"
|
||||||
>
|
>
|
||||||
<Icons.power class="w-3 h-3 mr-0.5" /> Stopping
|
<Icons.icon name="icon-power" class="w-3 h-3 mr-0.5" /> Stopping
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
:if={@paused and not @terminating?}
|
:if={@paused and not @terminating?}
|
||||||
class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-300"
|
class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-300"
|
||||||
>
|
>
|
||||||
<Icons.pause_circle class="w-3 h-3 mr-0.5" /> Paused
|
<Icons.icon name="icon-pause-circle" class="w-3 h-3 mr-0.5" /> Paused
|
||||||
</span>
|
</span>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
@ -147,9 +147,9 @@ defmodule Oban.Web.Queues.DetailInstanceComponent do
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<%= if @paused do %>
|
<%= if @paused do %>
|
||||||
<Icons.play_circle class="w-5 h-5" />
|
<Icons.icon name="icon-play-circle" class="w-5 h-5" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<Icons.pause_circle class="w-5 h-5" />
|
<Icons.icon name="icon-pause-circle" class="w-5 h-5" />
|
||||||
<% end %>
|
<% end %>
|
||||||
</button>
|
</button>
|
||||||
"""
|
"""
|
||||||
|
|
@ -168,7 +168,7 @@ defmodule Oban.Web.Queues.DetailInstanceComponent do
|
||||||
phx-target={@target}
|
phx-target={@target}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<Icons.pencil_square class="w-5 h-5" />
|
<Icons.icon name="icon-pencil-square" class="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ defmodule Oban.Web.Queues.TableComponent do
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div :if={Enum.empty?(@queues) and Enum.empty?(@checks)} class="py-16 px-6 text-center">
|
<div :if={Enum.empty?(@queues) and Enum.empty?(@checks)} class="py-16 px-6 text-center">
|
||||||
<Icons.queue_list class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
<Icons.icon name="icon-queue-list" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
||||||
<h3 class="mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100">No queues</h3>
|
<h3 class="mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100">No queues</h3>
|
||||||
<p class="mt-2 text-base text-gray-500 dark:text-gray-400 max-w-md mx-auto">
|
<p class="mt-2 text-base text-gray-500 dark:text-gray-400 max-w-md mx-auto">
|
||||||
Queues process jobs concurrently. They'll appear here once your Oban instance starts with queues configured.
|
Queues process jobs concurrently. They'll appear here once your Oban instance starts with queues configured.
|
||||||
|
|
@ -44,7 +44,7 @@ defmodule Oban.Web.Queues.TableComponent do
|
||||||
:if={Enum.empty?(@queues) and not Enum.empty?(@checks)}
|
:if={Enum.empty?(@queues) and not Enum.empty?(@checks)}
|
||||||
class="flex items-center justify-center py-12 space-x-2 text-lg text-gray-600 dark:text-gray-300"
|
class="flex items-center justify-center py-12 space-x-2 text-lg text-gray-600 dark:text-gray-300"
|
||||||
>
|
>
|
||||||
<Icons.no_symbol /> <span>No queues match the current filters.</span>
|
<Icons.icon name="icon-no-symbol" /> <span>No queues match the current filters.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="divide-y divide-gray-100 dark:divide-gray-800">
|
<ul class="divide-y divide-gray-100 dark:divide-gray-800">
|
||||||
|
|
@ -115,22 +115,25 @@ defmodule Oban.Web.Queues.TableComponent do
|
||||||
<span class="w-14 text-left tabular pl-2">{exec}/{limit}</span>
|
<span class="w-14 text-left tabular pl-2">{exec}/{limit}</span>
|
||||||
</span>
|
</span>
|
||||||
<div class="w-14 flex items-center justify-start space-x-1 text-gray-400 dark:text-gray-500">
|
<div class="w-14 flex items-center justify-start space-x-1 text-gray-400 dark:text-gray-500">
|
||||||
<Icons.globe
|
<Icons.icon
|
||||||
:if={Queue.global_limit?(@queue)}
|
:if={Queue.global_limit?(@queue)}
|
||||||
|
name="icon-globe"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
data-title="Global limit"
|
data-title="Global limit"
|
||||||
id={"#{@queue.name}-has-global"}
|
id={"#{@queue.name}-has-global"}
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
/>
|
/>
|
||||||
<Icons.arrow_trending_down
|
<Icons.icon
|
||||||
:if={Queue.rate_limit?(@queue)}
|
:if={Queue.rate_limit?(@queue)}
|
||||||
|
name="icon-arrow-trending-down"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
data-title="Rate limit"
|
data-title="Rate limit"
|
||||||
id={"#{@queue.name}-has-rate"}
|
id={"#{@queue.name}-has-rate"}
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
/>
|
/>
|
||||||
<Icons.view_columns
|
<Icons.icon
|
||||||
:if={Queue.partitioned?(@queue)}
|
:if={Queue.partitioned?(@queue)}
|
||||||
|
name="icon-view-columns"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
data-title="Partitioned"
|
data-title="Partitioned"
|
||||||
id={"#{@queue.name}-has-partition"}
|
id={"#{@queue.name}-has-partition"}
|
||||||
|
|
@ -203,24 +206,27 @@ defmodule Oban.Web.Queues.TableComponent do
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="w-20 pr-3 flex justify-center items-center space-x-1">
|
<div class="w-20 pr-3 flex justify-center items-center space-x-1">
|
||||||
<Icons.pause_circle
|
<Icons.icon
|
||||||
:if={Queue.all_paused?(@queue)}
|
:if={Queue.all_paused?(@queue)}
|
||||||
|
name="icon-pause-circle"
|
||||||
class="w-5 h-5"
|
class="w-5 h-5"
|
||||||
data-title="All paused"
|
data-title="All paused"
|
||||||
id={"#{@queue.name}-is-paused"}
|
id={"#{@queue.name}-is-paused"}
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
rel="is-paused"
|
rel="is-paused"
|
||||||
/>
|
/>
|
||||||
<Icons.play_pause_circle
|
<Icons.icon
|
||||||
:if={Queue.any_paused?(@queue) and not Queue.all_paused?(@queue)}
|
:if={Queue.any_paused?(@queue) and not Queue.all_paused?(@queue)}
|
||||||
|
name="icon-play-pause-circle"
|
||||||
class="w-5 h-5"
|
class="w-5 h-5"
|
||||||
data-title="Some paused"
|
data-title="Some paused"
|
||||||
id={"#{@queue.name}-is-some-paused"}
|
id={"#{@queue.name}-is-some-paused"}
|
||||||
phx-hook="Tippy"
|
phx-hook="Tippy"
|
||||||
rel="has-some-paused"
|
rel="has-some-paused"
|
||||||
/>
|
/>
|
||||||
<Icons.power
|
<Icons.icon
|
||||||
:if={Queue.terminating?(@queue)}
|
:if={Queue.terminating?(@queue)}
|
||||||
|
name="icon-power"
|
||||||
class="w-5 h-5"
|
class="w-5 h-5"
|
||||||
data-title="Terminating"
|
data-title="Terminating"
|
||||||
id={"#{@queue.name}-is-terminating"}
|
id={"#{@queue.name}-is-terminating"}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ defmodule Oban.Web.RefreshComponent do
|
||||||
phx-click={JS.toggle(to: "#refresh-menu")}
|
phx-click={JS.toggle(to: "#refresh-menu")}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<Icons.arrow_path_rounded />
|
<Icons.icon name="icon-arrow-path-rounded" />
|
||||||
<span class="ml-1 leading-6 text-sm">{:proplists.get_value(@refresh, @options)}</span>
|
<span class="ml-1 leading-6 text-sm">{:proplists.get_value(@refresh, @options)}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ defmodule Oban.Web.RefreshComponent do
|
||||||
phx-value-interval={@value}
|
phx-value-interval={@value}
|
||||||
>
|
>
|
||||||
<%= if @value == @refresh do %>
|
<%= if @value == @refresh do %>
|
||||||
<Icons.check class="w-5 h-5" />
|
<Icons.icon name="icon-check" class="w-5 h-5" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<span class="block w-5 h-5"></span>
|
<span class="block w-5 h-5"></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ defmodule Oban.Web.SearchComponent do
|
||||||
<%= if @loading do %>
|
<%= if @loading do %>
|
||||||
<Icons.spinner class="w-5 h-5 text-gray-200 animate-spin dark:text-gray-600 fill-violet-500" />
|
<Icons.spinner class="w-5 h-5 text-gray-200 animate-spin dark:text-gray-600 fill-violet-500" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<Icons.magnifying_glass class="w-5 h-5 text-gray-500" />
|
<Icons.icon name="icon-magnifying-glass" class="w-5 h-5 text-gray-500" />
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ defmodule Oban.Web.SearchComponent do
|
||||||
phx-click="clear"
|
phx-click="clear"
|
||||||
type="reset"
|
type="reset"
|
||||||
>
|
>
|
||||||
<Icons.x_circle class="w-5 h-5" />
|
<Icons.icon name="icon-x-circle" class="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<nav
|
<nav
|
||||||
|
|
@ -102,7 +102,7 @@ defmodule Oban.Web.SearchComponent do
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div :if={Enum.empty?(@suggestions)} class="w-full flex items-center space-x-2 p-1">
|
<div :if={Enum.empty?(@suggestions)} class="w-full flex items-center space-x-2 p-1">
|
||||||
<Icons.exclamation_circle class="w-5 h-5 text-gray-400" />
|
<Icons.icon name="icon-exclamation-circle" class="w-5 h-5 text-gray-400" />
|
||||||
<span class="text-gray-700">No suggestions matching <b>"{@buffer}"</b></span>
|
<span class="text-gray-700">No suggestions matching <b>"{@buffer}"</b></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -113,7 +113,7 @@ defmodule Oban.Web.SearchComponent do
|
||||||
title="Read the filtering and searching guide"
|
title="Read the filtering and searching guide"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<Icons.info_circle class="w-4 h-4" />
|
<Icons.icon name="icon-info-circle" class="w-4 h-4" />
|
||||||
<span class="text-xs">Filtering Tips</span>
|
<span class="text-xs">Filtering Tips</span>
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
@ -139,7 +139,7 @@ defmodule Oban.Web.SearchComponent do
|
||||||
phx-value-terms={@terms}
|
phx-value-terms={@terms}
|
||||||
phx-target="#search"
|
phx-target="#search"
|
||||||
>
|
>
|
||||||
<Icons.x_mark class="w-5 h-5" />
|
<Icons.icon name="icon-x-mark" class="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ defmodule Oban.Web.ShortcutsComponent do
|
||||||
class="absolute top-4 right-4 text-gray-400 hover:text-gray-600"
|
class="absolute top-4 right-4 text-gray-400 hover:text-gray-600"
|
||||||
aria-label="close"
|
aria-label="close"
|
||||||
>
|
>
|
||||||
<Icons.x_mark />
|
<Icons.icon name="icon-x-mark" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,11 @@ defmodule Oban.Web.ThemeComponent do
|
||||||
~H"""
|
~H"""
|
||||||
<%= case @theme do %>
|
<%= case @theme do %>
|
||||||
<% "light" -> %>
|
<% "light" -> %>
|
||||||
<Icons.sun />
|
<Icons.icon name="icon-sun" />
|
||||||
<% "dark" -> %>
|
<% "dark" -> %>
|
||||||
<Icons.moon />
|
<Icons.icon name="icon-moon" />
|
||||||
<% "system" -> %>
|
<% "system" -> %>
|
||||||
<Icons.computer_desktop />
|
<Icons.icon name="icon-computer-desktop" />
|
||||||
<% end %>
|
<% end %>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,10 @@ defmodule Oban.Web.Workflows.DetailComponent do
|
||||||
<% else %>
|
<% else %>
|
||||||
<div class="flex items-center justify-center py-16">
|
<div class="flex items-center justify-center py-16">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<Icons.rectangle_group class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
<Icons.icon
|
||||||
|
name="icon-rectangle-group"
|
||||||
|
class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500"
|
||||||
|
/>
|
||||||
<h3 class="mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100">
|
<h3 class="mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100">
|
||||||
Workflow not found
|
Workflow not found
|
||||||
</h3>
|
</h3>
|
||||||
|
|
@ -97,7 +100,7 @@ defmodule Oban.Web.Workflows.DetailComponent do
|
||||||
phx-hook="HistoryBack"
|
phx-hook="HistoryBack"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<Icons.arrow_left class="w-5 h-5" />
|
<Icons.icon name="icon-arrow-left" class="w-5 h-5" />
|
||||||
<span class="text-lg font-bold ml-2">{@workflow.name || @workflow.id}</span>
|
<span class="text-lg font-bold ml-2">{@workflow.name || @workflow.id}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -142,7 +145,7 @@ defmodule Oban.Web.Workflows.DetailComponent do
|
||||||
defp parent_breadcrumb(assigns) do
|
defp parent_breadcrumb(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="flex items-center ml-3 text-sm text-gray-500 dark:text-gray-400">
|
<div class="flex items-center ml-3 text-sm text-gray-500 dark:text-gray-400">
|
||||||
<Icons.arrow_turn_down_right class="w-4 h-4 mr-1" />
|
<Icons.icon name="icon-arrow-turn-down-right" class="w-4 h-4 mr-1" />
|
||||||
<span>sub-workflow of</span>
|
<span>sub-workflow of</span>
|
||||||
<.link
|
<.link
|
||||||
navigate={oban_path([:workflows, @parent.id])}
|
navigate={oban_path([:workflows, @parent.id])}
|
||||||
|
|
@ -233,10 +236,13 @@ defmodule Oban.Web.Workflows.DetailComponent do
|
||||||
phx-click="toggle-graph"
|
phx-click="toggle-graph"
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right class={[
|
<Icons.icon
|
||||||
"w-5 h-5 transition-transform",
|
name="icon-chevron-right"
|
||||||
@graph_open? && "rotate-90"
|
class={[
|
||||||
]} />
|
"w-5 h-5 transition-transform",
|
||||||
|
@graph_open? && "rotate-90"
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<span class="font-semibold">Workflow Graph</span>
|
<span class="font-semibold">Workflow Graph</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
@ -419,10 +425,13 @@ defmodule Oban.Web.Workflows.DetailComponent do
|
||||||
phx-click="toggle-subs"
|
phx-click="toggle-subs"
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
>
|
>
|
||||||
<Icons.chevron_right class={[
|
<Icons.icon
|
||||||
"w-5 h-5 transition-transform",
|
name="icon-chevron-right"
|
||||||
@subs_open? && "rotate-90"
|
class={[
|
||||||
]} />
|
"w-5 h-5 transition-transform",
|
||||||
|
@subs_open? && "rotate-90"
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<span class="font-semibold">
|
<span class="font-semibold">
|
||||||
Sub-workflows
|
Sub-workflows
|
||||||
<span class="text-gray-400 font-normal">
|
<span class="text-gray-400 font-normal">
|
||||||
|
|
@ -522,17 +531,17 @@ defmodule Oban.Web.Workflows.DetailComponent do
|
||||||
<span class="inline-flex">
|
<span class="inline-flex">
|
||||||
<%= case @state do %>
|
<%= case @state do %>
|
||||||
<% "executing" -> %>
|
<% "executing" -> %>
|
||||||
<Icons.play_circle class="w-5 h-5 text-emerald-400" />
|
<Icons.icon name="icon-play-circle" class="w-5 h-5 text-emerald-400" />
|
||||||
<% "completed" -> %>
|
<% "completed" -> %>
|
||||||
<Icons.check_circle class="w-5 h-5 text-cyan-400" />
|
<Icons.icon name="icon-check-circle" class="w-5 h-5 text-cyan-400" />
|
||||||
<% "retryable" -> %>
|
<% "retryable" -> %>
|
||||||
<Icons.arrow_path class="w-5 h-5 text-yellow-400" />
|
<Icons.icon name="icon-arrow-path" class="w-5 h-5 text-yellow-400" />
|
||||||
<% "cancelled" -> %>
|
<% "cancelled" -> %>
|
||||||
<Icons.x_circle class="w-5 h-5 text-violet-400" />
|
<Icons.icon name="icon-x-circle" class="w-5 h-5 text-violet-400" />
|
||||||
<% "discarded" -> %>
|
<% "discarded" -> %>
|
||||||
<Icons.exclamation_circle class="w-5 h-5 text-rose-400" />
|
<Icons.icon name="icon-exclamation-circle" class="w-5 h-5 text-rose-400" />
|
||||||
<% _ -> %>
|
<% _ -> %>
|
||||||
<Icons.minus_circle class="w-5 h-5 text-gray-400" />
|
<Icons.icon name="icon-minus-circle" class="w-5 h-5 text-gray-400" />
|
||||||
<% end %>
|
<% end %>
|
||||||
</span>
|
</span>
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,10 @@ defmodule Oban.Web.Workflows.TableComponent do
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div :if={Enum.empty?(@workflows)} class="py-16 px-6 text-center">
|
<div :if={Enum.empty?(@workflows)} class="py-16 px-6 text-center">
|
||||||
<Icons.rectangle_group class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
<Icons.icon
|
||||||
|
name="icon-rectangle-group"
|
||||||
|
class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500"
|
||||||
|
/>
|
||||||
<h3 class="mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100">No workflows</h3>
|
<h3 class="mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100">No workflows</h3>
|
||||||
<p class="mt-2 text-base text-gray-500 dark:text-gray-400 max-w-md mx-auto">
|
<p class="mt-2 text-base text-gray-500 dark:text-gray-400 max-w-md mx-auto">
|
||||||
Workflows coordinate jobs with dependencies. They'll appear here once jobs with workflow metadata are enqueued.
|
Workflows coordinate jobs with dependencies. They'll appear here once jobs with workflow metadata are enqueued.
|
||||||
|
|
@ -249,15 +252,15 @@ defmodule Oban.Web.Workflows.TableComponent do
|
||||||
<span data-title={status_title(@state)} id={"workflow-state-#{@id}"} phx-hook="Tippy">
|
<span data-title={status_title(@state)} id={"workflow-state-#{@id}"} phx-hook="Tippy">
|
||||||
<%= case @state do %>
|
<%= case @state do %>
|
||||||
<% :executing -> %>
|
<% :executing -> %>
|
||||||
<Icons.play_circle class="w-5 h-5 text-emerald-400" />
|
<Icons.icon name="icon-play-circle" class="w-5 h-5 text-emerald-400" />
|
||||||
<% :completed -> %>
|
<% :completed -> %>
|
||||||
<Icons.check_circle class="w-5 h-5 text-cyan-400" />
|
<Icons.icon name="icon-check-circle" class="w-5 h-5 text-cyan-400" />
|
||||||
<% :cancelled -> %>
|
<% :cancelled -> %>
|
||||||
<Icons.x_circle class="w-5 h-5 text-violet-400" />
|
<Icons.icon name="icon-x-circle" class="w-5 h-5 text-violet-400" />
|
||||||
<% :discarded -> %>
|
<% :discarded -> %>
|
||||||
<Icons.exclamation_circle class="w-5 h-5 text-rose-400" />
|
<Icons.icon name="icon-exclamation-circle" class="w-5 h-5 text-rose-400" />
|
||||||
<% _ -> %>
|
<% _ -> %>
|
||||||
<Icons.minus_circle class="w-5 h-5 text-gray-400" />
|
<Icons.icon name="icon-minus-circle" class="w-5 h-5 text-gray-400" />
|
||||||
<% end %>
|
<% end %>
|
||||||
</span>
|
</span>
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ defmodule Oban.Web.CronsPage do
|
||||||
"text-gray-400 dark:text-gray-500 border-gray-200 dark:border-gray-800 cursor-not-allowed opacity-50"
|
"text-gray-400 dark:text-gray-500 border-gray-200 dark:border-gray-800 cursor-not-allowed opacity-50"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Icons.plus_circle class="mr-1 h-4 w-4" /> New
|
<Icons.icon name="icon-plus-circle" class="mr-1 h-4 w-4" /> New
|
||||||
</.link>
|
</.link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
10
vendor/oban_web/lib/oban/web/pages/jobs_page.ex
vendored
|
|
@ -89,7 +89,7 @@ defmodule Oban.Web.JobsPage do
|
||||||
click="cancel-jobs"
|
click="cancel-jobs"
|
||||||
target={@myself}
|
target={@myself}
|
||||||
>
|
>
|
||||||
<:icon><Icons.x_circle class="w-5 h-5" /></:icon>
|
<:icon><Icons.icon name="icon-x-circle" class="w-5 h-5" /></:icon>
|
||||||
<:title>Cancel Jobs</:title>
|
<:title>Cancel Jobs</:title>
|
||||||
</Core.action_button>
|
</Core.action_button>
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ defmodule Oban.Web.JobsPage do
|
||||||
click="retry-jobs"
|
click="retry-jobs"
|
||||||
target={@myself}
|
target={@myself}
|
||||||
>
|
>
|
||||||
<:icon><Icons.arrow_right_circle class="w-5 h-5" /></:icon>
|
<:icon><Icons.icon name="icon-arrow-right-circle" class="w-5 h-5" /></:icon>
|
||||||
<:title>Retry Jobs</:title>
|
<:title>Retry Jobs</:title>
|
||||||
</Core.action_button>
|
</Core.action_button>
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ defmodule Oban.Web.JobsPage do
|
||||||
click="retry-jobs"
|
click="retry-jobs"
|
||||||
target={@myself}
|
target={@myself}
|
||||||
>
|
>
|
||||||
<:icon><Icons.arrow_right_circle class="w-5 h-5" /></:icon>
|
<:icon><Icons.icon name="icon-arrow-right-circle" class="w-5 h-5" /></:icon>
|
||||||
<:title>Run Jobs Now</:title>
|
<:title>Run Jobs Now</:title>
|
||||||
</Core.action_button>
|
</Core.action_button>
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ defmodule Oban.Web.JobsPage do
|
||||||
target={@myself}
|
target={@myself}
|
||||||
danger={true}
|
danger={true}
|
||||||
>
|
>
|
||||||
<:icon><Icons.trash class="w-5 h-5" /></:icon>
|
<:icon><Icons.icon name="icon-trash" class="w-5 h-5" /></:icon>
|
||||||
<:title>Delete Jobs</:title>
|
<:title>Delete Jobs</:title>
|
||||||
</Core.action_button>
|
</Core.action_button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -162,7 +162,7 @@ defmodule Oban.Web.JobsPage do
|
||||||
"text-gray-400 dark:text-gray-500 border-gray-200 dark:border-gray-800 cursor-not-allowed opacity-50"
|
"text-gray-400 dark:text-gray-500 border-gray-200 dark:border-gray-800 cursor-not-allowed opacity-50"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Icons.plus_circle class="mr-1 h-4 w-4" /> New
|
<Icons.icon name="icon-plus-circle" class="mr-1 h-4 w-4" /> New
|
||||||
</.link>
|
</.link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ defmodule Oban.Web.QueuesPage do
|
||||||
click="pause-queues"
|
click="pause-queues"
|
||||||
target={@myself}
|
target={@myself}
|
||||||
>
|
>
|
||||||
<:icon><Icons.pause_circle class="w-5 h-5" /></:icon>
|
<:icon><Icons.icon name="icon-pause-circle" class="w-5 h-5" /></:icon>
|
||||||
<:title>Pause Queues</:title>
|
<:title>Pause Queues</:title>
|
||||||
</Core.action_button>
|
</Core.action_button>
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ defmodule Oban.Web.QueuesPage do
|
||||||
click="resume-queues"
|
click="resume-queues"
|
||||||
target={@myself}
|
target={@myself}
|
||||||
>
|
>
|
||||||
<:icon><Icons.play_circle class="w-5 h-5" /></:icon>
|
<:icon><Icons.icon name="icon-play-circle" class="w-5 h-5" /></:icon>
|
||||||
<:title>Resume Queues</:title>
|
<:title>Resume Queues</:title>
|
||||||
</Core.action_button>
|
</Core.action_button>
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ defmodule Oban.Web.QueuesPage do
|
||||||
target={@myself}
|
target={@myself}
|
||||||
danger={true}
|
danger={true}
|
||||||
>
|
>
|
||||||
<:icon><Icons.x_circle class="w-5 h-5" /></:icon>
|
<:icon><Icons.icon name="icon-x-circle" class="w-5 h-5" /></:icon>
|
||||||
<:title>Stop Queues</:title>
|
<:title>Stop Queues</:title>
|
||||||
</Core.action_button>
|
</Core.action_button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ defmodule Oban.Web.WorkflowsPage do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="flex flex-col items-center justify-center py-16 px-6">
|
<div class="flex flex-col items-center justify-center py-16 px-6">
|
||||||
<div class="flex items-center justify-center w-16 h-16 rounded-full bg-violet-100 dark:bg-violet-900/30 mb-6">
|
<div class="flex items-center justify-center w-16 h-16 rounded-full bg-violet-100 dark:bg-violet-900/30 mb-6">
|
||||||
<Icons.rectangle_group class="w-8 h-8 text-violet-500 dark:text-violet-400" />
|
<Icons.icon name="icon-rectangle-group" class="w-8 h-8 text-violet-500 dark:text-violet-400" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-gray-100 mb-3">
|
<h2 class="text-2xl font-bold text-gray-900 dark:text-gray-100 mb-3">
|
||||||
|
|
@ -136,21 +136,21 @@ defmodule Oban.Web.WorkflowsPage do
|
||||||
|
|
||||||
<ul class="text-left text-gray-600 dark:text-gray-400 space-y-3 mb-8">
|
<ul class="text-left text-gray-600 dark:text-gray-400 space-y-3 mb-8">
|
||||||
<li class="flex items-start">
|
<li class="flex items-start">
|
||||||
<Icons.check class="w-5 h-5 text-violet-500 mr-2 mt-0.5 shrink-0" />
|
<Icons.icon name="icon-check" class="w-5 h-5 text-violet-500 mr-2 mt-0.5 shrink-0" />
|
||||||
<span>
|
<span>
|
||||||
<span class="font-medium text-gray-700 dark:text-gray-300">Fully Distributed</span>
|
<span class="font-medium text-gray-700 dark:text-gray-300">Fully Distributed</span>
|
||||||
— high availability and scalability across your infrastructure
|
— high availability and scalability across your infrastructure
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex items-start">
|
<li class="flex items-start">
|
||||||
<Icons.check class="w-5 h-5 text-violet-500 mr-2 mt-0.5 shrink-0" />
|
<Icons.icon name="icon-check" class="w-5 h-5 text-violet-500 mr-2 mt-0.5 shrink-0" />
|
||||||
<span>
|
<span>
|
||||||
<span class="font-medium text-gray-700 dark:text-gray-300">Cascading Context</span>
|
<span class="font-medium text-gray-700 dark:text-gray-300">Cascading Context</span>
|
||||||
— pass cumulative context between jobs for seamless data flow
|
— pass cumulative context between jobs for seamless data flow
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex items-start">
|
<li class="flex items-start">
|
||||||
<Icons.check class="w-5 h-5 text-violet-500 mr-2 mt-0.5 shrink-0" />
|
<Icons.icon name="icon-check" class="w-5 h-5 text-violet-500 mr-2 mt-0.5 shrink-0" />
|
||||||
<span>
|
<span>
|
||||||
<span class="font-medium text-gray-700 dark:text-gray-300">Nested Sub-Workflows</span>
|
<span class="font-medium text-gray-700 dark:text-gray-300">Nested Sub-Workflows</span>
|
||||||
— compose hierarchically for better organization and reusability
|
— compose hierarchically for better organization and reusability
|
||||||
|
|
@ -163,7 +163,7 @@ defmodule Oban.Web.WorkflowsPage do
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="inline-flex items-center px-5 py-2.5 rounded-lg bg-violet-600 hover:bg-violet-700 text-white font-medium transition-colors"
|
class="inline-flex items-center px-5 py-2.5 rounded-lg bg-violet-600 hover:bg-violet-700 text-white font-medium transition-colors"
|
||||||
>
|
>
|
||||||
Learn about Oban Pro <Icons.arrow_top_right_on_square class="w-4 h-4 ml-2" />
|
Learn about Oban Pro <Icons.icon name="icon-arrow-top-right-on-square" class="w-4 h-4 ml-2" />
|
||||||
</.link>
|
</.link>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,8 @@ defmodule Oban.Web.CronQuery do
|
||||||
query = select(Oban.Pro.Cron, [c], {c.expression, c.worker, c.opts, c.name, true, c.paused})
|
query = select(Oban.Pro.Cron, [c], {c.expression, c.worker, c.opts, c.name, true, c.paused})
|
||||||
|
|
||||||
Repo.all(conf, query)
|
Repo.all(conf, query)
|
||||||
|
else
|
||||||
|
[]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
1
vendor/oban_web/lib/oban/web/router.ex
vendored
|
|
@ -200,7 +200,6 @@ defmodule Oban.Web.Router do
|
||||||
get "/css-:md5", Oban.Web.Assets, :css, as: :oban_web_asset
|
get "/css-:md5", Oban.Web.Assets, :css, as: :oban_web_asset
|
||||||
get "/js-:md5", Oban.Web.Assets, :js, as: :oban_web_asset
|
get "/js-:md5", Oban.Web.Assets, :js, as: :oban_web_asset
|
||||||
get "/fonts/inter.woff2", Oban.Web.Assets, :font, as: :oban_web_font
|
get "/fonts/inter.woff2", Oban.Web.Assets, :font, as: :oban_web_font
|
||||||
get "/icons/*path", Oban.Web.Assets, :icon, as: :oban_web_icon
|
|
||||||
|
|
||||||
live "/", Oban.Web.DashboardLive, :home, route_opts
|
live "/", Oban.Web.DashboardLive, :home, route_opts
|
||||||
live "/:page", Oban.Web.DashboardLive, :index, route_opts
|
live "/:page", Oban.Web.DashboardLive, :index, route_opts
|
||||||
|
|
|
||||||
13
vendor/oban_web/lib/oban/web/utils.ex
vendored
|
|
@ -5,9 +5,9 @@ defmodule Oban.Web.Utils do
|
||||||
|
|
||||||
alias Oban.Repo
|
alias Oban.Repo
|
||||||
|
|
||||||
def has_crons?(conf), do: has_table?(conf, "oban_crons")
|
def has_crons?(conf), do: has_table?("oban_crons", conf)
|
||||||
|
|
||||||
def has_workflows?(conf), do: has_table?(conf, "oban_workflows")
|
def has_workflows?(conf), do: has_table?("oban_workflows", conf)
|
||||||
|
|
||||||
def has_pro? do
|
def has_pro? do
|
||||||
persistent_cache(:pro?, fn -> Code.ensure_loaded?(Oban.Pro) end)
|
persistent_cache(:pro?, fn -> Code.ensure_loaded?(Oban.Pro) end)
|
||||||
|
|
@ -20,10 +20,13 @@ defmodule Oban.Web.Utils do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp has_table?(conf, table_name) do
|
defp has_table?(_table_name, %{engine: Oban.Engines.Dolphin}), do: false
|
||||||
%{name: name, prefix: prefix} = conf
|
defp has_table?(_table_name, %{engine: Oban.Engines.Lite}), do: false
|
||||||
|
|
||||||
persistent_cache({:table?, name, table_name}, fn ->
|
defp has_table?(table_name, conf) do
|
||||||
|
%{name: oban_name, prefix: prefix} = conf
|
||||||
|
|
||||||
|
persistent_cache({:table?, oban_name, table_name}, fn ->
|
||||||
query =
|
query =
|
||||||
from("tables")
|
from("tables")
|
||||||
|> put_query_prefix("information_schema")
|
|> put_query_prefix("information_schema")
|
||||||
|
|
|
||||||
2
vendor/oban_web/mix.exs
vendored
|
|
@ -2,7 +2,7 @@ defmodule Oban.Web.MixProject do
|
||||||
use Mix.Project
|
use Mix.Project
|
||||||
|
|
||||||
@source_url "https://github.com/oban-bg/oban_web"
|
@source_url "https://github.com/oban-bg/oban_web"
|
||||||
@version "2.12.1"
|
@version "2.12.3"
|
||||||
|
|
||||||
def project do
|
def project do
|
||||||
[
|
[
|
||||||
|
|
|
||||||
2
vendor/oban_web/priv/static/app.css
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 380 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 13.5V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m12-3V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m-6-9V3.75m0 3.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 9.75V10.5"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 373 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 211 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12c0-1.232-.046-2.453-.138-3.662a4.006 4.006 0 00-3.7-3.7 48.678 48.678 0 00-7.324 0 4.006 4.006 0 00-3.7 3.7c-.017.22-.032.441-.046.662M19.5 12l3-3m-3 3l-3-3m-12 3c0 1.232.046 2.453.138 3.662a4.006 4.006 0 003.7 3.7 48.656 48.656 0 007.324 0 4.006 4.006 0 003.7-3.7c.017-.22.032-.441.046-.662M4.5 12l3 3m-3-3l-3 3"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 496 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 339 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12.75 15l3-3m0 0l-3-3m3 3h-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 241 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 211 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 302 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6L9 12.75l4.286-4.286a11.948 11.948 0 014.306 6.43l.776 2.898m0 0l3.182-5.511m-3.182 5.51l-5.511-3.181"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 284 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="m16.49 12 3.75 3.75m0 0-3.75 3.75m3.75-3.75H3.74V4.499" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 253 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3 4.5h14.25M3 9h9.75M3 13.5h9.75m4.5-4.5v12m0 0l-3.75-3.75M17.25 21L21 17.25"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 253 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.25-.75L17.25 9m0 0L21 12.75M17.25 9v12"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 250 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.317 6.066a.648.648 0 0 1 .337.703l-.683 3.517h3.404c.245 0 .467.147.568.375a.657.657 0 0 1-.096.688l-5.416 6.43a.613.613 0 0 1-.747.155.648.648 0 0 1-.338-.702l.683-3.518H7.625a.624.624 0 0 1-.568-.375.657.657 0 0 1 .096-.688l5.416-6.43a.613.613 0 0 1 .748-.155ZM21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 479 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M11.412 15.655 9.75 21.75l3.745-4.012M9.257 13.5H3.75l2.659-2.849m2.048-2.194L14.25 2.25 12 10.5h8.25l-4.707 5.043M8.457 8.457 3 3m5.457 5.457 7.086 7.086m0 0L21 21"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 340 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5m-9-6h.008v.008H12v-.008zM12 15h.008v.008H12V15zm0 2.25h.008v.008H12v-.008zM9.75 15h.008v.008H9.75V15zm0 2.25h.008v.008H9.75v-.008zM7.5 15h.008v.008H7.5V15zm0 2.25h.008v.008H7.5v-.008zm6.75-4.5h.008v.008h-.008v-.008zm0 2.25h.008v.008h-.008V15zm0 2.25h.008v.008h-.008v-.008zm2.25-4.5h.008v.008H16.5v-.008zm0 2.25h.008v.008H16.5V15z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 719 B |
|
|
@ -1,4 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 015.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 00-1.134-.175 2.31 2.31 0 01-1.64-1.055l-.822-1.316a2.192 2.192 0 00-1.736-1.039 48.774 48.774 0 00-5.232 0 2.192 2.192 0 00-1.736 1.039l-.821 1.316z"/>
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zM18.75 10.5h.008v.008h-.008V10.5z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 669 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M7.5 14.25v2.25m3-4.5v4.5m3-6.75v6.75m3-9v9M6 20.25h12A2.25 2.25 0 0020.25 18V6A2.25 2.25 0 0018 3.75H6A2.25 2.25 0 003.75 6v12A2.25 2.25 0 006 20.25z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 326 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 235 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 197 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 203 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 226 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 201 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 202 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 567 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 221 B |
|
|
@ -1,4 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 0 1 1.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.559.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.894.149c-.424.07-.764.383-.929.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 0 1-1.449.12l-.738-.527c-.35-.25-.806-.272-1.203-.107-.398.165-.71.505-.781.929l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 0 1-.12-1.45l.527-.737c.25-.35.272-.806.108-1.204-.165-.397-.506-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.108-1.204l-.526-.738a1.125 1.125 0 0 1 .12-1.45l.773-.773a1.125 1.125 0 0 1 1.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894Z"/>
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12a7.5 7.5 0 0015 0m-15 0a7.5 7.5 0 1115 0m-15 0H3m16.5 0H21m-1.5 0H12m-8.457 3.077l1.41-.513m14.095-5.13l1.41-.513M5.106 17.785l1.15-.964m11.49-9.642l1.149-.964M7.501 19.795l.75-1.3m7.5-12.99l.75-1.3m-6.063 16.658l.26-1.477m2.605-14.772l.26-1.477m0 17.726l-.26-1.477M10.698 4.614l-.26-1.477M16.5 19.794l-.75-1.299M7.5 4.205L12 12m6.894 5.785l-1.149-.964M6.256 7.178l-1.15-.964m15.352 8.864l-1.41-.513M4.954 9.435l-1.41-.514M12.002 12l-3.75 6.495"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 627 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0021 18V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v12a2.25 2.25 0 002.25 2.25z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 318 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 17.25v1.007a3 3 0 01-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0115 18.257V17.25m6-12V15a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15V5.25m18 0A2.25 2.25 0 0018.75 3H5.25A2.25 2.25 0 003 5.25m18 0V12a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 12V5.25"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 431 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8.625 12a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H8.25m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H12m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0h-.375M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 393 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 248 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 637 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M5.25 8.25h15m-16.5 7.5h15m-1.8-13.5l-3.9 19.5m-2.1-19.5l-3.9 19.5"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 242 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<line stroke-linecap="round" stroke-linejoin="round" x1="5" x2="19" y1="12" y2="12"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 202 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 322 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.712 4.33a9.027 9.027 0 0 1 1.652 1.306c.51.51.944 1.064 1.306 1.652M16.712 4.33l-3.448 4.138m3.448-4.138a9.014 9.014 0 0 0-9.424 0M19.67 7.288l-4.138 3.448m4.138-3.448a9.014 9.014 0 0 1 0 9.424m-4.138-5.976a3.736 3.736 0 0 0-.88-1.388 3.737 3.737 0 0 0-1.388-.88m2.268 2.268a3.765 3.765 0 0 1 0 2.528m-2.268-4.796a3.765 3.765 0 0 0-2.528 0m4.796 4.796c-.181.506-.475.982-.88 1.388a3.736 3.736 0 0 1-1.388.88m2.268-2.268 4.138 3.448m0 0a9.027 9.027 0 0 1-1.306 1.652c-.51.51-1.064.944-1.652 1.306m0 0-3.448-4.138m3.448 4.138a9.014 9.014 0 0 1-9.424 0m5.976-4.138a3.765 3.765 0 0 1-2.528 0m0 0a3.736 3.736 0 0 1-1.388-.88 3.737 3.737 0 0 1-.88-1.388m2.268 2.268L7.288 19.67m0 0a9.024 9.024 0 0 1-1.652-1.306 9.027 9.027 0 0 1-1.306-1.652m0 0 4.138-3.448M4.33 16.712a9.014 9.014 0 0 1 0-9.424m4.138 5.976a3.765 3.765 0 0 1 0-2.528m0 0c.181-.506.475-.982.88-1.388a3.736 3.736 0 0 1 1.388-.88m-2.268 2.268L4.33 7.288m6.406 1.18L7.288 4.33m0 0a9.024 9.024 0 0 0-1.652 1.306A9.025 9.025 0 0 0 4.33 7.288"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 368 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 344 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 250 B |
|
|
@ -1,4 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z"/>
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 348 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 217 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path d="M17.715 15.15A6.5 6.5 0 0 1 9 6.035C6.106 6.922 4 9.645 4 12.867c0 3.94 3.153 7.136 7.042 7.136 3.101 0 5.734-2.032 6.673-4.853Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 257 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 270 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14.25 9v6m-4.5 0V9M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 232 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 432 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path d="M6 4h12.5a2 2 0 0 1 2 2v12.5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm2 13 9-9m-6.313 2.125a.563.563 0 1 1-1.125 0 .563.563 0 0 1 1.126 0Zm4.75 4.75a.562.562 0 1 1-1.124 0 .562.562 0 0 1 1.124 0Z" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 377 B |
|
|
@ -1,4 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 392 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path d="M17 9v6m-2.455-6v6M7 14.32V9.68c0-.494.509-.803.918-.558l3.877 2.32c.191.115.31.328.31.559 0 .23-.119.443-.31.558l-3.877 2.32a.59.59 0 0 1-.613-.002.65.65 0 0 1-.305-.556h0ZM12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 386 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 222 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M5.636 5.636a9 9 0 1 0 12.728 0M12 3v9"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 214 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 398 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 12h16.5m-16.5 3.75h16.5M3.75 19.5h16.5M5.625 4.5h12.75a1.875 1.875 0 0 1 0 3.75H5.625a1.875 1.875 0 0 1 0-3.75Z" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 316 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 7.125C2.25 6.504 2.754 6 3.375 6h6c.621 0 1.125.504 1.125 1.125v3.75c0 .621-.504 1.125-1.125 1.125h-6a1.125 1.125 0 01-1.125-1.125v-3.75zM14.25 8.625c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125v8.25c0 .621-.504 1.125-1.125 1.125h-5.25a1.125 1.125 0 01-1.125-1.125v-8.25zM3.75 16.125c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125v2.25c0 .621-.504 1.125-1.125 1.125h-5.25a1.125 1.125 0 01-1.125-1.125v-2.25z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 623 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.813 15.904 9 18.75l-.813-2.846a4.5 4.5 0 0 0-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 0 0 3.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 0 0 3.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 0 0-3.09 3.09ZM18.259 8.715 18 9.75l-.259-1.035a3.375 3.375 0 0 0-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 0 0 2.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 0 0 2.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 0 0-2.456 2.456ZM16.894 20.567 16.5 21.75l-.394-1.183a2.25 2.25 0 0 0-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 0 0 1.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 0 0 1.423 1.423l1.183.394-1.183.394a2.25 2.25 0 0 0-1.423 1.423Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 787 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-2.25A2.25 2.25 0 0113.5 18v-2.25z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 650 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6.429 9.75L2.25 12l4.179 2.25m0-4.5l5.571 3 5.571-3m-11.142 0L2.25 7.5 12 2.25l9.75 5.25-4.179 2.25m0 0L21.75 12l-4.179 2.25m0 0l4.179 2.25L12 21.75 2.25 16.5l4.179-2.25m11.142 0l-5.571 3-5.571-3"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 372 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 369 B |