summaryrefslogtreecommitdiff
path: root/Pages/Component
diff options
context:
space:
mode:
authorJake Mannens <jake@asger.xyz>2023-10-03 16:41:58 +1100
committerJake Mannens <jake@asger.xyz>2023-10-03 16:41:58 +1100
commit33438ac951430fa370965b42a3d98a54e704ab01 (patch)
treefbd835c25ac7566e8437cd0ef988fce0596a15e7 /Pages/Component
parent7170867a9a2650fa5a98b9e2664fb2114a0bf114 (diff)
AclDialog
Diffstat (limited to 'Pages/Component')
-rw-r--r--Pages/Component/AclActionSwitch.razor20
-rw-r--r--Pages/Component/AclActionSwitch.razor.css48
-rw-r--r--Pages/Component/AclDialog.razor95
-rw-r--r--Pages/Component/AclDialog.razor.css32
-rw-r--r--Pages/Component/Titlebar.razor2
5 files changed, 191 insertions, 6 deletions
diff --git a/Pages/Component/AclActionSwitch.razor b/Pages/Component/AclActionSwitch.razor
new file mode 100644
index 0000000..8bc61d2
--- /dev/null
+++ b/Pages/Component/AclActionSwitch.razor
@@ -0,0 +1,20 @@
+<label>
+ <input
+ type="checkbox"
+ checked=@InitialValue
+ @onchange=@(e => OnToggle.InvokeAsync((e.Value as bool?) ?? false))
+ hidden>
+ <div class="outer">
+ <p>Deny</p>
+ <p>Allow</p>
+ <div class="inner"/>
+ </div>
+</label>
+
+@code {
+ [Parameter]
+ public bool InitialValue { get; set; } = false;
+
+ [Parameter]
+ public EventCallback<bool> OnToggle { get; set; }
+} \ No newline at end of file
diff --git a/Pages/Component/AclActionSwitch.razor.css b/Pages/Component/AclActionSwitch.razor.css
new file mode 100644
index 0000000..e9de5a2
--- /dev/null
+++ b/Pages/Component/AclActionSwitch.razor.css
@@ -0,0 +1,48 @@
+div.outer {
+ align-items: center;
+ border-radius: 10px;
+ border: 1px solid var(--color-aclaction-deny);
+ cursor: pointer;
+ display: flex;
+ flex-direction: row;
+ height: 20px;
+ position: relative;
+ transition: border-color 0.1s linear;
+ user-select: none;
+ width: min-content;
+}
+
+div.inner {
+ background: var(--color-aclaction-deny);
+ border-radius: 8px;
+ height: calc(100% - 2px);
+ left: 1px;
+ position: absolute;
+ top: 1px;
+ transition: left 0.1s linear, background 0.1s linear;
+ width: calc(50% - 2px);
+ z-index: 1;
+}
+
+div.outer p {
+ color: white;
+ font-family: 'Trebuchet MS';
+ font-size: 8pt;
+ text-align: center;
+ transition: color 0.1s linear;
+ width: 50px;
+ z-index: 2;
+}
+
+input:checked + div.outer {
+ border-color: var(--color-aclaction-allow);
+}
+
+input:checked + div.outer > div.inner {
+ background: var(--color-aclaction-allow);
+ left: calc(50% + 1px);
+}
+
+input:checked + div.outer p:nth-child(2) {
+ color: black;
+} \ No newline at end of file
diff --git a/Pages/Component/AclDialog.razor b/Pages/Component/AclDialog.razor
index 33d1f03..8116f04 100644
--- a/Pages/Component/AclDialog.razor
+++ b/Pages/Component/AclDialog.razor
@@ -1,19 +1,104 @@
-@implements IDialog
+@using System.Numerics;
+@inject IDbContextFactory<HBContext> dbFactory;
+@implements IDialog
<Dialog Title="Edit permissions" @ref=dialog>
+ @if(obj?.Acl is not null) {
+ <table class="data-table">
+ <tr>
+ <th>Action</th>
+ <th>Subject</th>
+ <th>Permissions</th>
+ <th></th>
+ </tr>
+ @foreach(var rule in obj.Acl.Rules.OrderByDescending(r => r.Action)) {
+ <tr>
+ <td><div><AclActionSwitch InitialValue=@(rule.Action == AclRuleAction.Allow)/></div></td>
+ <td>@rule.Principal.ToString()</td>
+ <td>@GetActivePermissions(rule)</td>
+ <td>
+ <a title="Edit" href="javascript:;">&#x1F589</a>
+ <a title="Delete" href="javascript:;">&#x2716</a>
+ </td>
+ </tr>
+ }
+ </table>
+ <br/>
+ <center><a href="javascript:;">Add new</a></center>
+ <ButtonContainer>
+ <button class="secondary" @onclick=Hide>Cancel</button>
+ <button data-keyboard-shortcut="a" @onclick=Hide><u>A</u>pply</button>
+ </ButtonContainer>
+ } else {
+ <center><i>This item does not have any permissions set!</i></center>
+ <ButtonContainer>
+ <button class="secondary" @onclick=Hide>Cancel</button>
+ </ButtonContainer>
+ }
</Dialog>
@code {
- [Parameter]
- public HBObject Object { get; set; }
-
public bool Visible {
get => dialog.Visible;
- set => dialog.Visible = value;
+ set {
+ dialog.Visible = value;
+ if(value)
+ StateHasChanged();
+ }
}
+ private HBObject? obj;
+
private Dialog dialog;
public void Show() => Visible = true;
public void Hide() => Visible = false;
+
+ public void Show(HBObject obj) {
+ Object = obj;
+ Show();
+ }
+
+ public HBObject? Object {
+ get => obj;
+ set {
+ if(value is null) {
+ obj = null;
+ return;
+ }
+
+ using var db = dbFactory.CreateDbContext();
+
+ obj = db.Objects
+ .Include(o => o.Acl)
+ .First(o => o.ObjectId == value.ObjectId);
+
+ if(obj.Acl is not null)
+ db.Entry(obj.Acl).Collection(a => a.Rules).Load();
+ }
+ }
+
+ public string GetActivePermissions(AclRule rule) {
+ var perms = Acl.GetPermissionDescriptions(obj!)
+ .Where(kv => (rule.Permissions & kv.Value) == kv.Value)
+ .ToList();
+
+ // Filter the list of matching permissions to include the
+ // most relevant encapsulation permissions only. E.g. if
+ // 'Full access' includes 'Read' and 'Write', then only
+ // show 'Full access'.
+ List<int> toRemove = new();
+ for(int i = 0; i < perms.Count(); i++)
+ for(int j = 0; j < perms.Count(); j++)
+ if(i != j)
+ if((perms[i].Value & perms[j].Value) == perms[i].Value)
+ toRemove.Add(i);
+ for(int i = toRemove.Count() - 1; i >= 0; i--)
+ perms.RemoveAt(toRemove[i]);
+
+ return string.Join(", ", perms
+ .OrderByDescending(kv => BitOperations.PopCount(kv.Value))
+ .ThenByDescending(kv => kv.Value)
+ .Select(kv => kv.Key));
+ }
} \ No newline at end of file
diff --git a/Pages/Component/AclDialog.razor.css b/Pages/Component/AclDialog.razor.css
new file mode 100644
index 0000000..f1b7931
--- /dev/null
+++ b/Pages/Component/AclDialog.razor.css
@@ -0,0 +1,32 @@
+table p {
+ margin: 8px 0 8px 0;
+}
+
+table tr {
+ background: none !important;
+}
+
+table td {
+ font-family: 'Lucida Console';
+ font-size: 8pt;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+table td:last-child {
+ font-size: 12pt;
+}
+
+table tr:nth-child(2n+1) td:not(:first-child) {
+ background: rgba(255, 255, 255, 0.1);
+}
+
+table td:nth-child(2n) {
+ white-space: nowrap;
+ width: 1px;
+}
+
+table td > div {
+ margin: auto;
+ width: min-content;
+} \ No newline at end of file
diff --git a/Pages/Component/Titlebar.razor b/Pages/Component/Titlebar.razor
index ad41532..766787a 100644
--- a/Pages/Component/Titlebar.razor
+++ b/Pages/Component/Titlebar.razor
@@ -74,5 +74,5 @@
private AboutDialog aboutDialog;
- private string username => AuthState.GetAwaiter().GetResult().User.Identity?.Name ?? "fugg";
+ private string username => AuthState.GetAwaiter().GetResult().User.Identity?.Name!;
}