mirror of https://github.com/abpframework/abp.git
17 changed files with 491 additions and 108 deletions
@ -0,0 +1,85 @@ |
|||
@page |
|||
|
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Layout |
|||
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Comments |
|||
@using Volo.CmsKit.Admin.Web.Menus |
|||
@using Volo.CmsKit.Localization |
|||
|
|||
@inject IPageLayout PageLayout |
|||
@inject IHtmlLocalizer<CmsKitResource> L |
|||
|
|||
@model IndexModel |
|||
|
|||
@{ |
|||
PageLayout.Content.Title = L["Comments"].Value; |
|||
PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); |
|||
PageLayout.Content.MenuItemName = CmsKitAdminMenus.Comments.CommentsMenu; |
|||
} |
|||
|
|||
@section styles { |
|||
<abp-style-bundle> |
|||
<abp-style src="/Pages/CmsKit/Comments/index.css" /> |
|||
</abp-style-bundle> |
|||
} |
|||
|
|||
@section scripts { |
|||
<abp-script-bundle> |
|||
<abp-script src="/client-proxies/cms-kit-common-proxy.js" /> |
|||
<abp-script src="/client-proxies/cms-kit-admin-proxy.js" /> |
|||
<abp-script src="/Pages/CmsKit/Comments/index.js" /> |
|||
</abp-script-bundle> |
|||
} |
|||
|
|||
<abp-alert id="commentsAlert" alert-type="Warning" style="display: none;"> |
|||
</abp-alert> |
|||
|
|||
<abp-card class="mb-4"> |
|||
<abp-card-body> |
|||
<div id="CmsKitCommentsWrapper"> |
|||
<form id="CmsKitCommentsFilterForm" method="post"> |
|||
<abp-row class="align-items-end"> |
|||
<abp-column size-lg="_4" size-md="_12"> |
|||
<abp-row> |
|||
<abp-column size-lg="_6" size-md="_6"> |
|||
<abp-input asp-for="@Model.CreationStartDate" class="singledatepicker" label="@L["StartDate"].Value" type="text" /> |
|||
</abp-column> |
|||
<abp-column size-lg="_6" size-md="_6"> |
|||
<abp-input asp-for="@Model.CreationEndDate" class="singledatepicker" label="@L["EndDate"].Value" type="text" /> |
|||
</abp-column> |
|||
</abp-row> |
|||
</abp-column> |
|||
|
|||
<abp-column size-lg="_2" size-md="_6"> |
|||
<abp-input asp-for="@Model.Author" label="@L["Username"].Value" type="text" /> |
|||
</abp-column> |
|||
|
|||
<abp-column size-lg="_2" size-md="_6"> |
|||
<abp-input asp-for="@Model.EntityType" label="@L["EntityType"].Value" type="text" /> |
|||
</abp-column> |
|||
|
|||
<abp-column size-lg="_2" size-md="_6"> |
|||
<select asp-for="@Model.IsApproved" label="@L["IsApproved"].Value"> |
|||
<option value="">@L["All"].Value</option> |
|||
<option value="true">@L["Approved"].Value</option> |
|||
<option value="false">@L["Rejected"].Value</option> |
|||
<option value="null">@L["Pending"].Value</option> |
|||
</select> |
|||
</abp-column> |
|||
|
|||
<abp-column size-lg="_2" size-md="_6"> |
|||
<abp-button class="w-100 mb-3" button-type="Primary" type="submit"> |
|||
<i class="fa fa-search" aria-hidden="true"></i> |
|||
</abp-button> |
|||
</abp-column> |
|||
</abp-row> |
|||
</form> |
|||
</div> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
|
|||
<abp-card> |
|||
<abp-card-body> |
|||
<abp-table id="CommentsTable" class="nowrap"></abp-table> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
|
|||
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Comments.Waiting; |
|||
|
|||
public class IndexModel : CmsKitAdminPageModel |
|||
{ |
|||
public string EntityType { get; set; } |
|||
|
|||
public string Author { get; set; } |
|||
|
|||
public DateTime? CreationStartDate { get; set; } |
|||
|
|||
public DateTime? CreationEndDate { get; set; } |
|||
public string IsApproved { get; set; } |
|||
|
|||
} |
|||
@ -0,0 +1,230 @@ |
|||
$(function () { |
|||
var l = abp.localization.getResource("CmsKit"); |
|||
|
|||
var commentsService = volo.cmsKit.admin.comments.commentAdmin; |
|||
|
|||
var detailsModal = new abp.ModalManager(abp.appPath + "CmsKit/Comments/DetailsModal"); |
|||
|
|||
moment()._locale.preparse = (string) => string; |
|||
moment()._locale.postformat = (string) => string; |
|||
|
|||
var getFormattedDate = function ($datePicker) { |
|||
if (!$datePicker.val()) { |
|||
return null; |
|||
} |
|||
var momentDate = moment($datePicker.val(), $datePicker.data('daterangepicker').locale.format); |
|||
return momentDate.isValid() ? momentDate.toISOString() : null; |
|||
}; |
|||
|
|||
|
|||
var defaultStartDate = moment().add(-7, 'days'); |
|||
$("#CreationStartDate").val(defaultStartDate.format('L')); |
|||
|
|||
$('.singledatepicker').daterangepicker({ |
|||
"singleDatePicker": true, |
|||
"showDropdowns": true, |
|||
"autoUpdateInput": false, |
|||
"autoApply": true, |
|||
"opens": "center", |
|||
"drops": "auto" |
|||
}); |
|||
|
|||
|
|||
|
|||
$('.singledatepicker').attr('autocomplete', 'off'); |
|||
|
|||
$('.singledatepicker').on('apply.daterangepicker', function (ev, picker) { |
|||
$(this).val(picker.startDate.format('l')); |
|||
}); |
|||
|
|||
|
|||
var filterForm = $('#CmsKitCommentsFilterForm'); |
|||
|
|||
var getFilter = function () { |
|||
var filterObj = filterForm.serializeFormToObject(); |
|||
|
|||
filterObj.creationStartDate = getFormattedDate($('#CreationStartDate')); |
|||
filterObj.creationEndDate = getFormattedDate($('#CreationEndDate')); |
|||
|
|||
return filterObj; |
|||
}; |
|||
|
|||
|
|||
var _dataTable = $('#CommentsTable').DataTable(abp.libs.datatables.normalizeConfiguration({ |
|||
processing: true, |
|||
serverSide: true, |
|||
paging: true, |
|||
scrollX: true, |
|||
searching: false, |
|||
scrollCollapse: true, |
|||
ajax: abp.libs.datatables.createAjax(commentsService.getList, getFilter), |
|||
columnDefs: [ |
|||
{ |
|||
width: "10%", |
|||
title: l("Actions"), |
|||
targets: 0, |
|||
orderable: false, |
|||
rowAction: { |
|||
items: [ |
|||
{ |
|||
text: l('Details'), |
|||
action: function (data) { |
|||
location.href = 'Comments/' + data.record.id; |
|||
} |
|||
}, |
|||
{ |
|||
text: l('Delete'), |
|||
visible: abp.auth.isGranted('CmsKit.Comments.Delete'), |
|||
confirmMessage: function (data) { |
|||
return l("CommentDeletionConfirmationMessage") |
|||
}, |
|||
action: function (data) { |
|||
commentsService |
|||
.delete(data.record.id) |
|||
.then(function () { |
|||
_dataTable.ajax.reloadEx(); |
|||
abp.notify.success(l('DeletedSuccessfully')); |
|||
}); |
|||
} |
|||
}, |
|||
{ |
|||
text: function (data) { |
|||
return data.isApproved ? l('Revoke Approval') : l('Approve'); |
|||
}, |
|||
action: function (data) { |
|||
var newApprovalStatus = !data.record?.isApproved; |
|||
|
|||
commentsService |
|||
.updateApprovalStatus(data.record.id, { IsApproved: newApprovalStatus }) |
|||
.then(function () { |
|||
_dataTable.ajax.reloadEx(); |
|||
var message = newApprovalStatus ? l('ApprovedSuccessfully') : l('ApprovalRevokedSuccessfully'); |
|||
abp.notify.success(message); |
|||
}) |
|||
.catch(function (error) { |
|||
console.log("error", error) |
|||
abp.notify.error(error.message); |
|||
}); |
|||
} |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
{ |
|||
width: "10%", |
|||
title: l("Username"), |
|||
orderable: false, |
|||
data: "author.userName", |
|||
render: function (data) { |
|||
if (data !== null) { |
|||
return GetFilterableDatatableContent('#Author', $.fn.dataTable.render.text().display(data)); //prevent against possible XSS
|
|||
} |
|||
return ""; |
|||
} |
|||
}, |
|||
{ |
|||
width: "15%", |
|||
title: l("EntityType"), |
|||
orderable: false, |
|||
data: "entityType", |
|||
render: function (data) { |
|||
if (data !== null) { |
|||
return GetFilterableDatatableContent('#EntityType', $.fn.dataTable.render.text().display(data)); |
|||
} |
|||
return ""; |
|||
} |
|||
}, |
|||
{ |
|||
title: l("URL"), |
|||
data: "url", |
|||
render: function (data, type, row) { |
|||
if (data !== null) { |
|||
return '<a href="' + data + '#comment-' + row.id + '" target="_blank"><i class="fa fa-location-arrow"></i></a>'; |
|||
} |
|||
return ""; |
|||
} |
|||
}, |
|||
{ |
|||
title: l("Text"), |
|||
data: "text", |
|||
orderable: false, |
|||
render: function (data) { |
|||
data = $.fn.dataTable.render.text().display(data || ""); |
|||
|
|||
var maxChars = 64; |
|||
|
|||
if (data.length > maxChars) { |
|||
return ( |
|||
'<span data-toggle="tooltip" title="' + |
|||
data + |
|||
'">' + |
|||
data.substring(0, maxChars) + |
|||
"..." + |
|||
"</span>" |
|||
); |
|||
} else { |
|||
return data; |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
width: "15%", |
|||
title: l("CreationTime"), |
|||
data: "creationTime", |
|||
orderable: true, |
|||
dataFormat: "datetime" |
|||
}, |
|||
{ |
|||
width: "5%", |
|||
title: l("Status"), |
|||
orderable: false, |
|||
|
|||
data: "isApproved", |
|||
render: function (data, type, row) { |
|||
var icons = '' |
|||
|
|||
if (data === null) { |
|||
icons = '<i class="fa-solid fa-hourglass-start"></i>'; |
|||
} else if (typeof data === "boolean") { |
|||
if (data) { |
|||
icons = '<i class="fa-solid fa-check" style="color: #63E6BE;"></i>'; |
|||
} else { |
|||
icons = '<i class="fa-solid fa-x" style="color: #e0102f;"></i>'; |
|||
} |
|||
} |
|||
|
|||
return icons; |
|||
} |
|||
} |
|||
] |
|||
})); |
|||
|
|||
function GetFilterableDatatableContent(filterSelector, data) { |
|||
return '<span class="datatableCell" data-field="' + filterSelector + '" data-val="' + data + '">' + data + '</span>'; |
|||
} |
|||
|
|||
$(document).on('click', '.datatableCell', function () { |
|||
var inputSelector = $(this).attr('data-field'); |
|||
var value = $(this).attr('data-val'); |
|||
|
|||
$(inputSelector).val(value); |
|||
|
|||
_dataTable.ajax.reloadEx(); |
|||
}); |
|||
|
|||
filterForm.submit(function (e) { |
|||
e.preventDefault(); |
|||
_dataTable.ajax.reloadEx(); |
|||
}); |
|||
// Get and display pending comment count
|
|||
commentsService.getPendingCommentCount().then(function (count) { |
|||
console.log(count) |
|||
if (count > 0) { |
|||
var alertMessage = 'You have pending comments: ' + count; |
|||
var alertElement = '<abp-alert alert-type="Warning">' + alertMessage + '</abp-alert>'; |
|||
console.log(count) |
|||
$('#commentsAlert').html(alertElement); |
|||
$('#commentsAlert').show() |
|||
} |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue