dashboard_entities.go 4.0 KB

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