mirror of https://github.com/gophish/gophish
Added summary routes for groups.
Routes: /api/groups/summary /api/groups/:id/summary The UI is now using these routes for the "Users & Groups" page.pull/539/merge
parent
9dfe54ac3d
commit
7453fd3b48
|
@ -214,6 +214,20 @@ func API_Groups(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API_Groups_Summary returns a summary of the groups owned by the current user.
|
||||||
|
func API_Groups_Summary(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch {
|
||||||
|
case r.Method == "GET":
|
||||||
|
gs, err := models.GetGroupSummaries(ctx.Get(r, "user_id").(int64))
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
JSONResponse(w, gs, http.StatusOK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// API_Groups_Id returns details about the requested group.
|
// API_Groups_Id returns details about the requested group.
|
||||||
// If the group is not valid, API_Groups_Id returns null.
|
// If the group is not valid, API_Groups_Id returns null.
|
||||||
func API_Groups_Id(w http.ResponseWriter, r *http.Request) {
|
func API_Groups_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -253,6 +267,21 @@ func API_Groups_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API_Groups_Id_Summary returns a summary of the groups owned by the current user.
|
||||||
|
func API_Groups_Id_Summary(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch {
|
||||||
|
case r.Method == "GET":
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
||||||
|
g, err := models.GetGroupSummary(id, ctx.Get(r, "user_id").(int64))
|
||||||
|
if err != nil {
|
||||||
|
JSONResponse(w, models.Response{Success: false, Message: "Group not found"}, http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
JSONResponse(w, g, http.StatusOK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// API_Templates handles the functionality for the /api/templates endpoint
|
// API_Templates handles the functionality for the /api/templates endpoint
|
||||||
func API_Templates(w http.ResponseWriter, r *http.Request) {
|
func API_Templates(w http.ResponseWriter, r *http.Request) {
|
||||||
switch {
|
switch {
|
||||||
|
|
|
@ -54,7 +54,9 @@ func CreateAdminRouter() http.Handler {
|
||||||
api.HandleFunc("/campaigns/{id:[0-9]+}/summary", Use(API_Campaign_Id_Summary, mid.RequireAPIKey))
|
api.HandleFunc("/campaigns/{id:[0-9]+}/summary", Use(API_Campaign_Id_Summary, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/campaigns/{id:[0-9]+}/complete", Use(API_Campaigns_Id_Complete, mid.RequireAPIKey))
|
api.HandleFunc("/campaigns/{id:[0-9]+}/complete", Use(API_Campaigns_Id_Complete, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/groups/", Use(API_Groups, mid.RequireAPIKey))
|
api.HandleFunc("/groups/", Use(API_Groups, mid.RequireAPIKey))
|
||||||
|
api.HandleFunc("/groups/summary", Use(API_Groups_Summary, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/groups/{id:[0-9]+}", Use(API_Groups_Id, mid.RequireAPIKey))
|
api.HandleFunc("/groups/{id:[0-9]+}", Use(API_Groups_Id, mid.RequireAPIKey))
|
||||||
|
api.HandleFunc("/groups/{id:[0-9]+}/summary", Use(API_Groups_Id_Summary, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/templates/", Use(API_Templates, mid.RequireAPIKey))
|
api.HandleFunc("/templates/", Use(API_Templates, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/templates/{id:[0-9]+}", Use(API_Templates_Id, mid.RequireAPIKey))
|
api.HandleFunc("/templates/{id:[0-9]+}", Use(API_Templates_Id, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/pages/", Use(API_Pages, mid.RequireAPIKey))
|
api.HandleFunc("/pages/", Use(API_Pages, mid.RequireAPIKey))
|
||||||
|
|
|
@ -18,6 +18,22 @@ type Group struct {
|
||||||
Targets []Target `json:"targets" sql:"-"`
|
Targets []Target `json:"targets" sql:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GroupSummaries is a struct representing the overview of Groups.
|
||||||
|
type GroupSummaries struct {
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
Groups []GroupSummary `json:"groups"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupSummary represents a summary of the Group model. The only
|
||||||
|
// difference is that, instead of listing the Targets (which could be expensive
|
||||||
|
// for large groups), it lists the target count.
|
||||||
|
type GroupSummary struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ModifiedDate time.Time `json:"modified_date"`
|
||||||
|
NumTargets int64 `json:"num_targets"`
|
||||||
|
}
|
||||||
|
|
||||||
// GroupTarget is used for a many-to-many relationship between 1..* Groups and 1..* Targets
|
// GroupTarget is used for a many-to-many relationship between 1..* Groups and 1..* Targets
|
||||||
type GroupTarget struct {
|
type GroupTarget struct {
|
||||||
GroupId int64 `json:"-"`
|
GroupId int64 `json:"-"`
|
||||||
|
@ -71,6 +87,27 @@ func GetGroups(uid int64) ([]Group, error) {
|
||||||
return gs, nil
|
return gs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetGroupSummaries returns the summaries for the groups
|
||||||
|
// created by the given uid.
|
||||||
|
func GetGroupSummaries(uid int64) (GroupSummaries, error) {
|
||||||
|
gs := GroupSummaries{}
|
||||||
|
query := db.Table("groups").Where("user_id=?", uid)
|
||||||
|
err := query.Select("id, name, modified_date").Scan(&gs.Groups).Error
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
return gs, err
|
||||||
|
}
|
||||||
|
for i := range gs.Groups {
|
||||||
|
query = db.Table("group_targets").Where("group_id=?", gs.Groups[i].Id)
|
||||||
|
err = query.Count(&gs.Groups[i].NumTargets).Error
|
||||||
|
if err != nil {
|
||||||
|
return gs, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gs.Total = int64(len(gs.Groups))
|
||||||
|
return gs, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetGroup returns the group, if it exists, specified by the given id and user_id.
|
// GetGroup returns the group, if it exists, specified by the given id and user_id.
|
||||||
func GetGroup(id int64, uid int64) (Group, error) {
|
func GetGroup(id int64, uid int64) (Group, error) {
|
||||||
g := Group{}
|
g := Group{}
|
||||||
|
@ -86,6 +123,23 @@ func GetGroup(id int64, uid int64) (Group, error) {
|
||||||
return g, nil
|
return g, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetGroupSummary returns the summary for the requested group
|
||||||
|
func GetGroupSummary(id int64, uid int64) (GroupSummary, error) {
|
||||||
|
g := GroupSummary{}
|
||||||
|
query := db.Table("groups").Where("user_id=? and id=?", uid, id)
|
||||||
|
err := query.Select("id, name, modified_date").Scan(&g).Error
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
return g, err
|
||||||
|
}
|
||||||
|
query = db.Table("group_targets").Where("group_id=?", id)
|
||||||
|
err = query.Count(&g.NumTargets).Error
|
||||||
|
if err != nil {
|
||||||
|
return g, err
|
||||||
|
}
|
||||||
|
return g, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetGroupByName returns the group, if it exists, specified by the given name and user_id.
|
// GetGroupByName returns the group, if it exists, specified by the given name and user_id.
|
||||||
func GetGroupByName(n string, uid int64) (Group, error) {
|
func GetGroupByName(n string, uid int64) (Group, error) {
|
||||||
g := Group{}
|
g := Group{}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
function errorFlash(e){$("#flashes").empty(),$("#flashes").append('<div style="text-align:center" class="alert alert-danger"> <i class="fa fa-exclamation-circle"></i> '+e+"</div>")}function successFlash(e){$("#flashes").empty(),$("#flashes").append('<div style="text-align:center" class="alert alert-success"> <i class="fa fa-check-circle"></i> '+e+"</div>")}function modalError(e){$("#modal\\.flashes").empty().append('<div style="text-align:center" class="alert alert-danger"> <i class="fa fa-exclamation-circle"></i> '+e+"</div>")}function query(e,t,n,r){return $.ajax({url:"/api"+e+"?api_key="+user.api_key,async:r,method:t,data:JSON.stringify(n),dataType:"json",contentType:"application/json"})}function escapeHtml(e){return $("<div/>").text(e).html()}function unescapeHtml(e){return $("<div/>").html(e).text()}var api={campaigns:{get:function(){return query("/campaigns/","GET",{},!1)},post:function(e){return query("/campaigns/","POST",e,!1)},summary:function(){return query("/campaigns/summary","GET",{},!1)}},campaignId:{get:function(e){return query("/campaigns/"+e,"GET",{},!0)},delete:function(e){return query("/campaigns/"+e,"DELETE",{},!1)},results:function(e){return query("/campaigns/"+e+"/results","GET",{},!0)},complete:function(e){return query("/campaigns/"+e+"/complete","GET",{},!0)},summary:function(e){return query("/campaigns/"+e+"/summary","GET",{},!0)}},groups:{get:function(){return query("/groups/","GET",{},!1)},post:function(e){return query("/groups/","POST",e,!1)}},groupId:{get:function(e){return query("/groups/"+e,"GET",{},!1)},put:function(e){return query("/groups/"+e.id,"PUT",e,!1)},delete:function(e){return query("/groups/"+e,"DELETE",{},!1)}},templates:{get:function(){return query("/templates/","GET",{},!1)},post:function(e){return query("/templates/","POST",e,!1)}},templateId:{get:function(e){return query("/templates/"+e,"GET",{},!1)},put:function(e){return query("/templates/"+e.id,"PUT",e,!1)},delete:function(e){return query("/templates/"+e,"DELETE",{},!1)}},pages:{get:function(){return query("/pages/","GET",{},!1)},post:function(e){return query("/pages/","POST",e,!1)}},pageId:{get:function(e){return query("/pages/"+e,"GET",{},!1)},put:function(e){return query("/pages/"+e.id,"PUT",e,!1)},delete:function(e){return query("/pages/"+e,"DELETE",{},!1)}},SMTP:{get:function(){return query("/smtp/","GET",{},!1)},post:function(e){return query("/smtp/","POST",e,!1)}},SMTPId:{get:function(e){return query("/smtp/"+e,"GET",{},!1)},put:function(e){return query("/smtp/"+e.id,"PUT",e,!1)},delete:function(e){return query("/smtp/"+e,"DELETE",{},!1)}},import_email:function(e){return query("/import/email","POST",{},!1)},clone_site:function(e){return query("/import/site","POST",e,!1)},send_test_email:function(e){return query("/util/send_test_email","POST",e,!0)}};$(document).ready(function(){$.fn.dataTable.moment("MMMM Do YYYY, h:mm:ss a"),$('[data-toggle="tooltip"]').tooltip()});
|
function errorFlash(e){$("#flashes").empty(),$("#flashes").append('<div style="text-align:center" class="alert alert-danger"> <i class="fa fa-exclamation-circle"></i> '+e+"</div>")}function successFlash(e){$("#flashes").empty(),$("#flashes").append('<div style="text-align:center" class="alert alert-success"> <i class="fa fa-check-circle"></i> '+e+"</div>")}function modalError(e){$("#modal\\.flashes").empty().append('<div style="text-align:center" class="alert alert-danger"> <i class="fa fa-exclamation-circle"></i> '+e+"</div>")}function query(e,t,n,r){return $.ajax({url:"/api"+e+"?api_key="+user.api_key,async:r,method:t,data:JSON.stringify(n),dataType:"json",contentType:"application/json"})}function escapeHtml(e){return $("<div/>").text(e).html()}function unescapeHtml(e){return $("<div/>").html(e).text()}var api={campaigns:{get:function(){return query("/campaigns/","GET",{},!1)},post:function(e){return query("/campaigns/","POST",e,!1)},summary:function(){return query("/campaigns/summary","GET",{},!1)}},campaignId:{get:function(e){return query("/campaigns/"+e,"GET",{},!0)},delete:function(e){return query("/campaigns/"+e,"DELETE",{},!1)},results:function(e){return query("/campaigns/"+e+"/results","GET",{},!0)},complete:function(e){return query("/campaigns/"+e+"/complete","GET",{},!0)},summary:function(e){return query("/campaigns/"+e+"/summary","GET",{},!0)}},groups:{get:function(){return query("/groups/","GET",{},!1)},post:function(e){return query("/groups/","POST",e,!1)},summary:function(){return query("/groups/summary","GET",{},!0)}},groupId:{get:function(e){return query("/groups/"+e,"GET",{},!1)},put:function(e){return query("/groups/"+e.id,"PUT",e,!1)},delete:function(e){return query("/groups/"+e,"DELETE",{},!1)}},templates:{get:function(){return query("/templates/","GET",{},!1)},post:function(e){return query("/templates/","POST",e,!1)}},templateId:{get:function(e){return query("/templates/"+e,"GET",{},!1)},put:function(e){return query("/templates/"+e.id,"PUT",e,!1)},delete:function(e){return query("/templates/"+e,"DELETE",{},!1)}},pages:{get:function(){return query("/pages/","GET",{},!1)},post:function(e){return query("/pages/","POST",e,!1)}},pageId:{get:function(e){return query("/pages/"+e,"GET",{},!1)},put:function(e){return query("/pages/"+e.id,"PUT",e,!1)},delete:function(e){return query("/pages/"+e,"DELETE",{},!1)}},SMTP:{get:function(){return query("/smtp/","GET",{},!1)},post:function(e){return query("/smtp/","POST",e,!1)}},SMTPId:{get:function(e){return query("/smtp/"+e,"GET",{},!1)},put:function(e){return query("/smtp/"+e.id,"PUT",e,!1)},delete:function(e){return query("/smtp/"+e,"DELETE",{},!1)}},import_email:function(e){return query("/import/email","POST",{},!1)},clone_site:function(e){return query("/import/site","POST",e,!1)},send_test_email:function(e){return query("/util/send_test_email","POST",e,!0)}};$(document).ready(function(){$.fn.dataTable.moment("MMMM Do YYYY, h:mm:ss a"),$('[data-toggle="tooltip"]').tooltip()});
|
|
@ -1 +1 @@
|
||||||
function save(a){var e=[];$.each($("#targetsTable").DataTable().rows().data(),function(a,s){e.push({first_name:unescapeHtml(s[0]),last_name:unescapeHtml(s[1]),email:unescapeHtml(s[2]),position:unescapeHtml(s[3])})});var s={name:$("#name").val(),targets:e};a!=-1?(s.id=groups[a].id,api.groupId.put(s).success(function(a){successFlash("Group updated successfully!"),load(),dismiss(),$("#modal").modal("hide")}).error(function(a){modalError(a.responseJSON.message)})):api.groups.post(s).success(function(a){successFlash("Group added successfully!"),load(),dismiss(),$("#modal").modal("hide")}).error(function(a){modalError(a.responseJSON.message)})}function dismiss(){$("#targetsTable").dataTable().DataTable().clear().draw(),$("#name").val(""),$("#modal\\.flashes").empty()}function edit(a){targets=$("#targetsTable").dataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),$("#modalSubmit").unbind("click").click(function(){save(a)}),a==-1?group={}:(group=groups[a],$("#name").val(group.name),$.each(group.targets,function(a,e){targets.DataTable().row.add([escapeHtml(e.first_name),escapeHtml(e.last_name),escapeHtml(e.email),escapeHtml(e.position),'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>']).draw()})),$("#csvupload").fileupload({dataType:"json",add:function(a,e){$("#modal\\.flashes").empty();var s=/(csv|txt)$/i,t=e.originalFiles[0].name;return t&&!s.test(t.split(".").pop())?(modalError("Unsupported file extension (use .csv or .txt)"),!1):void e.submit()},done:function(a,e){$.each(e.result,function(a,e){addTarget(e.first_name,e.last_name,e.email,e.position)}),targets.DataTable().draw()}})}function deleteGroup(a){confirm("Delete "+groups[a].name+"?")&&api.groupId.delete(groups[a].id).success(function(a){successFlash(a.message),load()})}function addTarget(a,e,s,t){var o=escapeHtml(s).toLowerCase(),r=[escapeHtml(a),escapeHtml(e),o,escapeHtml(t),'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'],n=targets.DataTable(),l=n.column(2,{order:"index"}).data().indexOf(o);l>=0?n.row(l,{order:"index"}).data(r):n.row.add(r)}function load(){$("#groupTable").hide(),$("#emptyMessage").hide(),$("#loading").show(),api.groups.get().success(function(a){$("#loading").hide(),a.length>0?(groups=a,$("#emptyMessage").hide(),$("#groupTable").show(),groupTable=$("#groupTable").DataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),groupTable.clear(),$.each(groups,function(a,e){var s="";$.each(e.targets,function(a,e){if(s+=e.email+", ",s.length>50)return s=s.slice(0,-3)+"...",!1}),groupTable.row.add([escapeHtml(e.name),escapeHtml(s),moment(e.modified_date).format("MMMM Do YYYY, h:mm:ss a"),"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit("+a+")'> <i class='fa fa-pencil'></i> </button> <button class='btn btn-danger' onclick='deleteGroup("+a+")'> <i class='fa fa-trash-o'></i> </button></div>"]).draw()})):$("#emptyMessage").show()}).error(function(){errorFlash("Error fetching groups")})}var groups=[];$(document).ready(function(){load(),$("#targetForm").submit(function(){return addTarget($("#firstName").val(),$("#lastName").val(),$("#email").val(),$("#position").val()),targets.DataTable().draw(),$("#targetForm>div>input").val(""),$("#firstName").focus(),!1}),$("#targetsTable").on("click","span>i.fa-trash-o",function(){targets.DataTable().row($(this).parents("tr")).remove().draw()}),$("#modal").on("hide.bs.modal",function(){dismiss()})});
|
function save(a){var e=[];$.each($("#targetsTable").DataTable().rows().data(),function(a,s){e.push({first_name:unescapeHtml(s[0]),last_name:unescapeHtml(s[1]),email:unescapeHtml(s[2]),position:unescapeHtml(s[3])})});var s={name:$("#name").val(),targets:e};a!=-1?(s.id=a,api.groupId.put(s).success(function(a){successFlash("Group updated successfully!"),load(),dismiss(),$("#modal").modal("hide")}).error(function(a){modalError(a.responseJSON.message)})):api.groups.post(s).success(function(a){successFlash("Group added successfully!"),load(),dismiss(),$("#modal").modal("hide")}).error(function(a){modalError(a.responseJSON.message)})}function dismiss(){$("#targetsTable").dataTable().DataTable().clear().draw(),$("#name").val(""),$("#modal\\.flashes").empty()}function edit(a){if(targets=$("#targetsTable").dataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),$("#modalSubmit").unbind("click").click(function(){save(a)}),a==-1);else api.groupId.get(a).success(function(a){$("#name").val(a.name),$.each(a.targets,function(a,e){targets.DataTable().row.add([escapeHtml(e.first_name),escapeHtml(e.last_name),escapeHtml(e.email),escapeHtml(e.position),'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>']).draw()})}).error(function(){errorFlash("Error fetching group")});$("#csvupload").fileupload({dataType:"json",add:function(a,e){$("#modal\\.flashes").empty();var s=/(csv|txt)$/i,t=e.originalFiles[0].name;return t&&!s.test(t.split(".").pop())?(modalError("Unsupported file extension (use .csv or .txt)"),!1):void e.submit()},done:function(a,e){$.each(e.result,function(a,e){addTarget(e.first_name,e.last_name,e.email,e.position)}),targets.DataTable().draw()}})}function deleteGroup(a){var e=groups.find(function(e){return e.id===a});return e?void(confirm("Delete "+e.name+"?")&&api.groupId.delete(a).success(function(a){successFlash(a.message),load()})):void console.log("wat")}function addTarget(a,e,s,t){var o=escapeHtml(s).toLowerCase(),r=[escapeHtml(a),escapeHtml(e),o,escapeHtml(t),'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'],n=targets.DataTable(),i=n.column(2,{order:"index"}).data().indexOf(o);i>=0?n.row(i,{order:"index"}).data(r):n.row.add(r)}function load(){$("#groupTable").hide(),$("#emptyMessage").hide(),$("#loading").show(),api.groups.summary().success(function(a){if($("#loading").hide(),a.total>0){groups=a.groups,$("#emptyMessage").hide(),$("#groupTable").show();var e=$("#groupTable").DataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]});e.clear(),$.each(groups,function(a,s){e.row.add([escapeHtml(s.name),escapeHtml(s.num_targets),moment(s.modified_date).format("MMMM Do YYYY, h:mm:ss a"),"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit("+s.id+")'> <i class='fa fa-pencil'></i> </button> <button class='btn btn-danger' onclick='deleteGroup("+s.id+")'> <i class='fa fa-trash-o'></i> </button></div>"]).draw()})}else $("#emptyMessage").show()}).error(function(){errorFlash("Error fetching groups")})}var groups=[];$(document).ready(function(){load(),$("#targetForm").submit(function(){return addTarget($("#firstName").val(),$("#lastName").val(),$("#email").val(),$("#position").val()),targets.DataTable().draw(),$("#targetForm>div>input").val(""),$("#firstName").focus(),!1}),$("#targetsTable").on("click","span>i.fa-trash-o",function(){targets.DataTable().row($(this).parents("tr")).remove().draw()}),$("#modal").on("hide.bs.modal",function(){dismiss()})});
|
|
@ -85,6 +85,10 @@ var api = {
|
||||||
// post() - Posts a group to POST /groups
|
// post() - Posts a group to POST /groups
|
||||||
post: function(group) {
|
post: function(group) {
|
||||||
return query("/groups/", "POST", group, false)
|
return query("/groups/", "POST", group, false)
|
||||||
|
},
|
||||||
|
// summary() - Queries the API for GET /groups/summary
|
||||||
|
summary: function() {
|
||||||
|
return query("/groups/summary", "GET", {}, true)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// groupId contains the endpoints for /groups/:id
|
// groupId contains the endpoints for /groups/:id
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
var groups = []
|
var groups = []
|
||||||
|
|
||||||
// Save attempts to POST or PUT to /groups/
|
// Save attempts to POST or PUT to /groups/
|
||||||
function save(idx) {
|
function save(id) {
|
||||||
var targets = []
|
var targets = []
|
||||||
$.each($("#targetsTable").DataTable().rows().data(), function(i, target) {
|
$.each($("#targetsTable").DataTable().rows().data(), function(i, target) {
|
||||||
targets.push({
|
targets.push({
|
||||||
|
@ -16,10 +16,10 @@ function save(idx) {
|
||||||
targets: targets
|
targets: targets
|
||||||
}
|
}
|
||||||
// Submit the group
|
// Submit the group
|
||||||
if (idx != -1) {
|
if (id != -1) {
|
||||||
// If we're just editing an existing group,
|
// If we're just editing an existing group,
|
||||||
// we need to PUT /groups/:id
|
// we need to PUT /groups/:id
|
||||||
group.id = groups[idx].id
|
group.id = id
|
||||||
api.groupId.put(group)
|
api.groupId.put(group)
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
successFlash("Group updated successfully!")
|
successFlash("Group updated successfully!")
|
||||||
|
@ -52,7 +52,7 @@ function dismiss() {
|
||||||
$("#modal\\.flashes").empty()
|
$("#modal\\.flashes").empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
function edit(idx) {
|
function edit(id) {
|
||||||
targets = $("#targetsTable").dataTable({
|
targets = $("#targetsTable").dataTable({
|
||||||
destroy: true, // Destroy any other instantiated table - http://datatables.net/manual/tech-notes/3#destroy
|
destroy: true, // Destroy any other instantiated table - http://datatables.net/manual/tech-notes/3#destroy
|
||||||
columnDefs: [{
|
columnDefs: [{
|
||||||
|
@ -61,12 +61,13 @@ function edit(idx) {
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
$("#modalSubmit").unbind('click').click(function() {
|
$("#modalSubmit").unbind('click').click(function() {
|
||||||
save(idx)
|
save(id)
|
||||||
})
|
})
|
||||||
if (idx == -1) {
|
if (id == -1) {
|
||||||
group = {}
|
var group = {}
|
||||||
} else {
|
} else {
|
||||||
group = groups[idx]
|
api.groupId.get(id)
|
||||||
|
.success(function(group) {
|
||||||
$("#name").val(group.name)
|
$("#name").val(group.name)
|
||||||
$.each(group.targets, function(i, record) {
|
$.each(group.targets, function(i, record) {
|
||||||
targets.DataTable()
|
targets.DataTable()
|
||||||
|
@ -78,6 +79,11 @@ function edit(idx) {
|
||||||
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||||
]).draw()
|
]).draw()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
.error(function() {
|
||||||
|
errorFlash("Error fetching group")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// Handle file uploads
|
// Handle file uploads
|
||||||
$("#csvupload").fileupload({
|
$("#csvupload").fileupload({
|
||||||
|
@ -105,9 +111,14 @@ function edit(idx) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteGroup(idx) {
|
function deleteGroup(id) {
|
||||||
if (confirm("Delete " + groups[idx].name + "?")) {
|
var group = groups.find(function(x){return x.id === id})
|
||||||
api.groupId.delete(groups[idx].id)
|
if (!group) {
|
||||||
|
console.log('wat');
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (confirm("Delete " + group.name + "?")) {
|
||||||
|
api.groupId.delete(id)
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
successFlash(data.message)
|
successFlash(data.message)
|
||||||
load()
|
load()
|
||||||
|
@ -150,14 +161,14 @@ function load() {
|
||||||
$("#groupTable").hide()
|
$("#groupTable").hide()
|
||||||
$("#emptyMessage").hide()
|
$("#emptyMessage").hide()
|
||||||
$("#loading").show()
|
$("#loading").show()
|
||||||
api.groups.get()
|
api.groups.summary()
|
||||||
.success(function(gs) {
|
.success(function(response) {
|
||||||
$("#loading").hide()
|
$("#loading").hide()
|
||||||
if (gs.length > 0) {
|
if (response.total > 0) {
|
||||||
groups = gs
|
groups = response.groups
|
||||||
$("#emptyMessage").hide()
|
$("#emptyMessage").hide()
|
||||||
$("#groupTable").show()
|
$("#groupTable").show()
|
||||||
groupTable = $("#groupTable").DataTable({
|
var groupTable = $("#groupTable").DataTable({
|
||||||
destroy: true,
|
destroy: true,
|
||||||
columnDefs: [{
|
columnDefs: [{
|
||||||
orderable: false,
|
orderable: false,
|
||||||
|
@ -166,22 +177,14 @@ function load() {
|
||||||
});
|
});
|
||||||
groupTable.clear();
|
groupTable.clear();
|
||||||
$.each(groups, function(i, group) {
|
$.each(groups, function(i, group) {
|
||||||
var targets = ""
|
|
||||||
$.each(group.targets, function(i, target) {
|
|
||||||
targets += target.email + ", "
|
|
||||||
if (targets.length > 50) {
|
|
||||||
targets = targets.slice(0, -3) + "..."
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
groupTable.row.add([
|
groupTable.row.add([
|
||||||
escapeHtml(group.name),
|
escapeHtml(group.name),
|
||||||
escapeHtml(targets),
|
escapeHtml(group.num_targets),
|
||||||
moment(group.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
moment(group.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
||||||
"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit(" + i + ")'>\
|
"<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit(" + group.id + ")'>\
|
||||||
<i class='fa fa-pencil'></i>\
|
<i class='fa fa-pencil'></i>\
|
||||||
</button>\
|
</button>\
|
||||||
<button class='btn btn-danger' onclick='deleteGroup(" + i + ")'>\
|
<button class='btn btn-danger' onclick='deleteGroup(" + group.id + ")'>\
|
||||||
<i class='fa fa-trash-o'></i>\
|
<i class='fa fa-trash-o'></i>\
|
||||||
</button></div>"
|
</button></div>"
|
||||||
]).draw()
|
]).draw()
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Members</th>
|
<th># of Members</th>
|
||||||
<th>Modified Date</th>
|
<th>Modified Date</th>
|
||||||
<th class="col-md-2 no-sort"></th>
|
<th class="col-md-2 no-sort"></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in New Issue