summaryrefslogtreecommitdiff
path: root/internal/commands/archive.go
diff options
context:
space:
mode:
authorT <t@tjp.lol>2025-09-29 15:04:44 -0600
committerT <t@tjp.lol>2025-09-30 11:40:45 -0600
commit7ba68d333bc20b5795ccfd3870546a05eee60470 (patch)
tree12dc4b017803b7d01844fd42b9e3be281cbbd986 /internal/commands/archive.go
parentbce8dbb58165e443902d9dae3909225ef42630c4 (diff)
Support for archiving clients and projects.HEADmain
Diffstat (limited to 'internal/commands/archive.go')
-rw-r--r--internal/commands/archive.go141
1 files changed, 141 insertions, 0 deletions
diff --git a/internal/commands/archive.go b/internal/commands/archive.go
new file mode 100644
index 0000000..d6c9977
--- /dev/null
+++ b/internal/commands/archive.go
@@ -0,0 +1,141 @@
+package commands
+
+import (
+ "errors"
+ "fmt"
+
+ "git.tjp.lol/punchcard/internal/actions"
+ punchctx "git.tjp.lol/punchcard/internal/context"
+
+ "github.com/spf13/cobra"
+)
+
+func NewArchiveCmd() *cobra.Command {
+ var clientFlag, projectFlag string
+
+ cmd := &cobra.Command{
+ Use: "archive",
+ Short: "Archive a client or project",
+ Long: `Archive a client or project to hide it from the default view.
+
+Archived clients and projects will not be shown in the "Clients & Projects" pane
+by default, but can be toggled visible. All historical time entries remain accessible.
+
+Examples:
+ punch archive --client "Acme Corp"
+ punch archive --client 1
+ punch archive --project "Website Redesign"
+ punch archive --project 5`,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ if clientFlag == "" && projectFlag == "" {
+ return errors.New("either --client or --project must be specified")
+ }
+
+ if clientFlag != "" && projectFlag != "" {
+ return errors.New("cannot specify both --client and --project")
+ }
+
+ q := punchctx.GetDB(cmd.Context())
+ if q == nil {
+ return fmt.Errorf("database not available in context")
+ }
+
+ a := actions.New(q)
+
+ if clientFlag != "" {
+ client, err := a.FindClient(cmd.Context(), clientFlag)
+ if err != nil {
+ return fmt.Errorf("failed to find client: %w", err)
+ }
+
+ if err := a.ArchiveClient(cmd.Context(), client.ID); err != nil {
+ return fmt.Errorf("failed to archive client: %w", err)
+ }
+
+ cmd.Printf("Archived client: %s\n", client.Name)
+ } else {
+ project, err := a.FindProject(cmd.Context(), projectFlag)
+ if err != nil {
+ return fmt.Errorf("failed to find project: %w", err)
+ }
+
+ if err := a.ArchiveProject(cmd.Context(), project.ID); err != nil {
+ return fmt.Errorf("failed to archive project: %w", err)
+ }
+
+ cmd.Printf("Archived project: %s\n", project.Name)
+ }
+
+ return nil
+ },
+ }
+
+ cmd.Flags().StringVarP(&clientFlag, "client", "c", "", "Client name or ID")
+ cmd.Flags().StringVarP(&projectFlag, "project", "p", "", "Project name or ID")
+
+ return cmd
+}
+
+func NewUnarchiveCmd() *cobra.Command {
+ var clientFlag, projectFlag string
+
+ cmd := &cobra.Command{
+ Use: "unarchive",
+ Short: "Unarchive a client or project",
+ Long: `Unarchive a client or project to show it in the default view again.
+
+Examples:
+ punch unarchive --client "Acme Corp"
+ punch unarchive --client 1
+ punch unarchive --project "Website Redesign"
+ punch unarchive --project 5`,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ if clientFlag == "" && projectFlag == "" {
+ return errors.New("either --client or --project must be specified")
+ }
+
+ if clientFlag != "" && projectFlag != "" {
+ return errors.New("cannot specify both --client and --project")
+ }
+
+ q := punchctx.GetDB(cmd.Context())
+ if q == nil {
+ return fmt.Errorf("database not available in context")
+ }
+
+ a := actions.New(q)
+
+ if clientFlag != "" {
+ client, err := a.FindClient(cmd.Context(), clientFlag)
+ if err != nil {
+ return fmt.Errorf("failed to find client: %w", err)
+ }
+
+ if err := a.UnarchiveClient(cmd.Context(), client.ID); err != nil {
+ return fmt.Errorf("failed to unarchive client: %w", err)
+ }
+
+ cmd.Printf("Unarchived client: %s\n", client.Name)
+ } else {
+ project, err := a.FindProject(cmd.Context(), projectFlag)
+ if err != nil {
+ return fmt.Errorf("failed to find project: %w", err)
+ }
+
+ if err := a.UnarchiveProject(cmd.Context(), project.ID); err != nil {
+ return fmt.Errorf("failed to unarchive project: %w", err)
+ }
+
+ cmd.Printf("Unarchived project: %s\n", project.Name)
+ }
+
+ return nil
+ },
+ }
+
+ cmd.Flags().StringVarP(&clientFlag, "client", "c", "", "Client name or ID")
+ cmd.Flags().StringVarP(&projectFlag, "project", "p", "", "Project name or ID")
+
+ return cmd
+}
+