okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
a1b0eb5
main
1package daemon 2 3import ( 4"context" 5"encoding/json" 6"fmt" 7"io" 8"net/http" 9"strings" 10 11"albedo/cli/internal/daemon/protocol" 12) 13 14type linkConfiguration struct { 15Value protocol.LinkConfiguration 16ETag string 17} 18 19func getLinkConfiguration (ctx context.Context ,conn * Connection ,workspace string ) (linkConfiguration ,error ) { 20result := linkConfiguration {} 21params := protocol.GetLinkGroupParams {Workspace :workspace ,View :new ("configuration "),Limit :new (int64 (200 ))} 22err := executeRead (ctx ,conn ,operation {Name :"read linked workspace membership" ,BuildRequest :func (base string ,body io.Reader ) (* http.Request ,error ) { 23return protocol .NewGetLinkGroupRequest (base ,& params ) 24 },Validator :& result .ETag ,Policy :readRecovery },func (data []byte )error { 25if err := decodeRequired (data ,& result .Value );err != nil { 26return err 27 } 28if result .Value .Workspace == "" || result .Value .GroupID == "" || result .ETag == "" { 29return fieldError ("link configuration" ) 30 } 31return nil 32 }) 33return result ,err 34} 35 36// PrepareLinkMerge captures both groups before a person confirms their merge. 37func PrepareLinkMerge (ctx context.Context ,conn * Connection ,session Session ,otherWorkspace string ) (* PageDocument ,error ) { 38current ,err := getLinkConfiguration (ctx ,conn ,session .Workspace ) 39if err != nil { 40return nil ,err 41 } 42other ,err := getLinkConfiguration (ctx ,conn ,otherWorkspace ) 43if err != nil { 44return nil ,err 45 } 46if current .Value .GroupID == other .Value .GroupID { 47return nil ,fmt .Errorf ("these workspaces already share a linked group" ) 48 } 49params := protocol.MergeLinkGroupsParams {Workspace :current .Value .Workspace ,View :"configuration" ,IfMatch :current .ETag } 50request ,err := protocol .NewMergeLinkGroupsRequestWithBody ("" ,& params ,"application/json" ,nil ) 51if err != nil { 52return nil ,err 53 } 54literal := func (v any ) protocol.Binding { 55encoded ,_ := json .Marshal (map [string ]any {"source" :"literal" ,"value" :v }) 56return protocol .Binding (encoded ) 57 } 58operation := protocol.ActionOperation {OperationID :"mergeLinkGroups" ,Method :request .Method ,PathTemplate :request .URL .Path ,Path :map [string ]protocol.Binding {},Query :map [string ]protocol.Binding {"workspace" :literal (current .Value .Workspace ),"view" :literal ("configuration" )},Headers :map [string ]protocol.Binding {"If-Match" :literal (current .ETag )},Body :map [string ]protocol.Binding {"/other_workspace" :literal (other .Value .Workspace ),"/other_etag" :literal (other .ETag )},ResultSchema :json .RawMessage (`{}` )} 59doc := & PageDocument {Title :"Link workspace groups" ,Summary :"The complete groups will share memory and work after you confirm." ,Session :& session ,Rows : []PageRow {},Actions : []PageAction {{ID :"merge" ,Key :"enter" ,Label :"link these groups" ,Confirmation :"Link both displayed workspace groups?" ,Confirm :true ,Operation :operation }}} 60for _ ,group := range []linkConfiguration {current ,other } { 61detail := strings .Join (group .Value .Members ,"\n" ) 62if group .Value .Next != nil { 63detail += "\nAdditional members are omitted from this preview." 64 } 65doc .Rows = append (doc .Rows ,PageRow {ID :group .Value .GroupID ,Text :group .Value .Workspace ,Badge :fmt .Sprintf ("%d shown" ,len (group .Value .Members )),Detail :detail ,Tone :TonePlain }) 66 } 67return doc ,nil 68}