Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,14 @@ FakesAssemblies/
License.config
/Blomsterringen.Web/imagecache
maildrop
.idea/.idea.Geta.DdsAdmin/riderModule.iml
Comment thread
gatisb marked this conversation as resolved.
Outdated
.idea/.idea.Geta.DdsAdmin/.idea/vcs.xml
.idea/.idea.Geta.DdsAdmin/.idea/misc.xml
.idea/.idea.Geta.DdsAdmin/.idea/indexLayout.xml
.idea/.idea.Geta.DdsAdmin/.idea/.name
.idea/.idea.Geta.DdsAdmin/.idea/.idea.Geta.DdsAdmin.iml
.idea/.idea.Geta.DdsAdmin/.idea/contentModel.xml
.idea/.idea.Geta.DdsAdmin/.idea/modules.xml
.idea/.idea.Geta.DdsAdmin/.idea/projectSettingsUpdater.xml
.idea/.idea.Geta.DdsAdmin/.idea/workspace.xml
.idea/.idea.Geta.DdsAdmin/.idea/encodings.xml
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ All notable changes to this project will be documented in this file.

## [11.0.0]
- Upgraded to CMS 11
- Upgraded to framework version 4.6.1
- Upgraded to framework version 4.6.1

## [11.0.4.6]
- Adding query string capability to filter data by column and exact value
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Where can I get it?
1. Add [EPiServer Nuget feed](http://nuget.episerver.com/en/Feed/) in Visual Studio Package Manager options (Tools ->Options -> Package Manager -> Package Sources).
1. Install DDSAdmin via NuGet in Visual Studio. Ensure that you also install the required dependencies.
1. Rebuild your solution.
1. Start editing your data in EPiServer DDS storages. It will be available in CMS menu: Geta->DDS Admin.
1. Start editing your data in EPiServer DDS storage's. It will be available in CMS menu: Geta->DDS Admin.

Where can I get more info?
------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/Dds/Interfaces/ICrudService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public interface ICrudService
{
StringResponse Create(string storeName, Dictionary<string, string> values);
StringResponse Delete(string storeName, string identityId);
ReadResponse Read(string storeName, int start, int pageSize, string search, int sortByColumn, string sortDirection);
ReadResponse Read(string storeName, int start, int pageSize, string search, int sortByColumn, string sortDirection, string filterColumnName, string filter);
Comment thread
gatisb marked this conversation as resolved.
Outdated
StringResponse Update(string storeName, int columnId, string value, string id, string columnName);
}
}
38 changes: 27 additions & 11 deletions src/Dds/Services/CrudService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public StringResponse Delete(string storeName, string identityId)
return response;
}

public ReadResponse Read(string storeName, int start, int pageSize, string search, int sortByColumn, string sortDirection)
public ReadResponse Read(string storeName, int start, int pageSize, string search, int sortByColumn, string sortDirection, string filterColumnName, string filter)
{
var response = new ReadResponse { Success = false };
logger.Debug("Read started");
Expand All @@ -83,22 +83,38 @@ public ReadResponse Read(string storeName, int start, int pageSize, string searc
var store = DynamicDataStoreFactory.Instance.GetStore(storeName);
var storeMetadata = store.Metadata();

// TODO: we cannot order here due to fact that this is PropertyBag, if we could it would be great performance boost
// var orderBy = sortByColumn == 0 ? "Id" : StoreMetadata.Columns.ToList()[sortByColumn - 1].PropertyName;
var query = store.ItemsAsPropertyBag(); // .OrderBy(orderBy);
List<PropertyBag> data;
int count;

var data = sortByColumn == 0 && string.IsNullOrEmpty(search)
? (sortDirection == "asc"
? query.OrderBy(r => r.Id).Skip(start).Take(pageSize).ToList()
: query.OrderByDescending(r => r.Id).Skip(start).Take(pageSize).ToList())
: query.ToList();
var preSorted = false;

if (string.IsNullOrWhiteSpace(filterColumnName) || string.IsNullOrWhiteSpace(filter))
Comment thread
gatisb marked this conversation as resolved.
Outdated
{
// TODO: we cannot order here due to fact that this is PropertyBag, if we could it would be great performance boost
// var orderBy = sortByColumn == 0 ? "Id" : StoreMetadata.Columns.ToList()[sortByColumn - 1].PropertyName;
var query = store.ItemsAsPropertyBag(); // .OrderBy(orderBy);

preSorted = sortByColumn == 0 && string.IsNullOrEmpty(search);
Comment thread
gatisb marked this conversation as resolved.

data = preSorted
? (sortDirection == "asc"
? query.OrderBy(r => r.Id).Skip(start).Take(pageSize).ToList()
: query.OrderByDescending(r => r.Id).Skip(start).Take(pageSize).ToList())
: query.ToList();
count = query.Count();
}
else
{
data = store.FindAsPropertyBag(filterColumnName, filter).ToList();
count = data.Count;
}

List<List<string>> stringData;
if (sortByColumn == 0 && string.IsNullOrEmpty(search))
if (preSorted)
{
// no sorting and no filtering, use fast code then
stringData = FormatData(storeMetadata, data);
totalCount = query.Count();
totalCount = count;
}
else
{
Expand Down
16 changes: 14 additions & 2 deletions src/Dds/Services/StoreService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,24 @@ public bool Delete(string storeName, Identity id)
}
}

public bool Flush(string storeName)
public bool Flush(string storeName, string filterColumnName, string filter)
Comment thread
gatisb marked this conversation as resolved.
{
try
{
var store = DynamicDataStoreFactory.Instance.GetStore(storeName);
store.DeleteAll();
if (!string.IsNullOrWhiteSpace(filterColumnName) && !string.IsNullOrWhiteSpace(filter))
Comment thread
gatisb marked this conversation as resolved.
Outdated
{
var itemsToBeDeleted = store.FindAsPropertyBag(filterColumnName, filter).ToList();
foreach (var itemToBeDeleted in itemsToBeDeleted)
{
store.Delete(itemToBeDeleted.Id);
}
}
else
{
store.DeleteAll();
}

return true;
}
catch (Exception ex)
Expand Down
Binary file modified src/modules/_protected/Geta.DdsAdmin/Admin/Constants.cs
Binary file not shown.
10 changes: 7 additions & 3 deletions src/modules/_protected/Geta.DdsAdmin/Admin/Data.ashx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private BaseResponse Delete(HttpContext context, string storeName)
return SerializeResponse(context, deleteResponse);
}

private BaseResponse Read(HttpContext context, string storeName)
private BaseResponse Read(HttpContext context, string storeName, string filterColumnName, string filter)
Comment thread
gatisb marked this conversation as resolved.
{
int start = Convert.ToInt32(context.Request.QueryString["iDisplayStart"]);
int pageSize = Convert.ToInt32(context.Request.QueryString["iDisplayLength"]);
Expand All @@ -82,7 +82,7 @@ private BaseResponse Read(HttpContext context, string storeName)
int sortByColumn = Convert.ToInt32(context.Request.QueryString["iSortCol_0"]);
string sortDirection = context.Request.QueryString["sSortDir_0"];

var readResponse = this.crudService.Read(storeName, start, pageSize, search, sortByColumn, sortDirection);
var readResponse = this.crudService.Read(storeName, start, pageSize, search, sortByColumn, sortDirection, filterColumnName, filter);

var result = new
{
Expand Down Expand Up @@ -113,6 +113,10 @@ private void WriteResponse(HttpContext context)
logger.InfoFormat("Operation:{0}", operation);
string storeName = context.Request.QueryString[Constants.StoreKey];
logger.InfoFormat("Store:{0}", operation);
string filterColumnName = context.Request.QueryString[Constants.FilterColumnNameKey];
logger.InfoFormat("Filter column name:{0}", filterColumnName);
string filter = context.Request.QueryString[Constants.FilterKey];
logger.InfoFormat("Filter:{0}", filter);

context.Response.Clear();
context.Response.ClearContent();
Expand All @@ -123,7 +127,7 @@ private void WriteResponse(HttpContext context)
{
case "read":
{
response = Read(context, storeName);
response = Read(context, storeName, filterColumnName, filter);
}
break;
case "update":
Expand Down
12 changes: 7 additions & 5 deletions src/modules/_protected/Geta.DdsAdmin/Admin/DdsAdmin.aspx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<html>
<head runat="server" ID="head1">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8"/>
<title><%# CurrentStoreName %></title>
<title><%# CurrentStoreName %> <%# CurrentFilterMessage%></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"> </script>
<script type="text/javascript">
if (typeof jQuery == 'undefined') {
Expand Down Expand Up @@ -49,17 +49,19 @@
</asp:repeater>
</form>

<h3><%= string.IsNullOrEmpty(CustomHeading) ? string.Format("Selected Store Type: {0}", CurrentStoreName) : CustomHeading %></h3>
<h3><%= string.IsNullOrEmpty(CustomHeading) ? string.Format("Selected Store Type: {0}", CurrentStoreName) : CustomHeading %> <%= CurrentFilterMessage %></h3>
<%= CustomMessage %>

<form runat="server">
<span class="epi-cmsButton">
<asp:Button runat="server" ID="Flush" Text="Delete All Data" OnClick="FlushStore" CssClass="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Delete" OnClientClick="return confirm('Are you really want to delete all data from ths table??')"/>
<asp:Button runat="server" ID="Flush" OnClick="FlushStore" CssClass="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Delete" />
Comment thread
gatisb marked this conversation as resolved.
Outdated
</span>
<span class="epi-cmsButton">
<asp:Button runat="server" ID="Export" Text="Export to Excel" OnClick="ExportStore" CssClass="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Export"/>
<asp:Button runat="server" ID="Export" OnClick="ExportStore" CssClass="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Export"/>
</span>
<input type="hidden" name="CurrentStoreName" value="<%= CurrentStoreName %>"/>
<input type="hidden" name="CurrentFilterColumnName" value="<%= CurrentFilterColumnName %>"/>
<input type="hidden" name="CurrentFilter" value="<%= CurrentFilter %>"/>
</form>

<br/>
Expand All @@ -84,7 +86,7 @@

<script type="text/javascript" charset="utf-8">
$(function() {
var storeParameter = "<%= Constants.StoreKey %>=<%= CurrentStoreName %>";
var storeParameter = "<%= GetParameters() %>";
var dataTable = $('#storeItems').dataTable({
sDom: "Rlfrtip",
bJQueryUI: true,
Expand Down
84 changes: 68 additions & 16 deletions src/modules/_protected/Geta.DdsAdmin/Admin/DdsAdmin.aspx.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Data;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -26,8 +26,11 @@ public DdsAdmin()

private int[] HiddenColumns { get; set; }
protected string CurrentStoreName { get; set; }
protected string CurrentFilterColumnName { get; set; }
protected string CurrentFilter { get; set; }
protected string CustomHeading { get; set; }
protected string CustomMessage { get; set; }
protected string CurrentFilterMessage { get; set; }
protected PropertyMap Item { get; set; }
protected StoreMetadata Store { get; set; }

Expand All @@ -47,17 +50,22 @@ protected override void OnPreRender(EventArgs e)

Page.Header.Controls.Add(new Literal
{
Text = "<link type=\"text/css\" rel=\"stylesheet\" href=\"" + Paths.ToClientResource(typeof (MenuProvider), "content/themes/DDSAdmin/custom/minified.css") + "\" />"
Text = "<link type=\"text/css\" rel=\"stylesheet\" href=\"" +
Paths.ToClientResource(typeof(MenuProvider), "content/themes/DDSAdmin/custom/minified.css") +
"\" />"
});

Page.Header.Controls.Add(new Literal
{
Text = "<script src=\"" + Paths.ToClientResource(typeof (MenuProvider), "scripts/datatables-1.9.4/media/js/jquery.dataTables.min.js") + "\"></script>"
Text = "<script src=\"" + Paths.ToClientResource(typeof(MenuProvider),
"scripts/datatables-1.9.4/media/js/jquery.dataTables.min.js") + "\"></script>"
});

Page.Header.Controls.Add(new Literal
{
Text = "<script src=\"" + Paths.ToClientResource(typeof (MenuProvider), "scripts/dataTables.jeditable.min.js") + "\"></script>"
Text = "<script src=\"" +
Paths.ToClientResource(typeof(MenuProvider), "scripts/dataTables.jeditable.min.js") +
"\"></script>"
});
}

Expand Down Expand Up @@ -87,9 +95,28 @@ protected string SetItem(RepeaterItem repeaterItem)
return string.Empty;
}

protected string GetParameters()
{
var result = $"{Constants.StoreKey}={CurrentStoreName}";
Comment thread
gatisb marked this conversation as resolved.
Outdated

if (CurrentFilterMessage != null)
{
result += $"&{Constants.FilterColumnNameKey}={CurrentFilterColumnName}";
result += $"&{Constants.FilterKey}={CurrentFilter}";
}

return result;
}

private void GetQueryStringParameters()
{
CurrentStoreName = HttpUtility.HtmlEncode(Request.QueryString[Constants.StoreKey]);
CurrentFilterColumnName = HttpUtility.HtmlEncode(Request.QueryString[Constants.FilterColumnNameKey]);
CurrentFilter = HttpUtility.HtmlEncode(Request.QueryString[Constants.FilterKey]);
CurrentFilterMessage =
!string.IsNullOrWhiteSpace(CurrentFilterColumnName) && !string.IsNullOrWhiteSpace(CurrentFilter)
? $"filtered by {CurrentFilterColumnName} = {CurrentFilter}"
: null;
CustomHeading = HttpUtility.HtmlEncode(Request.QueryString[Constants.HeadingKey]);
CustomMessage = HttpUtility.HtmlEncode(Request.QueryString[Constants.MessageKey]);

Expand All @@ -101,10 +128,10 @@ private void GetQueryStringParameters()
}

HiddenColumns = hiddenColumns.Split(new[]
{
","
},
StringSplitOptions.RemoveEmptyEntries).Select(item => Convert.ToInt32(item)).ToArray();
{
","
},
StringSplitOptions.RemoveEmptyEntries).Select(item => Convert.ToInt32(item)).ToArray();
}

private void LoadAndDisplayData()
Expand All @@ -127,20 +154,34 @@ private void LoadAndDisplayData()
repForm.DataSource = Store.Columns;
repColumnsHeader.DataBind();
repForm.DataBind();

Flush.Text = string.IsNullOrWhiteSpace(CurrentFilterMessage) ? "Delete all data" : "Delete filtered data";
Flush.OnClientClick = string.IsNullOrWhiteSpace(CurrentFilterMessage)
? "return confirm('Do you really want to delete all data from this table?')"
: "return confirm('Do you really want to delete filtered data from this table?')";
Export.Text = string.IsNullOrWhiteSpace(CurrentFilterMessage)
? "Export to Excel"
: "Export filtered data to Excel";
}

protected void FlushStore(object sender, EventArgs e)
{
var storeName = Request.Form["CurrentStoreName"];
_storeService.Flush(storeName);
var filterColumnName = Request.Form["CurrentFilterColumnName"];
var filter = Request.Form["CurrentFilter"];

_storeService.Flush(storeName, filterColumnName, filter);

Response.Redirect(Request.RawUrl);
}

protected void ExportStore(object sender, EventArgs e)
{
var storeName = Request.Form["CurrentStoreName"];
var ddsDataSet = GetDdsStoreAsDataSet(storeName);
var filterColumnName = Request.Form["CurrentFilterColumnName"];
var filter = Request.Form["CurrentFilter"];

var ddsDataSet = GetDdsStoreAsDataSet(storeName, filterColumnName, filter);

using (var wb = new XLWorkbook())
{
Expand All @@ -150,7 +191,18 @@ protected void ExportStore(object sender, EventArgs e)
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", $"attachment;filename={storeName}.xlsx");
if (!string.IsNullOrWhiteSpace(filterColumnName) && !string.IsNullOrWhiteSpace(filter))
{
var fileName = $"{storeName}.{filterColumnName}.{filter}.xlsx";
Path.GetInvalidFileNameChars()
.Aggregate(fileName, (current, c) => current.Replace(c, '_'));
Response.AddHeader("content-disposition", $"attachment;filename={fileName.Substring(0, Math.Min(fileName.Length, 200))}");
}
else
{
Response.AddHeader("content-disposition", $"attachment;filename={storeName}.xlsx");
}

using (var MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
Expand All @@ -161,20 +213,20 @@ protected void ExportStore(object sender, EventArgs e)
}
}

private DataSet GetDdsStoreAsDataSet(string storeName)
private DataSet GetDdsStoreAsDataSet(string storeName, string filterColumnName, string filter)
{
var dataTable = new DataTable("record");

var columns = _storeService.GetMetadata(storeName);

foreach (var column in columns.Columns)
{
dataTable.Columns.Add(column.PropertyName, typeof (string));
dataTable.Columns.Add(column.PropertyName, typeof(string));
}

var allRecords = _crudService.Read(storeName, 0, int.MaxValue, null, 0, null);
var allRecords = _crudService.Read(storeName, 0, int.MaxValue, null, 0, null, filterColumnName, filter);

if (allRecords == null || !allRecords.Success || allRecords.TotalCount == 0)
if (allRecords == null || !allRecords.Success)
{
return null;
}
Expand Down Expand Up @@ -203,4 +255,4 @@ private DataSet GetDdsStoreAsDataSet(string storeName)
};
}
}
}
}
Loading