Skip to content

Commit

Permalink
boundary ux
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanminutillo committed Nov 18, 2024
1 parent c4d43dd commit 7a33d2c
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 195 deletions.
2 changes: 1 addition & 1 deletion lib/web/boundaries_live_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ defmodule Bonfire.Boundaries.LiveHandler do
(circles || [])
|> Enum.map(fn
{circle, roles} ->
Enum.map(roles, &{e(known_circles, id(circle), nil) || circle, &1})
Enum.map(roles, &{ed(known_circles, id(circle), nil) || circle, &1})
end)
|> List.flatten()
|> debug("computed")
Expand Down
3 changes: 1 addition & 2 deletions lib/web/components/acls/acl_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@ defmodule Bonfire.UI.Boundaries.Web.AclLive do
end
end

def handle_event("edit_grant_role", %{"to_circles" => subjects} = _attrs, socket) do
# debug(attrs)
def handle_event("edit_grant_role", %{"to_circles" => subjects} = attrs, socket) do
current_user = current_user_required!(socket)
acl = e(assigns(socket), :acl, nil)
scope = e(assigns(socket), :scope, nil)
Expand Down
183 changes: 93 additions & 90 deletions lib/web/components/acls/acl_live.sface
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
</section>
{#match nil}
<div>
<div :if={!@setting_boundaries} class="p-4 border-b border-base-content/10">
<div
:if={!@setting_boundaries && e(@acl, :extra_info, :summary, nil)}
class="p-4 border-b border-base-content/10"
>
<span class="text-base-content/70">
{e(@acl, :extra_info, :summary, "No description provided for this boundary preset.")}
</span>
Expand Down Expand Up @@ -76,109 +79,109 @@
<form id="edit_grants" :on-change="edit_grant_role">
<ul class="flex flex-col divide-y divide-base-content/10">
<li
x-data="{open: false}"
:for={{{subject_id, %{subject: subject, grants: grants} = _subject_verb_grants}, _i} <-
Enum.with_index(@feed_by_subject || [])}
class="flex items-center justify-between p-4"
class="flex flex-col"
>
{#if e(subject, :profile, :id, nil)}
<StatelessComponent
module={maybe_component(Bonfire.UI.Me.ProfileItemLive)}
profile={e(subject, :profile, nil)}
avatar_class="w-10 h-10 rounded-full"
character={e(subject, :character, nil)}
show_controls={[]}
with_summary
/>
{#else}
<div class="flex items-center gap-3">
<span class="flex items-center w-10 h-10 rounded-full place-content-center bg-info/10">
<#Icon iconify="pajamas:group" class="inline-block w-5 h-5 text-base-content" />
</span>
<div class="flex flex-col">
<div class="text-base truncate max-w-[160px] font-semibold text-base-content">{LiveHandler.subject_name(subject)}</div>
<!-- <div class="text-sm truncate max-w-[160px] text-base-content/70">{LiveHandler.subject_summary(subject)}</div> -->
</div>
</div>
{/if}

<div class="flex items-center gap-2">
{#if !@read_only}
<Bonfire.UI.Boundaries.Web.RolesDropdownLive
circle_id={subject_id}
scope={@scope}
usage={@usage}
setting_boundaries={@setting_boundaries}
role={Bonfire.Boundaries.Roles.role_from_grants(Map.values(grants || %{}),
scope: @scope,
current_user: current_user(@__context__)
)
|> debug("the role")}
extra_roles={[{:custom, l("Custom")}]}
no_actions
<div class="flex items-center justify-between p-4">
{#if e(subject, :profile, :id, nil)}
<StatelessComponent
module={maybe_component(Bonfire.UI.Me.ProfileItemLive)}
profile={e(subject, :profile, nil)}
avatar_class="w-10 h-10 rounded-full"
character={e(subject, :character, nil)}
show_controls={[]}
with_summary
/>

<Bonfire.UI.Common.OpenModalLive
id={"remove_from_acl_#{uid(subject)}"}
title_text={l("Remove from boundary preset")}
no_actions
open_btn_wrapper_class="flex flex-1 w-full"
>
<div class="prose prose-sm mt-2">
{l("Are you sure to remove %{subject_name} from '%{boundary_name}' boundary preset?",
subject_name: LiveHandler.subject_name(subject),
boundary_name: e(@acl, :named, :name, nil) || e(@acl, :stereotyped, :named, :name, nil)
)}
</div>
<button
data-role="remove_from_boundary_btn"
phx-click={JS.push("remove_from_acl",
value: %{
subject_id: subject_id
},
target: @myself
)}
class="w-full mt-3 normal-case btn btn-error"
type="button"
>
{l("Remove")}
</button>
<:open_btn>
<button type="button" data-role="remove_from_boundary_modal" class="btn-outline btn btn-circle">
<#Icon iconify="ic:baseline-minus" class="w-4 h-4" />
</button>
</:open_btn>
</Bonfire.UI.Common.OpenModalLive>
{#else}
<button type="disabled" disabled class="btn btn-disabled btn-sm">
{Bonfire.Boundaries.Roles.role_from_grants(Map.values(grants || %{}),
scope: @scope,
current_user: current_user(@__context__),
fallback_to_list: true
<div class="flex items-center gap-3">
<span class="flex items-center w-10 h-10 rounded-full place-content-center bg-info/10">
<#Icon iconify="pajamas:group" class="inline-block w-5 h-5 text-base-content" />
</span>
<div class="flex flex-col">
<div class="text-base truncate max-w-[160px] font-semibold text-base-content">{LiveHandler.subject_name(subject)}</div>
<!-- <div class="text-sm truncate max-w-[160px] text-base-content/70">{LiveHandler.subject_summary(subject)}</div> -->
</div>
</div>
{/if}

<div class="flex items-center gap-2">
<button x-on:click="open = !open" type="button" x-cloak class="btn btn-neutral btn-sm">
{Recase.to_title(
to_string(
Bonfire.Boundaries.Roles.role_from_grants(Map.values(grants || %{}),
scope: @scope,
current_user: current_user(@__context__)
)
)
)}
</button>
{/if}
{#if !@read_only}
<span>
<Bonfire.UI.Common.OpenModalLive
id={"remove_from_acl_#{uid(subject)}"}
title_text={l("Remove from boundary preset")}
no_actions
open_btn_wrapper_class="flex flex-1 w-full"
>
<div class="prose prose-sm mt-2">
{l("Are you sure to remove %{subject_name} from '%{boundary_name}' boundary preset?",
subject_name: LiveHandler.subject_name(subject),
boundary_name: e(@acl, :named, :name, nil) || e(@acl, :stereotyped, :named, :name, nil)
)}
</div>
<button
data-role="remove_from_boundary_btn"
phx-click={JS.push("remove_from_acl",
value: %{
subject_id: subject_id
},
target: @myself
)}
class="w-full mt-3 normal-case btn btn-error"
type="button"
>
{l("Remove")}
</button>
<:open_btn>
<button
type="button"
data-role="remove_from_boundary_modal"
class="btn-outline btn-xs btn btn-circle"
>
<#Icon iconify="ic:baseline-minus" class="w-4 h-4" />
</button>
</:open_btn>
</Bonfire.UI.Common.OpenModalLive>
</span>
{/if}
</div>
</div>
<div x-show="open" x-cloak x-collapse class="mt-0 m-3 p-3 rounded-lg shadow bg-base-content/5">
<div class="font-semibold text-sm text-base-content/70 py-2 pb-4">{l("Assign a role to %{subject_name}", subject_name: LiveHandler.subject_name(subject))}</div>
<Bonfire.UI.Boundaries.Web.TabledRolesLive
id={LiveHandler.subject_name(subject)}
scope={@scope}
read_only
selectable
circle_id={subject_id}
event_target={@myself}
role={Bonfire.Boundaries.Roles.role_from_grants(Map.values(grants || %{}),
scope: @scope,
current_user: current_user(@__context__)
)
|> debug("the role")}
roles={Bonfire.Boundaries.Roles.roles_for_dropdown(@usage, scope: @scope, context: @__context__)}
/>
<!-- roles={Bonfire.Boundaries.Roles.roles_for_dropdown(@usage, scope: @scope, context: @__context__)} -->
</div>
</li>
</ul>
</form>
{/if}
</div>
</div>
<style>
.boundaries-switches label div.btn {
color: oklch(var(--bc));
}
.boundaries-switches label input:checked ~ div.btn-yes {
background: oklch(var(--su) / 0.90);
}
.boundaries-switches label input:checked ~ div.btn-no {
background: oklch(var(--er) / 0.90);
}
.boundaries-switches label input:checked ~ div.btn-maybe {
background: white;
color: black;
}
</style>
{/if}
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion lib/web/components/display/yes_maybe_false_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ defmodule Bonfire.UI.Boundaries.Web.YesMaybeFalseLive do

prop id, :any, default: nil
prop field_name, :any, default: nil

prop role, :any, default: nil
prop verb, :any, default: nil
prop value, :any, default: nil
prop read_only, :boolean, default: false
prop event_target, :any, default: nil
Expand Down
77 changes: 38 additions & 39 deletions lib/web/components/display/yes_maybe_false_live.sface
Original file line number Diff line number Diff line change
Expand Up @@ -14,55 +14,54 @@
<#Icon solid="Minus" class="w-4 h-4 text-gray-400" />
{/case}
{#else}
<div class="flex items-center gap-3 boundaries-switches">
<form
data-id={@id}
:on-change="edit_verb_value"
phx-target={@event_target}
class="flex items-center gap-3"
>
{!-- <input
:if={@value != nil}
value={if @value == true, do: "1", else: "0"}
type="checkbox"
name={@field_name}
<div class="flex items-center boundaries-switches">
<div class="border p-1 flex items-center gap-1 border-base-content/10 rounded-xl">
<button
class={
"toggle toggle-md",
"!toggle-success": @value == true,
"!border-error !bg-error !text-error": @value == false
"text-base-content/70 p-1 rounded-lg hover:bg-base-content/10 transition-colors duration-100",
"bg-success hover:bg-success text-success-content": @value == :can
}
checked={@value}
/>
<label :if={@value != nil && !@read_only}>
<input
class="absolute opacity-0"
name={@field_name}
type="radio"
value=""
checked={is_nil(@value)}
/>
<div class="btn btn-circle btn-xs">
<#Icon solid="X" class="w-4 h-4" />
</div>
</label>
phx-click="edit_verb_value"
phx-value-role={@role}
phx-value-verb={@verb}
phx-value-status={1}
phx-target={@event_target}
>
<#Icon solid="Check" class="w-4 h-4" />
</button>
<button
:if={@value == nil && !@read_only}
class={
"normal-case rounded btn btn-xs",
"btn-disabled": @read_only
"text-base-content/70 p-1 rounded-lg hover:bg-base-content/10 transition-colors duration-100",
"bg-neutral hover:bg-neutral text-neutral-content": @value == nil
}
phx-click="edit_verb_value"
phx-value-role={@role}
phx-value-verb={@verb}
phx-value-status=""
phx-target={@event_target}
>
{l("Edit")}
<#Icon solid="Minus" class="w-4 h-4" />
</button>
<button
:if={@value == nil && @read_only}
class={
"normal-case rounded btn btn-xs",
"btn-disabled": @read_only
"text-base-content/70 p-1 rounded-lg hover:bg-base-content/10 transition-colors duration-100",
"bg-error hover:bg-error text-error-content": @value == :cannot
}
phx-click="edit_verb_value"
phx-value-role={@role}
phx-value-verb={@verb}
phx-value-status={0}
phx-target={@event_target}
>
{l("Not specified")}
</button> --}
<#Icon solid="X" class="w-4 h-4" />
</button>
</div>
<!-- <form
data-id={@id}
:on-change="edit_verb_value"
phx-target={@event_target}
class="flex items-center gap-3"
>
<label class="tooltip tooltip-top" data-tip={if @value == true, do: l("Can")}>
<input
class="absolute opacity-0"
Expand Down Expand Up @@ -111,6 +110,6 @@
<#Icon solid="X" class="w-4 h-4" />
</div>
</label>
</form>
</form> -->
</div>
{/if}
8 changes: 6 additions & 2 deletions lib/web/components/roles/roles_dropdown_live.sface
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<select name={"#{@field}[#{@circle_id}][]"} class="select select-bordered" disabled={@read_only}>
<select
name={"#{@field}[#{@circle_id}][]"}
class="select select-xs select-bordered"
disabled={@read_only}
>
<option value="">{l("Select role")}</option>
<option
:for={{id, name} <-
Expand All @@ -7,5 +11,5 @@
(@extra_roles || [])}
value={id}
selected={if to_string(@role) == to_string(id), do: true}
>{name}</option>
>{Recase.to_title(to_string(id))}</option>
</select>
Loading

0 comments on commit 7a33d2c

Please sign in to comment.