config.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package views
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strings"
  6. "github.com/qor5/admin/activity"
  7. "github.com/qor5/admin/presets"
  8. "github.com/qor5/admin/presets/actions"
  9. "github.com/qor5/admin/publish"
  10. . "github.com/qor5/ui/vuetify"
  11. "github.com/qor5/web"
  12. "github.com/qor5/x/i18n"
  13. "github.com/sunfmin/reflectutils"
  14. h "github.com/theplant/htmlgo"
  15. "golang.org/x/text/language"
  16. "gorm.io/gorm"
  17. )
  18. const I18nPublishKey i18n.ModuleKey = "I18nPublishKey"
  19. func Configure(b *presets.Builder, db *gorm.DB, ab *activity.ActivityBuilder, publisher *publish.Builder, models ...*presets.ModelBuilder) {
  20. for _, m := range models {
  21. obj := m.NewModel()
  22. _ = obj.(presets.SlugEncoder)
  23. _ = obj.(presets.SlugDecoder)
  24. if model, ok := obj.(publish.VersionInterface); ok {
  25. if schedulePublishModel, ok := model.(publish.ScheduleInterface); ok {
  26. publish.VersionPublishModels[m.Info().URIName()] = reflect.ValueOf(schedulePublishModel).Elem().Interface()
  27. }
  28. m.Editing().SidePanelFunc(sidePanel(db, m)).ActionsFunc(versionActionsFunc(m))
  29. searcher := m.Listing().Searcher
  30. mb := m
  31. m.Listing().SearchFunc(func(model interface{}, params *presets.SearchParams, ctx *web.EventContext) (r interface{}, totalCount int, err error) {
  32. stmt := &gorm.Statement{DB: db}
  33. stmt.Parse(mb.NewModel())
  34. tn := stmt.Schema.Table
  35. var pks []string
  36. condition := ""
  37. for _, f := range stmt.Schema.Fields {
  38. if f.Name == "DeletedAt" {
  39. condition = "WHERE deleted_at IS NULL"
  40. }
  41. }
  42. for _, f := range stmt.Schema.PrimaryFields {
  43. if f.Name != "Version" {
  44. pks = append(pks, f.DBName)
  45. }
  46. }
  47. pkc := strings.Join(pks, ",")
  48. sql := fmt.Sprintf("(%v,version) IN (SELECT %v, MAX(version) FROM %v %v GROUP BY %v)", pkc, pkc, tn, condition, pkc)
  49. con := presets.SQLCondition{
  50. Query: sql,
  51. }
  52. params.SQLConditions = append(params.SQLConditions, &con)
  53. return searcher(model, params, ctx)
  54. })
  55. // listing-delete deletes all versions
  56. {
  57. // rewrite Delete row menu item to show correct id in prompt message
  58. m.Listing().RowMenu().RowMenuItem("Delete").ComponentFunc(func(obj interface{}, id string, ctx *web.EventContext) h.HTMLComponent {
  59. msgr := presets.MustGetMessages(ctx.R)
  60. if m.Info().Verifier().Do(presets.PermDelete).ObjectOn(obj).WithReq(ctx.R).IsAllowed() != nil {
  61. return nil
  62. }
  63. promptID := id
  64. if slugger, ok := obj.(presets.SlugDecoder); ok {
  65. fvs := []string{}
  66. for f, v := range slugger.PrimaryColumnValuesBySlug(id) {
  67. if f == "id" {
  68. fvs = append([]string{v}, fvs...)
  69. } else {
  70. if f != "version" {
  71. fvs = append(fvs, v)
  72. }
  73. }
  74. }
  75. promptID = strings.Join(fvs, "_")
  76. }
  77. onclick := web.Plaid().
  78. EventFunc(actions.DeleteConfirmation).
  79. Query(presets.ParamID, id).
  80. Query("all_versions", true).
  81. Query("prompt_id", promptID)
  82. if presets.IsInDialog(ctx.R.Context()) {
  83. onclick.URL(ctx.R.RequestURI).
  84. Query(presets.ParamOverlay, actions.Dialog).
  85. Query(presets.ParamInDialog, true).
  86. Query(presets.ParamListingQueries, ctx.Queries().Encode())
  87. }
  88. return VListItem(
  89. VListItemIcon(VIcon("delete")),
  90. VListItemTitle(h.Text(msgr.Delete)),
  91. ).Attr("@click", onclick.Go())
  92. })
  93. // rewrite Deleter to ignore version condition
  94. m.Editing().DeleteFunc(func(obj interface{}, id string, ctx *web.EventContext) (err error) {
  95. allVersions := ctx.R.URL.Query().Get("all_versions") == "true"
  96. wh := db.Model(obj)
  97. if id != "" {
  98. if slugger, ok := obj.(presets.SlugDecoder); ok {
  99. cs := slugger.PrimaryColumnValuesBySlug(id)
  100. for key, value := range cs {
  101. if allVersions && key == "version" {
  102. continue
  103. }
  104. wh = wh.Where(fmt.Sprintf("%s = ?", key), value)
  105. }
  106. } else {
  107. wh = wh.Where("id = ?", id)
  108. }
  109. }
  110. return wh.Delete(obj).Error
  111. })
  112. }
  113. setter := m.Editing().Setter
  114. m.Editing().SetterFunc(func(obj interface{}, ctx *web.EventContext) {
  115. if ctx.R.FormValue(presets.ParamID) == "" {
  116. version := fmt.Sprintf("%s-v01", db.NowFunc().Format("2006-01-02"))
  117. if err := reflectutils.Set(obj, "Version.Version", version); err != nil {
  118. return
  119. }
  120. if err := reflectutils.Set(obj, "Version.VersionName", version); err != nil {
  121. return
  122. }
  123. }
  124. if setter != nil {
  125. setter(obj, ctx)
  126. }
  127. })
  128. m.Listing().Field("Draft Count").ComponentFunc(draftCountFunc(db))
  129. m.Listing().Field("Online").ComponentFunc(onlineFunc(db))
  130. if m.Editing().GetField("StatusBar") != nil {
  131. m.Editing().Field("StatusBar").ComponentFunc(StatusEditFunc())
  132. }
  133. } else {
  134. if schedulePublishModel, ok := obj.(publish.ScheduleInterface); ok {
  135. publish.NonVersionPublishModels[m.Info().URIName()] = reflect.ValueOf(schedulePublishModel).Elem().Interface()
  136. }
  137. }
  138. if model, ok := obj.(publish.ListInterface); ok {
  139. if schedulePublishModel, ok := model.(publish.ScheduleInterface); ok {
  140. publish.ListPublishModels[m.Info().URIName()] = reflect.ValueOf(schedulePublishModel).Elem().Interface()
  141. }
  142. }
  143. registerEventFuncs(db, m, publisher, ab)
  144. }
  145. b.FieldDefaults(presets.LIST).
  146. FieldType(publish.Status{}).
  147. ComponentFunc(StatusListFunc())
  148. b.FieldDefaults(presets.WRITE).
  149. FieldType(publish.Schedule{}).
  150. ComponentFunc(ScheduleEditFunc()).
  151. SetterFunc(ScheduleEditSetterFunc)
  152. b.I18n().
  153. RegisterForModule(language.English, I18nPublishKey, Messages_en_US).
  154. RegisterForModule(language.SimplifiedChinese, I18nPublishKey, Messages_zh_CN).
  155. RegisterForModule(language.Japanese, I18nPublishKey, Messages_ja_JP)
  156. }