| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- package executor
- import (
- "fmt"
- config "github.com/OliveTin/OliveTin/internal/config"
- "github.com/OliveTin/OliveTin/internal/entities"
- )
- type DashboardNavigationTarget struct {
- Title string
- EntityType string
- EntityKey string
- Path string
- }
- func (target DashboardNavigationTarget) key() string {
- return target.Title + "\x00" + target.EntityType + "\x00" + target.EntityKey
- }
- func (b *ActionBinding) IsOnConfiguredDashboard() bool {
- for _, dashboard := range b.OnDashboards {
- if dashboard.Title != "Actions" {
- return true
- }
- }
- return false
- }
- type dashboardTargetIndex struct {
- byTitle map[string][]DashboardNavigationTarget
- byTitleEntityKey map[string]map[string][]DashboardNavigationTarget
- }
- func buildDashboardTargetIndex(cfg *config.Config) *dashboardTargetIndex {
- index := &dashboardTargetIndex{
- byTitle: make(map[string][]DashboardNavigationTarget),
- byTitleEntityKey: make(map[string]map[string][]DashboardNavigationTarget),
- }
- for _, dashboard := range cfg.Dashboards {
- walkDashboardContents(dashboard.Contents, dashboard.Title, index)
- }
- return index
- }
- func walkDashboardContents(contents []*config.DashboardComponent, rootDashboardTitle string, index *dashboardTargetIndex) {
- for _, component := range contents {
- walkDashboardComponent(component, rootDashboardTitle, index)
- }
- }
- func walkDashboardComponent(component *config.DashboardComponent, rootDashboardTitle string, index *dashboardTargetIndex) {
- if component.Type == "fieldset" && component.Entity != "" {
- walkEntityFieldset(component, rootDashboardTitle, component.Entity, index)
- return
- }
- recordActionTarget(component, rootDashboardTitle, "", "", index)
- if len(component.Contents) > 0 {
- walkDashboardContents(component.Contents, rootDashboardTitle, index)
- }
- }
- func walkEntityFieldset(fieldset *config.DashboardComponent, rootDashboardTitle, entityType string, index *dashboardTargetIndex) {
- for _, component := range fieldset.Contents {
- if component.Type == "directory" {
- walkEntityDirectory(component, entityType, index)
- continue
- }
- recordActionTargetForAllEntities(component, rootDashboardTitle, entityType, index)
- if len(component.Contents) > 0 {
- walkEntityFieldsetContents(component.Contents, rootDashboardTitle, entityType, index)
- }
- }
- }
- func walkEntityFieldsetContents(contents []*config.DashboardComponent, rootDashboardTitle, entityType string, index *dashboardTargetIndex) {
- for _, component := range contents {
- if component.Type == "directory" {
- walkEntityDirectory(component, entityType, index)
- continue
- }
- recordActionTargetForAllEntities(component, rootDashboardTitle, entityType, index)
- if len(component.Contents) > 0 {
- walkEntityFieldsetContents(component.Contents, rootDashboardTitle, entityType, index)
- }
- }
- }
- func walkEntityDirectory(directory *config.DashboardComponent, entityType string, index *dashboardTargetIndex) {
- for _, entity := range entities.GetEntityInstancesOrdered(entityType) {
- for _, component := range directory.Contents {
- recordActionTarget(component, directory.Title, entityType, entity.UniqueKey, index)
- }
- }
- }
- func recordActionTargetForAllEntities(component *config.DashboardComponent, rootDashboardTitle, entityType string, index *dashboardTargetIndex) {
- actionTitle := actionTitleFromComponent(component)
- if actionTitle == "" {
- return
- }
- target := dashboardNavigationTarget(rootDashboardTitle, "", "")
- for _, entity := range entities.GetEntityInstancesOrdered(entityType) {
- addEntityTarget(index, actionTitle, entity.UniqueKey, target)
- }
- }
- func recordActionTarget(component *config.DashboardComponent, dashboardTitle, entityType, entityKey string, index *dashboardTargetIndex) {
- actionTitle := actionTitleFromComponent(component)
- if actionTitle == "" {
- return
- }
- target := dashboardNavigationTarget(dashboardTitle, entityType, entityKey)
- if entityType != "" && entityKey != "" {
- addEntityTarget(index, actionTitle, entityKey, target)
- return
- }
- addTitleTarget(index, actionTitle, target)
- }
- func actionTitleFromComponent(component *config.DashboardComponent) string {
- if title := inlineActionTitle(component); title != "" {
- return title
- }
- if component.Type == "link" || component.Type == "" {
- return component.Title
- }
- return ""
- }
- func inlineActionTitle(component *config.DashboardComponent) string {
- if component.InlineAction == nil {
- return ""
- }
- if component.Title != "" {
- return component.Title
- }
- return component.InlineAction.Title
- }
- func dashboardNavigationTarget(title, entityType, entityKey string) DashboardNavigationTarget {
- return DashboardNavigationTarget{
- Title: title,
- EntityType: entityType,
- EntityKey: entityKey,
- Path: dashboardNavigationPath(title, entityType, entityKey),
- }
- }
- func dashboardNavigationPath(title, entityType, entityKey string) string {
- if title == "Actions" {
- return "/"
- }
- if entityType != "" && entityKey != "" {
- return fmt.Sprintf("/dashboards/%s/%s/%s", title, entityType, entityKey)
- }
- return fmt.Sprintf("/dashboards/%s", title)
- }
- func addTitleTarget(index *dashboardTargetIndex, actionTitle string, target DashboardNavigationTarget) {
- index.byTitle[actionTitle] = appendUniqueTarget(index.byTitle[actionTitle], target)
- }
- func addEntityTarget(index *dashboardTargetIndex, actionTitle, entityKey string, target DashboardNavigationTarget) {
- if index.byTitleEntityKey[actionTitle] == nil {
- index.byTitleEntityKey[actionTitle] = make(map[string][]DashboardNavigationTarget)
- }
- entityTargets := index.byTitleEntityKey[actionTitle][entityKey]
- index.byTitleEntityKey[actionTitle][entityKey] = appendUniqueTarget(entityTargets, target)
- }
- func appendUniqueTarget(targets []DashboardNavigationTarget, target DashboardNavigationTarget) []DashboardNavigationTarget {
- for _, existing := range targets {
- if existing.key() == target.key() {
- return targets
- }
- }
- return append(targets, target)
- }
- func (index *dashboardTargetIndex) targetsForAction(actionTitle string) []DashboardNavigationTarget {
- return dedupeTargets(index.byTitle[actionTitle])
- }
- func (index *dashboardTargetIndex) targetsForEntityAction(actionTitle, entityKey string) []DashboardNavigationTarget {
- targets := make([]DashboardNavigationTarget, 0)
- targets = append(targets, index.byTitle[actionTitle]...)
- if entityTargets, ok := index.byTitleEntityKey[actionTitle]; ok {
- targets = append(targets, entityTargets[entityKey]...)
- }
- return dedupeTargets(targets)
- }
- func dedupeTargets(targets []DashboardNavigationTarget) []DashboardNavigationTarget {
- if len(targets) == 0 {
- return nil
- }
- seen := make(map[string]bool, len(targets))
- result := make([]DashboardNavigationTarget, 0, len(targets))
- for _, target := range targets {
- key := target.key()
- if seen[key] {
- continue
- }
- seen[key] = true
- result = append(result, target)
- }
- return result
- }
- func resolveOnDashboards(index *dashboardTargetIndex, actionTitle, entityKey string) []DashboardNavigationTarget {
- var targets []DashboardNavigationTarget
- if entityKey == "" {
- targets = index.targetsForAction(actionTitle)
- } else {
- targets = index.targetsForEntityAction(actionTitle, entityKey)
- }
- if len(targets) == 0 {
- return []DashboardNavigationTarget{dashboardNavigationTarget("Actions", "", "")}
- }
- return targets
- }
|