Packages

phoenix_kit

1.7.145
1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps β€” SaaS, social networks, ERP systems, marketplaces, and more

Current section

221 Versions

Jump to

Compare versions

15 files changed
+924 additions
-262 deletions
unknownCHANGELOG.md
File is too large to be displayed (100 KB limit).
  @@ -1,6 +1,6 @@
1 1 {<<"links">>,[{<<"GitHub">>,<<"https://github.com/BeamLabEU/phoenix_kit">>}]}.
2 2 {<<"name">>,<<"phoenix_kit">>}.
3 - {<<"version">>,<<"1.7.144">>}.
3 + {<<"version">>,<<"1.7.145">>}.
4 4 {<<"description">>,
5 5 <<65,32,102,111,117,110,100,97,116,105,111,110,32,102,111,114,32,98,117,105,
6 6 108,100,105,110,103,32,69,108,105,120,105,114,32,80,104,111,101,110,105,
  @@ -549,6 +549,7 @@
549 549 <<"lib/phoenix_kit/migrations/postgres/v124.ex">>,
550 550 <<"lib/phoenix_kit/migrations/postgres/v64.ex">>,
551 551 <<"lib/phoenix_kit/migrations/postgres/v93.ex">>,
552 + <<"lib/phoenix_kit/migrations/postgres/v133.ex">>,
552 553 <<"lib/phoenix_kit/migrations/postgres/v84.ex">>,
553 554 <<"lib/phoenix_kit/migrations/postgres/v73.ex">>,
554 555 <<"lib/phoenix_kit/migrations/postgres/v03.ex">>,
  @@ -591,6 +592,7 @@
591 592 <<"lib/phoenix_kit/migrations/postgres/v123.ex">>,
592 593 <<"lib/phoenix_kit/migrations/postgres/v94.ex">>,
593 594 <<"lib/phoenix_kit/migrations/postgres/v63.ex">>,
595 + <<"lib/phoenix_kit/migrations/postgres/v134.ex">>,
594 596 <<"lib/phoenix_kit/migrations/postgres/v74.ex">>,
595 597 <<"lib/phoenix_kit/migrations/postgres/v83.ex">>,
596 598 <<"lib/phoenix_kit/migrations/postgres/v04.ex">>,
  @@ -19,6 +19,20 @@ defmodule PhoenixKit.Modules.Storage.Folder do
19 19 field :description, :string
20 20 field :color, :string, default: "default"
21 21 field :trashed_at, :utc_datetime
22 + # Folder hero-header customization. The cover (background) and logo (icon)
23 + # are media files living in the folder, excluded from its visible listing.
24 + # `header_size` is small/medium/large; the `header_show_*` flags toggle each
25 + # header element. All defaulted so existing folders render as before.
26 + field :cover_file_uuid, UUIDv7
27 + field :logo_file_uuid, UUIDv7
28 + field :header_size, :string, default: "medium"
29 + field :header_show_title, :boolean, default: true
30 + field :header_show_icon, :boolean, default: true
31 + field :header_show_creator, :boolean, default: true
32 + field :header_show_date, :boolean, default: true
33 + field :header_show_file_count, :boolean, default: true
34 + field :header_show_description, :boolean, default: true
35 + field :header_show_background, :boolean, default: true
22 36
23 37 belongs_to :parent, __MODULE__,
24 38 foreign_key: :parent_uuid,
  @@ -47,9 +61,27 @@ defmodule PhoenixKit.Modules.Storage.Folder do
47 61
48 62 def changeset(folder, attrs) do
49 63 folder
50 - |> cast(attrs, [:name, :description, :parent_uuid, :user_uuid, :color, :trashed_at])
64 + |> cast(attrs, [
65 + :name,
66 + :description,
67 + :parent_uuid,
68 + :user_uuid,
69 + :color,
70 + :trashed_at,
71 + :cover_file_uuid,
72 + :logo_file_uuid,
73 + :header_size,
74 + :header_show_title,
75 + :header_show_icon,
76 + :header_show_creator,
77 + :header_show_date,
78 + :header_show_file_count,
79 + :header_show_description,
80 + :header_show_background
81 + ])
51 82 |> validate_required([:name])
52 83 |> validate_inclusion(:color, @folder_colors)
84 + |> validate_inclusion(:header_size, ~w(small medium large))
53 85 |> validate_length(:name, min: 1, max: 255)
54 86 |> validate_length(:description, max: 2000)
55 87 |> foreign_key_constraint(:parent_uuid)
unknownlib/modules/storage/storage.ex
File is too large to be displayed (100 KB limit).
  @@ -12,50 +12,11 @@
12 12 title={gettext("Media Settings")}
13 13 subtitle={
14 14 gettext(
15 - "Configure media storage buckets and file processing settings for your application"
15 + "Media is a core system module that is always enabled and cannot be disabled β€” it provides essential file management functionality across PhoenixKit. Configure its storage buckets and file processing settings here."
16 16 )
17 17 }
18 18 />
19 19
20 - <%!-- Module Status Alert --%>
21 - <div class="alert alert-info mb-6">
22 - <.icon name="hero-information-circle" class="w-5 h-5" />
23 - <div>
24 - <h3 class="font-bold">{gettext("Core System Module")}</h3>
25 - <p class="text-sm">
26 - {gettext("Media is a core system module that is always enabled and cannot be disabled.")}
27 - {gettext("It provides essential file management functionality across PhoenixKit.")}
28 - </p>
29 - </div>
30 - </div>
31 -
32 - <%!-- Repair Media Module Section --%>
33 - <div class="alert alert-warning mb-6">
34 - <.icon name="hero-wrench-screwdriver" class="w-5 h-5" />
35 - <div class="flex-1">
36 - <h3 class="font-bold">{gettext("Media Module Repair")}</h3>
37 - <p class="text-sm">
38 - {gettext(
39 - "If your media module isn't working correctly, use this to reset configuration to defaults."
40 - )}
41 - {gettext("This will NOT delete any uploaded files.")}
42 - </p>
43 - </div>
44 - <button
45 - phx-click="repair_storage_module"
46 - data-confirm={
47 - gettext(
48 - "This will reset dimensions and settings to defaults, and create a local bucket if none exist. Your uploaded files will NOT be deleted. Continue?"
49 - )
50 - }
51 - class="btn btn-warning btn-sm"
52 - >
53 - <.icon name="hero-wrench-screwdriver" class="w-4 h-4 mr-1" /> {gettext(
54 - "Repair Media Module"
55 - )}
56 - </button>
57 - </div>
58 -
59 20 <%!-- System Dependencies Check --%>
60 21 <%= if match?({:error, :not_installed}, @imagemagick_status) do %>
61 22 <div class="alert alert-error mb-6">
  @@ -503,122 +464,109 @@
503 464 <%!-- Quick Actions --%>
504 465 <div class="divider">{gettext("Quick Actions")}</div>
505 466
467 + <%!--
468 + Each action is wrapped in a daisyUI tooltip (rather than putting the
469 + tooltip on the button) so the hover description also works on the
470 + disabled "Media Stats" button β€” a disabled button has
471 + `pointer-events: none` and would otherwise swallow hover. Each button
472 + also carries a trailing info icon as the visible "what does this do?"
473 + affordance.
474 + --%>
506 475 <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
507 - <.link
508 - navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions")}
509 - class="btn btn-outline"
476 + <%!-- Manage Dimensions --%>
477 + <div
478 + class="tooltip tooltip-bottom"
479 + data-tip={
480 + gettext(
481 + "Create and edit the image/video size presets used to generate variants of uploaded media."
482 + )
483 + }
510 484 >
511 - <.icon name="hero-photo" class="w-4 h-4 mr-2" /> {gettext("Manage Dimensions")}
512 - </.link>
485 + <.link
486 + navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions")}
487 + class="btn btn-outline w-full"
488 + >
489 + <.icon name="hero-photo" class="w-4 h-4 mr-2" /> {gettext("Manage Dimensions")}
490 + <.icon name="hero-information-circle" class="w-4 h-4 ml-1 opacity-50" />
491 + </.link>
492 + </div>
513 493
514 - <button class="btn btn-outline" disabled>
515 - <.icon name="hero-chart-bar" class="w-4 h-4 mr-2" /> {gettext("Media Stats")}
516 - <span class="badge badge-xs ml-1">{gettext("Soon")}</span>
517 - </button>
518 -
519 - <.link
520 - navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media/health")}
521 - class="btn btn-outline"
494 + <%!-- Media Stats (coming soon) --%>
495 + <div
496 + class="tooltip tooltip-bottom"
497 + data-tip={gettext("View storage usage and media statistics. Coming soon.")}
522 498 >
523 - <.icon name="hero-arrow-path" class="w-4 h-4 mr-2" /> {gettext("Sync Files")}
524 - </.link>
525 - </div>
526 - </div>
527 - </div>
528 -
529 - <%!-- Coming Soon Features --%>
530 - <div class="card bg-base-100 shadow-xl border-2 border-dashed border-base-300">
531 - <div class="card-body">
532 - <h2 class="card-title text-2xl mb-4">
533 - <.icon name="hero-rocket-launch" class="w-6 h-6 mr-2" /> {gettext(
534 - "Advanced Features Coming Soon"
535 - )}
536 - </h2>
537 -
538 - <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
539 - <%!-- Multi-Location Media Storage --%>
540 - <div class="border border-base-300 rounded-lg p-4">
541 - <div class="flex items-start gap-3">
542 - <div class="text-3xl">πŸ—‚οΈ</div>
543 - <div>
544 - <h3 class="font-bold mb-1">{gettext("Multi-Location Media Storage")}</h3>
545 - <p class="text-sm text-base-content/70">
546 - {gettext("Store files across 1-5 redundant locations with automatic failover")}
547 - </p>
548 - </div>
549 - </div>
499 + <button class="btn btn-outline w-full" disabled>
500 + <.icon name="hero-chart-bar" class="w-4 h-4 mr-2" /> {gettext("Media Stats")}
501 + <span class="badge badge-xs ml-1">{gettext("Soon")}</span>
502 + <.icon name="hero-information-circle" class="w-4 h-4 ml-1 opacity-50" />
503 + </button>
550 504 </div>
551 505
552 - <%!-- S3 Integration --%>
553 - <div class="border border-base-300 rounded-lg p-4">
554 - <div class="flex items-start gap-3">
555 - <div class="text-3xl">☁️</div>
556 - <div>
557 - <h3 class="font-bold mb-1">{gettext("AWS S3 Integration")}</h3>
558 - <p class="text-sm text-base-content/70">
559 - {gettext("Store files in Amazon S3 buckets for cloud redundancy")}
560 - </p>
561 - </div>
562 - </div>
506 + <%!-- Sync Files / Health dashboard --%>
507 + <div
508 + class="tooltip tooltip-bottom"
509 + data-tip={
510 + gettext(
511 + "Open the media health dashboard to check file redundancy and re-sync files across storage locations."
512 + )
513 + }
514 + >
515 + <.link
516 + navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media/health")}
517 + class="btn btn-outline w-full"
518 + >
519 + <.icon name="hero-arrow-path" class="w-4 h-4 mr-2" /> {gettext("Sync Files")}
520 + <.icon name="hero-information-circle" class="w-4 h-4 ml-1 opacity-50" />
521 + </.link>
563 522 </div>
564 523
565 - <%!-- Remote Servers --%>
566 - <div class="border border-base-300 rounded-lg p-4">
567 - <div class="flex items-start gap-3">
568 - <div class="text-3xl">πŸ–₯️</div>
569 - <div>
570 - <h3 class="font-bold mb-1">{gettext("Remote Servers")}</h3>
571 - <p class="text-sm text-base-content/70">
572 - {gettext("Distribute files across multiple remote servers and datacenters")}
573 - </p>
574 - </div>
575 - </div>
524 + <%!-- Find Orphaned Files --%>
525 + <div
526 + class="tooltip tooltip-bottom"
527 + data-tip={
528 + gettext(
529 + "Browse files no longer attached to any record (orphaned media) so you can review or delete them."
530 + )
531 + }
532 + >
533 + <.link
534 + navigate={PhoenixKit.Utils.Routes.path("/admin/media") <> "?orphaned=1"}
535 + class="btn btn-outline w-full"
536 + >
537 + <.icon name="hero-funnel" class="w-4 h-4 mr-2" /> {gettext("Find Orphaned Files")}
538 + <.icon name="hero-information-circle" class="w-4 h-4 ml-1 opacity-50" />
539 + </.link>
576 540 </div>
577 541
578 - <%!-- Admin Dashboard --%>
579 - <div class="border border-base-300 rounded-lg p-4">
580 - <div class="flex items-start gap-3">
581 - <div class="text-3xl">πŸ“Š</div>
582 - <div>
583 - <h3 class="font-bold mb-1">{gettext("Admin Dashboard")}</h3>
584 - <p class="text-sm text-base-content/70">
585 - {gettext("Monitor media health, locations, and file distribution")}
586 - </p>
587 - </div>
588 - </div>
589 - </div>
590 -
591 - <%!-- File Tracking --%>
592 - <div class="border border-base-300 rounded-lg p-4">
593 - <div class="flex items-start gap-3">
594 - <div class="text-3xl">πŸ“‹</div>
595 - <div>
596 - <h3 class="font-bold mb-1">{gettext("File Tracking")}</h3>
597 - <p class="text-sm text-base-content/70">
598 - {gettext("PostgreSQL-based file registry with location tracking")}
599 - </p>
600 - </div>
601 - </div>
602 - </div>
603 -
604 - <%!-- Automatic Failover --%>
605 - <div class="border border-base-300 rounded-lg p-4">
606 - <div class="flex items-start gap-3">
607 - <div class="text-3xl">πŸ”„</div>
608 - <div>
609 - <h3 class="font-bold mb-1">{gettext("Automatic Failover")}</h3>
610 - <p class="text-sm text-base-content/70">
611 - {gettext("Seamless file retrieval even when media locations fail")}
612 - </p>
613 - </div>
614 - </div>
542 + <%!-- Repair Media Module --%>
543 + <div
544 + class="tooltip tooltip-bottom"
545 + data-tip={
546 + gettext(
547 + "Reset dimensions and settings to defaults and create a local bucket if none exist. Does not delete uploaded files."
548 + )
549 + }
550 + >
551 + <button
552 + phx-click="repair_storage_module"
553 + data-confirm={
554 + gettext(
555 + "This will reset dimensions and settings to defaults, and create a local bucket if none exist. Your uploaded files will NOT be deleted. Continue?"
556 + )
557 + }
558 + class="btn btn-outline btn-warning w-full"
559 + >
560 + <.icon name="hero-wrench-screwdriver" class="w-4 h-4 mr-2" /> {gettext(
561 + "Repair Media Module"
562 + )}
563 + <.icon name="hero-information-circle" class="w-4 h-4 ml-1 opacity-50" />
564 + </button>
615 565 </div>
616 566 </div>
617 567 </div>
618 568 </div>
619 569
620 - <%!-- Upload Test Section --%>
621 -
622 570 <%!-- Help Section --%>
623 571 <div class="alert mt-6">
624 572 <.icon name="hero-light-bulb" class="w-5 h-5" />
Loading more files…