Browse Source

Users list with pagination, universal

Vova Tkach 6 years ago
parent
commit
644efed3b8
2 changed files with 158 additions and 31 deletions
  1. 15 31
      engine/backend/modules/module_users.go
  2. 143 0
      engine/backend/modules/modules.go

+ 15 - 31
engine/backend/modules/module_users.go

@@ -46,39 +46,23 @@ func (this *Module) Module_users_submenu() []utils.ModuleSubMenu {
 
 func (this *Module) Module_users_content() string {
 	if this.smod == "default" {
-		// List
-		result := `<table class="table table-striped table-bordered">
-			<thead>
-				<tr>
-					<th scope="col">Email</th>
-					<th scope="col">First name</th>
-					<th scope="col">Last name</th>
-					<th scope="col">Action</th>
-				</tr>
-			</thead>
-		<tbody>`
-		rows, err := this.db.Query("SELECT `id`, `first_name`, `last_name`, `email` FROM `users`;")
-		if err == nil {
-			var id int
-			var first_name string
-			var last_name string
-			var email string
-			for rows.Next() {
-				err = rows.Scan(&id, &first_name, &last_name, &email)
-				if err == nil {
-					result += `<tr>
-						<td>` + email + `</td>
-						<td>` + first_name + `</td>
-						<td>` + last_name + `</td>
-						<td><a href="#">` + others.File_assets_sys_svg_edit + `</a> <a href="#">` + others.File_assets_sys_svg_remove + `</a></td>
-					</tr>`
-				}
-			}
-		}
-		result += `</tbody></table>`
-		return result
+		breadcrumb := this.breadcrumb([]dataBreadcrumb{
+			{"List of users", ""},
+		})
+		data_table := this.data_table("users", "email", "ASC", []dataTableRow{
+			{"id", "", nil},
+			{"email", "Email", nil},
+			{"first_name", "First name", nil},
+			{"last_name", "Last name", nil},
+		}, func(values *[]string) string {
+			return `<a href="/cp/users/modify/` + (*values)[0] + `/">` +
+				others.File_assets_sys_svg_edit + `</a>` +
+				`<a href="#">` + others.File_assets_sys_svg_remove + `</a>`
+		}, "/cp/users/default/")
+		return breadcrumb + data_table
 	} else if this.smod == "modify" {
 		// Add/Edit
+		return "Edit!"
 	}
 	return ""
 }

+ 143 - 0
engine/backend/modules/modules.go

@@ -4,6 +4,8 @@ import (
 	"database/sql"
 	_ "github.com/go-sql-driver/mysql"
 
+	"fmt"
+	"math"
 	"reflect"
 	"sort"
 	"strconv"
@@ -14,6 +16,21 @@ import (
 	utils "golang-fave/engine/wrapper/utils"
 )
 
+type dataTableDisplay func(values *[]string) string
+
+type dataTableAction func(values *[]string) string
+
+type dataTableRow struct {
+	dbField     string
+	nameInTable string
+	display     dataTableDisplay
+}
+
+type dataBreadcrumb struct {
+	name string
+	link string
+}
+
 type ModuleItem struct {
 	Alias   string
 	Display bool
@@ -114,6 +131,132 @@ func (this *Module) module_get_list_of_modules() *[]ModuleItem {
 	return &this.modlist
 }
 
+func (this *Module) breadcrumb(data []dataBreadcrumb) string {
+	result := ``
+	result += `<nav aria-label="breadcrumb">`
+	result += `<ol class="breadcrumb">`
+	result += `<li class="breadcrumb-item"><a href="/cp/` + this.mmod + `/">` + this.module_get_name(this.mmod) + `</a></li>`
+	for _, item := range data {
+		if item.link == "" {
+			result += `<li class="breadcrumb-item active" aria-current="page">` + item.name + `</li>`
+		} else {
+			result += `<li class="breadcrumb-item"><a href="` + item.link + `">` + item.name + `</a></li>`
+		}
+	}
+	result += `</ol>`
+	result += `</nav>`
+	return result
+}
+
+func (this *Module) data_table(table string, order_by string, order_way string, data []dataTableRow, action dataTableAction, pagination_url string) string {
+	var num int
+	err := this.db.QueryRow("SELECT COUNT(*) FROM `" + table + "`;").Scan(&num)
+	if err != nil {
+		return ""
+	}
+	pear_page := 10
+	max_pages := int(math.Ceil(float64(num) / float64(pear_page)))
+	curr_page := 1
+	p := this.wrapper.R.URL.Query().Get("p")
+	if p != "" {
+		pi, err := strconv.Atoi(p)
+		if err != nil {
+			curr_page = 1
+		} else {
+			if pi < 1 {
+				curr_page = 1
+			} else if pi > max_pages {
+				curr_page = max_pages
+			} else {
+				curr_page = pi
+			}
+		}
+	}
+	limit_offset := curr_page*pear_page - pear_page
+	result := `<table class="table table-striped table-bordered table_` + table + `">`
+	result += `<thead>`
+	result += `<tr>`
+	sqld := "SELECT"
+	for i, column := range data {
+		if column.nameInTable != "" {
+			result += `<th scope="col" class="col_` + column.dbField + `">` + column.nameInTable + `</th>`
+		}
+		sqld += " `" + column.dbField + "`"
+		if i+1 < len(data) {
+			sqld += ","
+		}
+	}
+	sqld += " FROM `" + table + "` ORDER BY `" + order_by + "` " + order_way + " LIMIT ?, ?;"
+	if action != nil {
+		result += `<th scope="col" class="col_action">Action</th>`
+	}
+	result += `</tr>`
+	result += `</thead>`
+	result += `<tbody>`
+	rows, err := this.db.Query(sqld, limit_offset, pear_page)
+	if err == nil {
+		values := make([]string, len(data))
+		scan := make([]interface{}, len(values))
+		for i := range values {
+			scan[i] = &values[i]
+		}
+		for rows.Next() {
+			err = rows.Scan(scan...)
+			if err == nil {
+				result += `<tr>`
+				for i, val := range values {
+					if data[i].nameInTable != "" {
+						if data[i].display == nil {
+							result += `<td class="col_` + data[i].dbField + `">` + string(val) + `</td>`
+						} else {
+							result += `<td class="col_` + data[i].dbField + `">` + data[i].display(&values) + `</td>`
+						}
+					}
+				}
+				if action != nil {
+					result += `<td class="col_action">` + action(&values) + `</td>`
+				}
+				result += `</tr>`
+			}
+		}
+	}
+	result += `</tbody></table>`
+	result += `<nav>`
+	result += `<ul class="pagination" style="margin-bottom:0px;">`
+	class := ""
+	if curr_page <= 1 {
+		class = " disabled"
+	}
+	result += `<li class="page-item` + class + `">`
+	result += `<a class="page-link" href="` + pagination_url + `?p=` + fmt.Sprintf("%d", curr_page-1) + `" aria-label="Previous">`
+	result += `<span aria-hidden="true">&laquo;</span>`
+	result += `<span class="sr-only">Previous</span>`
+	result += `</a>`
+	result += `</li>`
+	for i := 1; i <= max_pages; i++ {
+		class = ""
+		if i == curr_page {
+			class = " active"
+		}
+		result += `<li class="page-item` + class + `">`
+		result += `<a class="page-link" href="` + pagination_url + `?p=` + fmt.Sprintf("%d", i) + `">` + fmt.Sprintf("%d", i) + `</a>`
+		result += `</li>`
+	}
+	class = ""
+	if curr_page >= max_pages {
+		class = " disabled"
+	}
+	result += `<li class="page-item` + class + `">`
+	result += `<a class="page-link" href="` + pagination_url + `?p=` + fmt.Sprintf("%d", curr_page+1) + `" aria-label="Next">`
+	result += `<span aria-hidden="true">&raquo;</span>`
+	result += `<span class="sr-only">Next</span>`
+	result += `</a>`
+	result += `</li>`
+	result += `</ul>`
+	result += `</nav>`
+	return result
+}
+
 func New(wrapper *wrapper.Wrapper, db *sql.DB, user *utils.MySql_user, url_args *[]string) *Module {
 	mmod := "index"
 	smod := "default"