dashboard_entities.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package api
  2. import (
  3. apiv1 "github.com/OliveTin/OliveTin/gen/olivetin/api/v1"
  4. config "github.com/OliveTin/OliveTin/internal/config"
  5. entities "github.com/OliveTin/OliveTin/internal/entities"
  6. "github.com/OliveTin/OliveTin/internal/tpl"
  7. log "github.com/sirupsen/logrus"
  8. )
  9. func buildEntityFieldsets(entityTitle string, tpl *config.DashboardComponent, rr *DashboardRenderRequest) []*apiv1.DashboardComponent {
  10. ret := make([]*apiv1.DashboardComponent, 0)
  11. orderedEntities := entities.GetEntityInstancesOrdered(entityTitle)
  12. for _, ent := range orderedEntities {
  13. fs := buildEntityFieldset(tpl, ent, rr)
  14. if len(fs.Contents) > 0 {
  15. ret = append(ret, fs)
  16. }
  17. }
  18. return ret
  19. }
  20. func buildEntityFieldset(component *config.DashboardComponent, ent *entities.Entity, rr *DashboardRenderRequest) *apiv1.DashboardComponent {
  21. return &apiv1.DashboardComponent{
  22. Title: tpl.ParseTemplateOfActionBeforeExec(component.Title, ent),
  23. Type: "fieldset",
  24. Contents: removeFieldsetIfHasNoLinks(buildEntityFieldsetContents(component.Contents, ent, component.Entity, rr)),
  25. CssClass: tpl.ParseTemplateOfActionBeforeExec(component.CssClass, ent),
  26. Action: rr.findActionForEntity(component.Title, ent),
  27. EntityType: component.Entity,
  28. EntityKey: ent.UniqueKey,
  29. }
  30. }
  31. func removeFieldsetIfHasNoLinks(contents []*apiv1.DashboardComponent) []*apiv1.DashboardComponent {
  32. return contents
  33. /*
  34. for _, subitem := range contents {
  35. if subitem.Type == "link" {
  36. return contents
  37. }
  38. }
  39. log.Infof("removeFieldsetIfHasNoLinks: %+v", contents)
  40. return nil
  41. */
  42. }
  43. func buildEntityFieldsetContents(contents []*config.DashboardComponent, ent *entities.Entity, entityType string, rr *DashboardRenderRequest) []*apiv1.DashboardComponent {
  44. ret := make([]*apiv1.DashboardComponent, 0)
  45. for _, subitem := range contents {
  46. c := cloneItem(subitem, ent, entityType, rr)
  47. log.Tracef("cloneItem: %+v", c)
  48. if c != nil {
  49. ret = append(ret, c)
  50. }
  51. }
  52. return ret
  53. }
  54. func cloneItem(subitem *config.DashboardComponent, ent *entities.Entity, entityType string, rr *DashboardRenderRequest) *apiv1.DashboardComponent {
  55. clone := &apiv1.DashboardComponent{}
  56. clone.CssClass = tpl.ParseTemplateOfActionBeforeExec(subitem.CssClass, ent)
  57. if isLinkType(subitem.Type) {
  58. return cloneLinkItem(subitem, ent, clone, rr)
  59. }
  60. return cloneNonLinkItem(subitem, ent, entityType, clone, rr)
  61. }
  62. func isLinkType(itemType string) bool {
  63. return itemType == "" || itemType == "link"
  64. }
  65. func cloneLinkItem(subitem *config.DashboardComponent, ent *entities.Entity, clone *apiv1.DashboardComponent, rr *DashboardRenderRequest) *apiv1.DashboardComponent {
  66. // Prefer an entity-specific action when available, but fall back to a
  67. // non-entity-scoped action with the same title. This allows inline actions
  68. // defined inside entity dashboards to work without requiring an explicit
  69. // entity binding.
  70. action := rr.findActionForEntity(subitem.Title, ent)
  71. if action == nil {
  72. action = rr.findAction(subitem.Title)
  73. }
  74. if action == nil {
  75. return nil
  76. }
  77. clone.Type = "link"
  78. clone.Title = tpl.ParseTemplateOfActionBeforeExec(subitem.Title, ent)
  79. clone.Action = action
  80. return clone
  81. }
  82. func cloneNonLinkItem(subitem *config.DashboardComponent, ent *entities.Entity, entityType string, clone *apiv1.DashboardComponent, rr *DashboardRenderRequest) *apiv1.DashboardComponent {
  83. clone.Title = tpl.ParseTemplateOfActionBeforeExec(subitem.Title, ent)
  84. clone.Type = subitem.Type
  85. if isDirectoryWithEntity(clone.Type, ent, entityType) {
  86. clone.EntityType = entityType
  87. clone.EntityKey = ent.UniqueKey
  88. }
  89. if len(subitem.Contents) > 0 {
  90. clone.Contents = buildEntityFieldsetContents(subitem.Contents, ent, entityType, rr)
  91. }
  92. return clone
  93. }
  94. func isDirectoryWithEntity(itemType string, ent *entities.Entity, entityType string) bool {
  95. return itemType == "directory" && ent != nil && entityType != ""
  96. }