row_menu.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package presets
  2. import (
  3. "fmt"
  4. "github.com/iancoleman/strcase"
  5. . "github.com/qor5/ui/vuetify"
  6. vx "github.com/qor5/ui/vuetifyx"
  7. "github.com/qor5/web"
  8. "github.com/qor5/x/i18n"
  9. h "github.com/theplant/htmlgo"
  10. )
  11. type RowMenuBuilder struct {
  12. lb *ListingBuilder
  13. listings []string
  14. defaultListings []string
  15. items map[string]*RowMenuItemBuilder
  16. }
  17. func (b *ListingBuilder) RowMenu(listings ...string) *RowMenuBuilder {
  18. if b.rowMenu == nil {
  19. b.rowMenu = &RowMenuBuilder{
  20. lb: b,
  21. listings: listings,
  22. items: make(map[string]*RowMenuItemBuilder),
  23. }
  24. }
  25. rmb := b.rowMenu
  26. if len(listings) == 0 {
  27. return rmb
  28. }
  29. rmb.listings = listings
  30. for _, li := range rmb.listings {
  31. rmb.RowMenuItem(li)
  32. }
  33. return rmb
  34. }
  35. func (b *RowMenuBuilder) Empty() {
  36. b.listings = nil
  37. b.items = nil
  38. }
  39. func (b *RowMenuBuilder) listingItemFuncs(ctx *web.EventContext) (fs []vx.RowMenuItemFunc) {
  40. listings := b.defaultListings
  41. if len(b.listings) > 0 {
  42. listings = b.listings
  43. }
  44. for _, li := range listings {
  45. if ib, ok := b.items[strcase.ToSnake(li)]; ok {
  46. fs = append(fs, ib.getComponentFunc(ctx))
  47. }
  48. }
  49. return fs
  50. }
  51. type RowMenuItemBuilder struct {
  52. rmb *RowMenuBuilder
  53. name string
  54. icon string
  55. clickF RowMenuItemClickFunc
  56. compF vx.RowMenuItemFunc
  57. permAction string
  58. eventID string
  59. }
  60. func (b *RowMenuBuilder) RowMenuItem(name string) *RowMenuItemBuilder {
  61. if v, ok := b.items[strcase.ToSnake(name)]; ok {
  62. return v
  63. }
  64. ib := &RowMenuItemBuilder{
  65. rmb: b,
  66. name: name,
  67. eventID: fmt.Sprintf("%s_rowMenuItemFunc_%s", b.lb.mb.uriName, name),
  68. }
  69. b.items[strcase.ToSnake(name)] = ib
  70. b.defaultListings = append(b.defaultListings, name)
  71. b.lb.mb.RegisterEventFunc(ib.eventID, func(ctx *web.EventContext) (r web.EventResponse, err error) {
  72. id := ctx.R.FormValue(ParamID)
  73. if ib.permAction != "" {
  74. var obj = b.lb.mb.NewModel()
  75. obj, err = b.lb.mb.editing.Fetcher(obj, id, ctx)
  76. if err != nil {
  77. return r, err
  78. }
  79. err = b.lb.mb.Info().Verifier().Do(ib.permAction).ObjectOn(obj).WithReq(ctx.R).IsAllowed()
  80. if err != nil {
  81. return r, err
  82. }
  83. }
  84. if ib.clickF == nil {
  85. return r, nil
  86. }
  87. return ib.clickF(ctx, id)
  88. })
  89. return ib
  90. }
  91. func (b *RowMenuItemBuilder) Icon(v string) *RowMenuItemBuilder {
  92. b.icon = v
  93. return b
  94. }
  95. type RowMenuItemClickFunc func(ctx *web.EventContext, id string) (r web.EventResponse, err error)
  96. func (b *RowMenuItemBuilder) OnClick(v RowMenuItemClickFunc) *RowMenuItemBuilder {
  97. b.clickF = v
  98. return b
  99. }
  100. func (b *RowMenuItemBuilder) ComponentFunc(v vx.RowMenuItemFunc) *RowMenuItemBuilder {
  101. b.compF = v
  102. return b
  103. }
  104. func (b *RowMenuItemBuilder) PermAction(v string) *RowMenuItemBuilder {
  105. b.permAction = v
  106. return b
  107. }
  108. func (b *RowMenuItemBuilder) getComponentFunc(ctx *web.EventContext) vx.RowMenuItemFunc {
  109. if b.compF != nil {
  110. return b.compF
  111. }
  112. return func(obj interface{}, id string, ctx *web.EventContext) h.HTMLComponent {
  113. if b.permAction != "" && b.rmb.lb.mb.Info().Verifier().Do(b.permAction).ObjectOn(obj).WithReq(ctx.R).IsAllowed() != nil {
  114. return nil
  115. }
  116. return VListItem(
  117. VListItemIcon(VIcon(b.icon)),
  118. VListItemTitle(h.Text(i18n.PT(ctx.R, ModelsI18nModuleKey, strcase.ToCamel(b.rmb.lb.mb.label+" RowMenuItem"), b.name))),
  119. ).Attr("@click", web.Plaid().
  120. EventFunc(b.eventID).
  121. Query(ParamID, id).
  122. Go())
  123. }
  124. }