github.com/kotovmak/go-admin@v1.1.1/template/types/button.go (about)

     1  package types
     2  
     3  import (
     4  	"html/template"
     5  	"net/url"
     6  
     7  	"github.com/kotovmak/go-admin/context"
     8  	"github.com/kotovmak/go-admin/modules/utils"
     9  	"github.com/kotovmak/go-admin/plugins/admin/models"
    10  )
    11  
    12  type Button interface {
    13  	Content() (template.HTML, template.JS)
    14  	GetAction() Action
    15  	URL() string
    16  	METHOD() string
    17  	ID() string
    18  	Type() string
    19  	GetName() string
    20  	SetName(name string)
    21  	IsType(t string) bool
    22  }
    23  
    24  type BaseButton struct {
    25  	Id, Url, Method, Name, TypeName string
    26  	Title                           template.HTML
    27  	Action                          Action
    28  }
    29  
    30  func (b *BaseButton) Content() (template.HTML, template.JS) { return "", "" }
    31  func (b *BaseButton) GetAction() Action                     { return b.Action }
    32  func (b *BaseButton) ID() string                            { return b.Id }
    33  func (b *BaseButton) URL() string                           { return b.Url }
    34  func (b *BaseButton) Type() string                          { return b.TypeName }
    35  func (b *BaseButton) IsType(t string) bool                  { return b.TypeName == t }
    36  func (b *BaseButton) METHOD() string                        { return b.Method }
    37  func (b *BaseButton) GetName() string                       { return b.Name }
    38  func (b *BaseButton) SetName(name string)                   { b.Name = name }
    39  
    40  type DefaultButton struct {
    41  	*BaseButton
    42  	Color     template.HTML
    43  	TextColor template.HTML
    44  	Icon      string
    45  	Direction template.HTML
    46  	Group     bool
    47  }
    48  
    49  func GetDefaultButton(title template.HTML, icon string, action Action, colors ...template.HTML) *DefaultButton {
    50  	return defaultButton(title, "right", icon, action, false, colors...)
    51  }
    52  
    53  func GetDefaultButtonGroup(title template.HTML, icon string, action Action, colors ...template.HTML) *DefaultButton {
    54  	return defaultButton(title, "right", icon, action, true, colors...)
    55  }
    56  
    57  func defaultButton(title, direction template.HTML, icon string, action Action, group bool, colors ...template.HTML) *DefaultButton {
    58  	id := btnUUID()
    59  	action.SetBtnId("." + id)
    60  
    61  	var color, textColor template.HTML
    62  	if len(colors) > 0 {
    63  		color = colors[0]
    64  	}
    65  	if len(colors) > 1 {
    66  		textColor = colors[1]
    67  	}
    68  	node := action.GetCallbacks()
    69  	return &DefaultButton{
    70  		BaseButton: &BaseButton{
    71  			Id:     id,
    72  			Title:  title,
    73  			Action: action,
    74  			Url:    node.Path,
    75  			Method: node.Method,
    76  		},
    77  		Group:     group,
    78  		Color:     color,
    79  		TextColor: textColor,
    80  		Icon:      icon,
    81  		Direction: direction,
    82  	}
    83  }
    84  
    85  func GetColumnButton(title template.HTML, icon string, action Action, colors ...template.HTML) *DefaultButton {
    86  	return defaultButton(title, "", icon, action, true, colors...)
    87  }
    88  
    89  func (b *DefaultButton) Content() (template.HTML, template.JS) {
    90  
    91  	color := template.HTML("")
    92  	if b.Color != template.HTML("") {
    93  		color = template.HTML(`background-color:`) + b.Color + template.HTML(`;`)
    94  	}
    95  	textColor := template.HTML("")
    96  	if b.TextColor != template.HTML("") {
    97  		textColor = template.HTML(`color:`) + b.TextColor + template.HTML(`;`)
    98  	}
    99  
   100  	style := template.HTML("")
   101  	addColor := color + textColor
   102  
   103  	if addColor != template.HTML("") {
   104  		style = template.HTML(`style="`) + addColor + template.HTML(`"`)
   105  	}
   106  
   107  	h := template.HTML("")
   108  	if b.Group {
   109  		h += `<div class="btn-group pull-` + b.Direction + `" style="margin-right: 10px">`
   110  	}
   111  
   112  	h += `<a ` + style + ` class="` + template.HTML(b.Id) + ` btn btn-sm btn-default ` + b.Action.BtnClass() + `" ` + b.Action.BtnAttribute() + `>
   113                      <i class="fa ` + template.HTML(b.Icon) + `"></i>&nbsp;&nbsp;` + b.Title + `
   114                  </a>`
   115  	if b.Group {
   116  		h += `</div>`
   117  	}
   118  	return h + b.Action.ExtContent(), b.Action.Js()
   119  }
   120  
   121  type ActionButton struct {
   122  	*BaseButton
   123  }
   124  
   125  func GetActionButton(title template.HTML, action Action, ids ...string) *ActionButton {
   126  
   127  	id := ""
   128  	if len(ids) > 0 {
   129  		id = ids[0]
   130  	} else {
   131  		id = "action-info-btn-" + utils.Uuid(10)
   132  	}
   133  
   134  	action.SetBtnId("." + id)
   135  	node := action.GetCallbacks()
   136  
   137  	return &ActionButton{
   138  		BaseButton: &BaseButton{
   139  			Id:     id,
   140  			Title:  title,
   141  			Action: action,
   142  			Url:    node.Path,
   143  			Method: node.Method,
   144  		},
   145  	}
   146  }
   147  
   148  func (b *ActionButton) Content() (template.HTML, template.JS) {
   149  	h := template.HTML(`<li style="cursor: pointer;"><a data-id="{{.Id}}" class="`+template.HTML(b.Id)+` `+
   150  		b.Action.BtnClass()+`" `+b.Action.BtnAttribute()+`>`+b.Title+`</a></li>`) + b.Action.ExtContent()
   151  	return h, b.Action.Js()
   152  }
   153  
   154  type ActionIconButton struct {
   155  	Icon template.HTML
   156  	*BaseButton
   157  }
   158  
   159  func GetActionIconButton(icon string, action Action, ids ...string) *ActionIconButton {
   160  
   161  	id := ""
   162  	if len(ids) > 0 {
   163  		id = ids[0]
   164  	} else {
   165  		id = "action-info-btn-" + utils.Uuid(10)
   166  	}
   167  
   168  	action.SetBtnId("." + id)
   169  	node := action.GetCallbacks()
   170  
   171  	return &ActionIconButton{
   172  		Icon: template.HTML(icon),
   173  		BaseButton: &BaseButton{
   174  			Id:     id,
   175  			Action: action,
   176  			Url:    node.Path,
   177  			Method: node.Method,
   178  		},
   179  	}
   180  }
   181  
   182  func (b *ActionIconButton) Content() (template.HTML, template.JS) {
   183  	h := template.HTML(`<a data-id="{{.Id}}" class="`+template.HTML(b.Id)+` `+
   184  		b.Action.BtnClass()+`" `+b.Action.BtnAttribute()+`><i class="fa `+b.Icon+`" style="font-size: 16px;"></i></a>`) + b.Action.ExtContent()
   185  	return h, b.Action.Js()
   186  }
   187  
   188  type Buttons []Button
   189  
   190  func (b Buttons) Add(btn Button) Buttons {
   191  	return append(b, btn)
   192  }
   193  
   194  func (b Buttons) Content() (template.HTML, template.JS) {
   195  	h := template.HTML("")
   196  	j := template.JS("")
   197  
   198  	for _, btn := range b {
   199  		hh, jj := btn.Content()
   200  		h += hh
   201  		j += jj
   202  	}
   203  	return h, j
   204  }
   205  
   206  func (b Buttons) Copy() Buttons {
   207  	var c = make(Buttons, len(b))
   208  	copy(c, b)
   209  	return c
   210  }
   211  
   212  func (b Buttons) FooterContent() template.HTML {
   213  	footer := template.HTML("")
   214  
   215  	for _, btn := range b {
   216  		footer += btn.GetAction().FooterContent()
   217  	}
   218  	return footer
   219  }
   220  
   221  func (b Buttons) CheckPermission(user models.UserModel) Buttons {
   222  	btns := make(Buttons, 0)
   223  	for _, btn := range b {
   224  		if btn.IsType(ButtonTypeNavDropDown) {
   225  			items := make([]Button, 0)
   226  			for _, navItem := range btn.(*NavDropDownButton).Items {
   227  				if user.CheckPermissionByUrlMethod(btn.URL(), btn.METHOD(), url.Values{}) {
   228  					items = append(items, navItem)
   229  				}
   230  			}
   231  			if len(items) > 0 {
   232  				btns = append(btns, btn)
   233  			}
   234  		} else if user.CheckPermissionByUrlMethod(btn.URL(), btn.METHOD(), url.Values{}) {
   235  			btns = append(btns, btn)
   236  		}
   237  	}
   238  	return btns
   239  }
   240  
   241  func (b Buttons) CheckPermissionWhenURLAndMethodNotEmpty(user models.UserModel) Buttons {
   242  	btns := make(Buttons, 0)
   243  	for _, b := range b {
   244  		if b.URL() == "" || b.METHOD() == "" || user.CheckPermissionByUrlMethod(b.URL(), b.METHOD(), url.Values{}) {
   245  			btns = append(btns, b)
   246  		}
   247  	}
   248  	return btns
   249  }
   250  
   251  func (b Buttons) AddNavButton(ico, name string, action Action) Buttons {
   252  	if !b.CheckExist(name) {
   253  		return append(b, GetNavButton("", ico, action, name))
   254  	}
   255  	return b
   256  }
   257  
   258  func (b Buttons) RemoveButtonByName(name string) Buttons {
   259  	if name == "" {
   260  		return b
   261  	}
   262  
   263  	for i := 0; i < len(b); i++ {
   264  		if b[i].GetName() == name {
   265  			b = append(b[:i], b[i+1:]...)
   266  		}
   267  	}
   268  	return b
   269  }
   270  
   271  func (b Buttons) CheckExist(name string) bool {
   272  	if name == "" {
   273  		return false
   274  	}
   275  	for i := 0; i < len(b); i++ {
   276  		if b[i].GetName() == name {
   277  			return true
   278  		}
   279  	}
   280  	return false
   281  }
   282  
   283  func (b Buttons) Callbacks() []context.Node {
   284  	cbs := make([]context.Node, 0)
   285  	for _, btn := range b {
   286  		cbs = append(cbs, btn.GetAction().GetCallbacks())
   287  	}
   288  	return cbs
   289  }
   290  
   291  const (
   292  	NavBtnSiteName = "go_admin_site_navbtn"
   293  	NavBtnInfoName = "go_admin_info_navbtn"
   294  	NavBtnToolName = "go_admin_tool_navbtn"
   295  	NavBtnPlugName = "go_admin_plug_navbtn"
   296  )
   297  
   298  func (b Buttons) RemoveSiteNavButton() Buttons {
   299  	return b.RemoveButtonByName(NavBtnSiteName)
   300  }
   301  
   302  func (b Buttons) RemoveInfoNavButton() Buttons {
   303  	return b.RemoveButtonByName(NavBtnInfoName)
   304  }
   305  
   306  func (b Buttons) RemoveToolNavButton() Buttons {
   307  	return b.RemoveButtonByName(NavBtnToolName)
   308  }
   309  
   310  func (b Buttons) RemovePlugNavButton() Buttons {
   311  	return b.RemoveButtonByName(NavBtnPlugName)
   312  }
   313  
   314  type NavButton struct {
   315  	*BaseButton
   316  	Icon string
   317  }
   318  
   319  func GetNavButton(title template.HTML, icon string, action Action, names ...string) *NavButton {
   320  
   321  	id := btnUUID()
   322  	action.SetBtnId("." + id)
   323  	node := action.GetCallbacks()
   324  	name := ""
   325  
   326  	if len(names) > 0 {
   327  		name = names[0]
   328  	}
   329  
   330  	return &NavButton{
   331  		BaseButton: &BaseButton{
   332  			Id:     id,
   333  			Title:  title,
   334  			Action: action,
   335  			Url:    node.Path,
   336  			Method: node.Method,
   337  			Name:   name,
   338  		},
   339  		Icon: icon,
   340  	}
   341  }
   342  
   343  func (n *NavButton) Content() (template.HTML, template.JS) {
   344  
   345  	ico := template.HTML("")
   346  	title := template.HTML("")
   347  
   348  	if n.Icon != "" {
   349  		ico = template.HTML(`<i class="fa ` + n.Icon + `"></i>`)
   350  	}
   351  
   352  	if n.Title != "" {
   353  		title = `<span>` + n.Title + `</span>`
   354  	}
   355  
   356  	h := template.HTML(`<li>
   357      <a class="`+template.HTML(n.Id)+` `+n.Action.BtnClass()+`" `+n.Action.BtnAttribute()+`>
   358        `+ico+`
   359        `+title+`
   360      </a>
   361  </li>`) + n.Action.ExtContent()
   362  	return h, n.Action.Js()
   363  }
   364  
   365  type NavDropDownButton struct {
   366  	*BaseButton
   367  	Icon  string
   368  	Items []*NavDropDownItemButton
   369  }
   370  
   371  type NavDropDownItemButton struct {
   372  	*BaseButton
   373  }
   374  
   375  func GetDropDownButton(title template.HTML, icon string, items []*NavDropDownItemButton, names ...string) *NavDropDownButton {
   376  	id := btnUUID()
   377  	name := ""
   378  
   379  	if len(names) > 0 {
   380  		name = names[0]
   381  	}
   382  
   383  	return &NavDropDownButton{
   384  		BaseButton: &BaseButton{
   385  			Id:       id,
   386  			Title:    title,
   387  			Name:     name,
   388  			TypeName: ButtonTypeNavDropDown,
   389  			Action:   new(NilAction),
   390  		},
   391  		Items: items,
   392  		Icon:  icon,
   393  	}
   394  }
   395  
   396  func (n *NavDropDownButton) SetItems(items []*NavDropDownItemButton) {
   397  	n.Items = items
   398  }
   399  
   400  func (n *NavDropDownButton) AddItem(item *NavDropDownItemButton) {
   401  	n.Items = append(n.Items, item)
   402  }
   403  
   404  func (n *NavDropDownButton) Content() (template.HTML, template.JS) {
   405  
   406  	ico := template.HTML("")
   407  	title := template.HTML("")
   408  
   409  	if n.Icon != "" {
   410  		ico = template.HTML(`<i class="fa ` + n.Icon + `"></i>`)
   411  	}
   412  
   413  	if n.Title != "" {
   414  		title = `<span>` + n.Title + `</span>`
   415  	}
   416  
   417  	content := template.HTML("")
   418  	js := template.JS("")
   419  
   420  	for _, item := range n.Items {
   421  		c, j := item.Content()
   422  		content += c
   423  		js += j
   424  	}
   425  
   426  	did := utils.Uuid(10)
   427  
   428  	h := template.HTML(`<li class="dropdown" id="` + template.HTML(did) + `">
   429      <a class="` + template.HTML(n.Id) + ` dropdown-toggle" data-toggle="dropdown" style="cursor:pointer;">
   430        ` + ico + `
   431        ` + title + `
   432      </a>
   433  	<ul class="dropdown-menu"  aria-labelledby="` + template.HTML(did) + `">
   434      	` + content + `
   435  	</ul>
   436  </li>`)
   437  
   438  	return h, js
   439  }
   440  
   441  const (
   442  	ButtonTypeNavDropDownItem = "navdropdownitem"
   443  	ButtonTypeNavDropDown     = "navdropdown"
   444  )
   445  
   446  func GetDropDownItemButton(title template.HTML, action Action, names ...string) *NavDropDownItemButton {
   447  	id := btnUUID()
   448  	action.SetBtnId("." + id)
   449  	node := action.GetCallbacks()
   450  	name := ""
   451  
   452  	if len(names) > 0 {
   453  		name = names[0]
   454  	}
   455  
   456  	return &NavDropDownItemButton{
   457  		BaseButton: &BaseButton{
   458  			Id:       id,
   459  			Title:    title,
   460  			Action:   action,
   461  			Url:      node.Path,
   462  			Method:   node.Method,
   463  			Name:     name,
   464  			TypeName: ButtonTypeNavDropDownItem,
   465  		},
   466  	}
   467  }
   468  
   469  func (n *NavDropDownItemButton) Content() (template.HTML, template.JS) {
   470  
   471  	title := template.HTML("")
   472  
   473  	if n.Title != "" {
   474  		title = `<span>` + n.Title + `</span>`
   475  	}
   476  
   477  	h := template.HTML(`<li><a class="dropdown-item `+template.HTML(n.Id)+` `+
   478  		n.Action.BtnClass()+`" `+n.Action.BtnAttribute()+`>
   479        `+title+`
   480  </a></li>`) + n.Action.ExtContent()
   481  	return h, n.Action.Js()
   482  }