diff --git a/Oqtane.Client/Modules/Controls/PermissionGrid.razor b/Oqtane.Client/Modules/Controls/PermissionGrid.razor
index eed771a4..f1762af4 100644
--- a/Oqtane.Client/Modules/Controls/PermissionGrid.razor
+++ b/Oqtane.Client/Modules/Controls/PermissionGrid.razor
@@ -28,7 +28,9 @@
@foreach (PermissionString permission in permissions)
{
var p = permission;
-
PermissionChanged(e, p.PermissionName, role.Name))" /> |
+
+
+ |
}
}
@@ -51,12 +53,15 @@
@foreach (User user in users)
{
+ string userid = "[" + user.UserId.ToString() + "]";
@user.DisplayName |
@foreach (PermissionString permission in permissions)
{
var p = permission;
- PermissionChanged(e, p.PermissionName, "[" + user.UserId.ToString() + "]"))" /> |
+
+
+ |
}
}
@@ -125,15 +130,22 @@
}
}
- private bool GetPermissionValue(string Permissions, string SecurityKey)
+ private bool? GetPermissionValue(string Permissions, string SecurityKey)
{
- if ((";" + Permissions + ";").Contains(";" + SecurityKey + ";"))
+ if ((";" + Permissions + ";").Contains(";" + "!" + SecurityKey + ";"))
{
- return true;
+ return false; // deny permission
}
else
{
- return false;
+ if ((";" + Permissions + ";").Contains(";" + SecurityKey + ";"))
+ {
+ return true; // grant permission
+ }
+ else
+ {
+ return null; // not specified
+ }
}
}
@@ -169,20 +181,27 @@
username = "";
}
- private void PermissionChanged(UIChangeEventArgs e, string PermissionName, string SecurityId)
+ private void PermissionChanged(bool? Value, string PermissionName, string SecurityId)
{
- bool selected = (bool)e.Value;
+ bool? selected = Value;
PermissionString permission = permissions.Find(item => item.PermissionName == PermissionName);
if (permission != null)
{
List ids = permission.Permissions.Split(';').ToList();
- if (selected)
+
+ ids.Remove(SecurityId); // remove grant permission
+ ids.Remove("!" + SecurityId); // remove deny permission
+
+ switch (selected)
{
- ids.Add(SecurityId);
- }
- else
- {
- ids.Remove(SecurityId);
+ case true:
+ ids.Add(SecurityId); // add grant permission
+ break;
+ case false:
+ ids.Add("!" + SecurityId); // add deny permission
+ break;
+ case null:
+ break; // permission not specified
}
permissions[permissions.FindIndex(item => item.PermissionName == PermissionName)].Permissions = string.Join(";", ids.ToArray());
}
diff --git a/Oqtane.Client/Modules/Controls/TriStateCheckBox.razor b/Oqtane.Client/Modules/Controls/TriStateCheckBox.razor
new file mode 100644
index 00000000..9c75e34d
--- /dev/null
+++ b/Oqtane.Client/Modules/Controls/TriStateCheckBox.razor
@@ -0,0 +1,60 @@
+
+
+@code {
+ [Parameter]
+ public bool? Value { get; set; }
+
+ [Parameter]
+ public bool Disabled { get; set; }
+
+ [Parameter]
+ public Action OnChange { get; set; }
+
+ bool? value = null;
+ string title;
+ string src = "";
+
+ protected override void OnInitialized()
+ {
+ value = Value;
+ SetImage();
+ }
+
+ private void SetValue()
+ {
+ switch (value)
+ {
+ case true:
+ value = false;
+ break;
+ case false:
+ value = null;
+ break;
+ case null:
+ value = true;
+ break;
+ }
+ SetImage();
+ OnChange(value);
+ }
+
+ private void SetImage()
+ {
+ switch (value)
+ {
+ case true:
+ src = "images/checked.png";
+ title = "Permission Granted";
+ break;
+ case false:
+ src = "images/unchecked.png";
+ title = "Permission Denied";
+ break;
+ case null:
+ src = "images/null.png";
+ title = "";
+ break;
+ }
+ StateHasChanged();
+ }
+}
diff --git a/Oqtane.Client/wwwroot/images/checked.png b/Oqtane.Client/wwwroot/images/checked.png
new file mode 100644
index 00000000..a4100c70
Binary files /dev/null and b/Oqtane.Client/wwwroot/images/checked.png differ
diff --git a/Oqtane.Client/wwwroot/images/null.png b/Oqtane.Client/wwwroot/images/null.png
new file mode 100644
index 00000000..d0f50939
Binary files /dev/null and b/Oqtane.Client/wwwroot/images/null.png differ
diff --git a/Oqtane.Client/wwwroot/images/unchecked.png b/Oqtane.Client/wwwroot/images/unchecked.png
new file mode 100644
index 00000000..566e60a8
Binary files /dev/null and b/Oqtane.Client/wwwroot/images/unchecked.png differ
diff --git a/Oqtane.Server/Scripts/00.00.00.sql b/Oqtane.Server/Scripts/00.00.00.sql
index b8b8ad32..2f97a61e 100644
--- a/Oqtane.Server/Scripts/00.00.00.sql
+++ b/Oqtane.Server/Scripts/00.00.00.sql
@@ -179,6 +179,28 @@ CREATE TABLE [dbo].[Setting](
)
GO
+CREATE TABLE [dbo].[Profile](
+ [ProfileId] [int] IDENTITY(1,1) NOT NULL,
+ [SiteId] [int] NULL,
+ [Name] [nvarchar](50) NOT NULL,
+ [Category] [nvarchar](50) NOT NULL,
+ [ViewOrder] [int] NOT NULL,
+ [MaxLength] [int] NOT NULL,
+ [DefaultValue] [nvarchar](2000) NULL,
+ [IsRequired] [bit] NOT NULL,
+ [IsPrivate] [bit] NOT NULL,
+ [CreatedBy] [nvarchar](256) NOT NULL,
+ [CreatedOn] [datetime] NOT NULL,
+ [ModifiedBy] [nvarchar](256) NOT NULL,
+ [ModifiedOn] [datetime] NOT NULL,
+ CONSTRAINT [PK_Profile] PRIMARY KEY CLUSTERED
+ (
+ [ProfileId] ASC
+ )
+)
+
+GO
+
CREATE TABLE [dbo].[HtmlText](
[HtmlTextId] [int] IDENTITY(1,1) NOT NULL,
[ModuleId] [int] NOT NULL,
@@ -259,6 +281,11 @@ ALTER TABLE [dbo].[Permission] WITH CHECK ADD CONSTRAINT [FK_Permission_Role] FO
REFERENCES [dbo].[Role] ([RoleId])
GO
+ALTER TABLE [dbo].[Profile] WITH NOCHECK ADD CONSTRAINT [FK_Profile_Sites] FOREIGN KEY([SiteId])
+REFERENCES [dbo].[Site] ([SiteId])
+ON DELETE CASCADE
+GO
+
/*
Create indexes
diff --git a/Oqtane.Server/wwwroot/images/checked.png b/Oqtane.Server/wwwroot/images/checked.png
new file mode 100644
index 00000000..a4100c70
Binary files /dev/null and b/Oqtane.Server/wwwroot/images/checked.png differ
diff --git a/Oqtane.Server/wwwroot/images/null.png b/Oqtane.Server/wwwroot/images/null.png
new file mode 100644
index 00000000..d0f50939
Binary files /dev/null and b/Oqtane.Server/wwwroot/images/null.png differ
diff --git a/Oqtane.Server/wwwroot/images/unchecked.png b/Oqtane.Server/wwwroot/images/unchecked.png
new file mode 100644
index 00000000..566e60a8
Binary files /dev/null and b/Oqtane.Server/wwwroot/images/unchecked.png differ