Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion src/diagonal.works/b6/ui/lines.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package ui

import (
"cmp"
"fmt"
"reflect"
"slices"
"strconv"
"strings"

Expand Down Expand Up @@ -223,7 +225,7 @@ func lineFromTags(tags []b6.Tag, f b6.Feature) *pb.LineProto {
Tags: make([]*pb.TagAtomProto, len(tags)),
}
for i, tag := range tags {
if strings.HasPrefix(tag.Key, "#") || strings.HasPrefix(tag.Key, "#") {
if strings.HasPrefix(tag.Key, "#") {
tl.Tags[i] = &pb.TagAtomProto{Prefix: tag.Key[0:1], Key: tag.Key[1:], Value: tag.Value.String()}
} else {
tl.Tags[i] = &pb.TagAtomProto{Prefix: "", Key: tag.Key, Value: tag.Value.String()}
Expand Down Expand Up @@ -434,6 +436,9 @@ func fillSubstacksFromFeature(response *UIResponseJSON, substacks []*pb.Substack
if tags := f.AllTags(); len(tags) > 0 {
substack := &pb.SubstackProto{Collapsable: true}
line := leftRightValueLineFromValues("Tags", len(tags), w)
// TODO: Work out which one to call here
// sortTagsAlphabetically(tags)
// sortTagsReverseAlphabetically(tags)
substack.Lines = append(substack.Lines, line, lineFromTags(tags, f))
substacks = append(substacks, substack)
}
Expand Down Expand Up @@ -633,3 +638,48 @@ func sortableKeyForString(s string) string {
}
return s
}

// Sort tags alphabetically by the key, but also ignore the "#" if it is in
// front of the tag name; i.e. "c, #b, a" should result in "a, #b, c".
func sortTagsAlphabetically(tags []b6.Tag) {
slices.SortFunc(tags, func(a, b b6.Tag) int {
var aa, bb string
if strings.HasPrefix(a.Key, "#") {
aa = a.Key[1:]
} else {
aa = a.Key
}
if strings.HasPrefix(b.Key, "#") {
bb = b.Key[1:]
} else {
bb = b.Key
}
return cmp.Compare(aa, bb)
})
}

func sortTagsReverseAlphabetically(tags []b6.Tag) {
sortTagsAlphabetically(tags)
slices.Reverse(tags)
}

func removeAtIndex[E any](slice []E, s int) []E {
return append(slice[:s], slice[s+1:]...)
}

// Given the provided sorted list, bump the ones in the 'priority' to the top
// of the list, in the order provided in that list.
func withPriorityItems(priority []string, tags []b6.Tag) []b6.Tag {
tmp := make([]b6.Tag, len(tags))
copy(tmp, tags)
result := make([]b6.Tag, 0)
for _, tagName := range priority {
idx := slices.IndexFunc(tmp, func(t b6.Tag) bool { return t.Key == tagName })
if idx >= 0 {
tag := tmp[idx]
tmp = removeAtIndex(tmp, idx)
result = append(result, tag)
}
}
return append(result, tmp...)
}
8 changes: 6 additions & 2 deletions src/diagonal.works/b6/ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,9 @@ func (o *OpenSourceUI) ServeStartup(request *StartupRequest, response *StartupRe
} else if !ok {
break
}
if i.Key() == "centroid" {

switch i.Key() {
case "centroid":
switch v := i.Value().(type) {
// Read a raw point from the yaml:
//
Expand Down Expand Up @@ -461,7 +463,9 @@ func (o *OpenSourceUI) ServeStartup(request *StartupRequest, response *StartupRe
default:
return fmt.Errorf("Couldn't interpret centroid in world %s of type %T", request.Root, i.Value())
}
} else if i.Key() == "docked" {
case "tag-ordering":
log.Printf("About to consider tag-sorting-method %s", i.Value())
case "docked":
if featureId, ok := i.Value().(b6.FeatureID); ok {
if docked := w.FindFeatureByID(featureId); docked != nil {
uiResponse := NewUIResponseJSON()
Expand Down
44 changes: 44 additions & 0 deletions src/diagonal.works/b6/ui/ui_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,47 @@ func TestEqualiseBars(t *testing.T) {
t.Errorf("Expected no difference, found: %s", diff)
}
}

func TestSortingTags(t *testing.T) {
a := b6.Tag{Key: "a"}
b := b6.Tag{Key: "#b"}
c := b6.Tag{Key: "c"}

input := []b6.Tag{b, a, c}

// Alphabetical first:
expected := []b6.Tag{a, b, c}
sortTagsAlphabetically(input)

if diff := cmp.Diff(input, expected); diff != "" {
t.Errorf("Expected no difference, found: %s", diff)
}

// Then the other way around
expected = []b6.Tag{c, b, a}
sortTagsReverseAlphabetically(input)

if diff := cmp.Diff(input, expected); diff != "" {
t.Errorf("Expected no difference, found: %s", diff)
}

// Now with a fixed list at the top
priorityList := []string{"#b", "x"}
sortTagsAlphabetically(input)
result := withPriorityItems(priorityList, input)
expected = []b6.Tag{b, a, c}

if diff := cmp.Diff(result, expected); diff != "" {
t.Errorf("Expected no difference, found: %s", diff)
}

// Another other scenario
priorityList = []string{"#b", "c"}
sortTagsAlphabetically(input)
result = withPriorityItems(priorityList, input)
expected = []b6.Tag{b, c, a}

if diff := cmp.Diff(result, expected); diff != "" {
t.Errorf("Expected no difference, found: %s", diff)
}
}