| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- package cmd
- import (
- "context"
- "encoding/json"
- "fmt"
- "os"
- "gogs.dmsc.dev/arp/arp_cli/client"
- "gogs.dmsc.dev/arp/arp_cli/config"
- "github.com/AlecAivazis/survey/v2"
- "github.com/olekukonko/tablewriter"
- "github.com/urfave/cli/v3"
- )
- // NoteCommand returns the note command
- func NoteCommand() *cli.Command {
- return &cli.Command{
- Name: "note",
- Usage: "Manage notes",
- Description: `Manage ARP notes. Notes are text entries belonging to users and associated with services.
- Use this command to create, list, update, and delete notes.`,
- Commands: []*cli.Command{
- {
- Name: "list",
- Aliases: []string{"ls"},
- Usage: "List all notes",
- Flags: []cli.Flag{
- &cli.BoolFlag{
- Name: "json",
- Aliases: []string{"j"},
- Usage: "Output as JSON",
- },
- },
- Action: noteList,
- },
- {
- Name: "get",
- Usage: "Get a note by ID",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "id",
- Aliases: []string{"i"},
- Usage: "Note ID",
- Required: true,
- },
- &cli.BoolFlag{
- Name: "json",
- Aliases: []string{"j"},
- Usage: "Output as JSON",
- },
- },
- Action: noteGet,
- },
- {
- Name: "create",
- Usage: "Create a new note",
- Action: noteCreate,
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "title",
- Aliases: []string{"t"},
- Usage: "Note title",
- },
- &cli.StringFlag{
- Name: "content",
- Aliases: []string{"c"},
- Usage: "Note content",
- },
- &cli.StringFlag{
- Name: "user",
- Aliases: []string{"u"},
- Usage: "User ID",
- },
- &cli.StringFlag{
- Name: "service",
- Aliases: []string{"s"},
- Usage: "Service ID",
- },
- },
- },
- {
- Name: "update",
- Usage: "Update a note",
- Action: noteUpdate,
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "id",
- Aliases: []string{"i"},
- Usage: "Note ID",
- Required: true,
- },
- &cli.StringFlag{
- Name: "title",
- Aliases: []string{"t"},
- Usage: "Note title",
- },
- &cli.StringFlag{
- Name: "content",
- Aliases: []string{"c"},
- Usage: "Note content",
- },
- &cli.StringFlag{
- Name: "user",
- Aliases: []string{"u"},
- Usage: "User ID",
- },
- &cli.StringFlag{
- Name: "service",
- Aliases: []string{"s"},
- Usage: "Service ID",
- },
- },
- },
- {
- Name: "delete",
- Usage: "Delete a note",
- Action: noteDelete,
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "id",
- Aliases: []string{"i"},
- Usage: "Note ID",
- Required: true,
- },
- &cli.BoolFlag{
- Name: "yes",
- Aliases: []string{"y"},
- Usage: "Skip confirmation",
- },
- },
- },
- },
- }
- }
- type Note struct {
- ID string `json:"id"`
- Title string `json:"title"`
- Content string `json:"content"`
- UserID string `json:"userId"`
- User *User `json:"user"`
- ServiceID string `json:"serviceId"`
- Service *Service `json:"service"`
- CreatedAt string `json:"createdAt"`
- UpdatedAt string `json:"updatedAt"`
- }
- func noteList(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- query := "query Notes { notes { id title content userId user { id email } serviceId createdAt updatedAt } }"
- resp, err := c.Query(query, nil)
- if err != nil {
- return err
- }
- var result struct {
- Notes []Note `json:"notes"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if cmd.Bool("json") {
- enc := json.NewEncoder(os.Stdout)
- enc.SetIndent("", " ")
- return enc.Encode(result.Notes)
- }
- if len(result.Notes) == 0 {
- fmt.Println("No notes found.")
- return nil
- }
- table := tablewriter.NewWriter(os.Stdout)
- table.Header([]string{"ID", "Title", "User", "Service ID", "Created At"})
-
- for _, n := range result.Notes {
- userEmail := ""
- if n.User != nil {
- userEmail = n.User.Email
- }
- table.Append([]string{n.ID, n.Title, userEmail, n.ServiceID, n.CreatedAt})
- }
- table.Render()
- return nil
- }
- func noteGet(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- id := cmd.String("id")
- query := "query Note($id: ID!) { note(id: $id) { id title content userId user { id email } serviceId service { id name } createdAt updatedAt } }"
- resp, err := c.Query(query, map[string]interface{}{"id": id})
- if err != nil {
- return err
- }
- var result struct {
- Note *Note `json:"note"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if result.Note == nil {
- return fmt.Errorf("note not found")
- }
- if cmd.Bool("json") {
- enc := json.NewEncoder(os.Stdout)
- enc.SetIndent("", " ")
- return enc.Encode(result.Note)
- }
- n := result.Note
- fmt.Printf("ID: %s\n", n.ID)
- fmt.Printf("Title: %s\n", n.Title)
- fmt.Printf("Content: %s\n", n.Content)
- if n.User != nil {
- fmt.Printf("User: %s (%s)\n", n.User.Email, n.UserID)
- } else {
- fmt.Printf("User ID: %s\n", n.UserID)
- }
- if n.Service != nil {
- fmt.Printf("Service: %s (%s)\n", n.Service.Name, n.ServiceID)
- } else {
- fmt.Printf("Service ID: %s\n", n.ServiceID)
- }
- fmt.Printf("Created At: %s\n", n.CreatedAt)
- fmt.Printf("Updated At: %s\n", n.UpdatedAt)
- return nil
- }
- func noteCreate(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- title := cmd.String("title")
- content := cmd.String("content")
- userID := cmd.String("user")
- serviceID := cmd.String("service")
- if title == "" {
- prompt := &survey.Input{Message: "Title:"}
- if err := survey.AskOne(prompt, &title, survey.WithValidator(survey.Required)); err != nil {
- return err
- }
- }
- if content == "" {
- prompt := &survey.Multiline{Message: "Content:"}
- if err := survey.AskOne(prompt, &content, survey.WithValidator(survey.Required)); err != nil {
- return err
- }
- }
- if userID == "" {
- prompt := &survey.Input{Message: "User ID:"}
- if err := survey.AskOne(prompt, &userID, survey.WithValidator(survey.Required)); err != nil {
- return err
- }
- }
- if serviceID == "" {
- prompt := &survey.Input{Message: "Service ID:"}
- if err := survey.AskOne(prompt, &serviceID, survey.WithValidator(survey.Required)); err != nil {
- return err
- }
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- mutation := `mutation CreateNote($input: NewNote!) { createNote(input: $input) { id title content userId user { id email } serviceId createdAt updatedAt } }`
- input := map[string]interface{}{
- "title": title,
- "content": content,
- "userId": userID,
- "serviceId": serviceID,
- }
- resp, err := c.Mutation(mutation, map[string]interface{}{"input": input})
- if err != nil {
- return err
- }
- var result struct {
- CreateNote *Note `json:"createNote"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if result.CreateNote == nil {
- return fmt.Errorf("failed to create note")
- }
- fmt.Printf("Note created successfully!\n")
- fmt.Printf("ID: %s\n", result.CreateNote.ID)
- fmt.Printf("Title: %s\n", result.CreateNote.Title)
- return nil
- }
- func noteUpdate(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- id := cmd.String("id")
- title := cmd.String("title")
- content := cmd.String("content")
- userID := cmd.String("user")
- serviceID := cmd.String("service")
- if title == "" && content == "" && userID == "" && serviceID == "" {
- fmt.Println("No updates provided. Use flags to specify what to update.")
- return nil
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- input := make(map[string]interface{})
- if title != "" {
- input["title"] = title
- }
- if content != "" {
- input["content"] = content
- }
- if userID != "" {
- input["userId"] = userID
- }
- if serviceID != "" {
- input["serviceId"] = serviceID
- }
- mutation := `mutation UpdateNote($id: ID!, $input: UpdateNoteInput!) { updateNote(id: $id, input: $input) { id title content userId serviceId createdAt updatedAt } }`
- resp, err := c.Mutation(mutation, map[string]interface{}{"id": id, "input": input})
- if err != nil {
- return err
- }
- var result struct {
- UpdateNote *Note `json:"updateNote"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if result.UpdateNote == nil {
- return fmt.Errorf("note not found")
- }
- fmt.Printf("Note updated successfully!\n")
- fmt.Printf("ID: %s\n", result.UpdateNote.ID)
- fmt.Printf("Title: %s\n", result.UpdateNote.Title)
- return nil
- }
- func noteDelete(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- id := cmd.String("id")
- skipConfirm := cmd.Bool("yes")
- if !skipConfirm {
- confirm := false
- prompt := &survey.Confirm{
- Message: fmt.Sprintf("Are you sure you want to delete note %s?", id),
- Default: false,
- }
- if err := survey.AskOne(prompt, &confirm); err != nil {
- return err
- }
- if !confirm {
- fmt.Println("Deletion cancelled.")
- return nil
- }
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- mutation := `mutation DeleteNote($id: ID!) { deleteNote(id: $id) }`
- resp, err := c.Mutation(mutation, map[string]interface{}{"id": id})
- if err != nil {
- return err
- }
- var result struct {
- DeleteNote bool `json:"deleteNote"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if result.DeleteNote {
- fmt.Printf("Note %s deleted successfully.\n", id)
- } else {
- fmt.Printf("Failed to delete note %s.\n", id)
- }
- return nil
- }
|