Compare commits

..

1 Commits

Author SHA1 Message Date
Jiayuan
93d4094419 feat(inbox): remove redundant mark-as-done hover button, add archive button for done tasks
Remove the "mark as done" hover button from inbox list items since it
duplicates the one in the issue detail header. For done tasks, show an
archive button in the issue detail header instead.

Co-authored-by: multica-agent <github@multica.ai>
2026-05-01 08:51:56 +02:00
5 changed files with 19 additions and 87 deletions

View File

@@ -77,6 +77,13 @@ export function IssuesPage() {
const updateIssueMutation = useUpdateIssue();
const handleMoveIssue = useCallback(
(issueId: string, newStatus: IssueStatus, newPosition?: number) => {
// Auto-switch to manual sort so drag ordering is preserved
const viewState = useIssueViewStore.getState();
if (viewState.sortBy !== "position") {
viewState.setSortBy("position");
viewState.setSortDirection("asc");
}
const updates: Partial<{ status: IssueStatus; position: number }> = {
status: newStatus,
};

View File

@@ -102,6 +102,12 @@ export function MyIssuesPage() {
const updateIssueMutation = useUpdateIssue();
const handleMoveIssue = useCallback(
(issueId: string, newStatus: IssueStatus, newPosition?: number) => {
const viewState = myIssuesViewStore.getState();
if (viewState.sortBy !== "position") {
viewState.setSortBy("position");
viewState.setSortDirection("asc");
}
const updates: Partial<{ status: IssueStatus; position: number }> = {
status: newStatus,
};

View File

@@ -134,6 +134,11 @@ function ProjectIssuesContent({
const updateIssueMutation = useUpdateIssue();
const handleMoveIssue = useCallback(
(issueId: string, newStatus: IssueStatus, newPosition?: number) => {
const viewState = projectViewStore.getState();
if (viewState.sortBy !== "position") {
viewState.setSortBy("position");
viewState.setSortDirection("asc");
}
const updates: Partial<{ status: IssueStatus; position: number }> = { status: newStatus };
if (newPosition !== undefined) updates.position = newPosition;
updateIssueMutation.mutate(

View File

@@ -10,7 +10,6 @@ import (
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"
"time"
@@ -20,34 +19,8 @@ import (
// It passes the full daemon environment so credential helpers (e.g. gh) can
// locate their config, and disables TTY prompting so auth failures produce
// clear errors instead of blocking on a non-existent terminal.
//
// safe.directory=* is set via GIT_CONFIG_* env vars so git trusts all
// directories regardless of ownership. The daemon manages its own bare
// caches and worktrees, so the ownership check adds no security value
// and breaks CI environments where the runner UID differs from the
// directory owner.
func gitEnv() []string {
base := os.Environ()
// Find the existing GIT_CONFIG_COUNT so we append at the next index
// rather than overwriting any env-scoped git config (auth, URL
// rewrites, extra headers, etc.).
existing := 0
for _, e := range base {
if strings.HasPrefix(e, "GIT_CONFIG_COUNT=") {
if n, err := strconv.Atoi(strings.TrimPrefix(e, "GIT_CONFIG_COUNT=")); err == nil {
existing = n
}
}
}
idx := strconv.Itoa(existing)
return append(base,
"GIT_TERMINAL_PROMPT=0",
"GIT_CONFIG_COUNT="+strconv.Itoa(existing+1),
"GIT_CONFIG_KEY_"+idx+"=safe.directory",
"GIT_CONFIG_VALUE_"+idx+"=*",
)
return append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
}
// RepoInfo describes a repository to cache.

View File

@@ -44,65 +44,6 @@ func TestGitEnv(t *testing.T) {
if !foundHome {
t.Error("gitEnv() must include HOME from os.Environ()")
}
// Must set safe.directory=* via GIT_CONFIG env vars.
envHas := func(env []string, want string) bool {
for _, e := range env {
if e == want {
return true
}
}
return false
}
if !envHas(env, "GIT_CONFIG_KEY_0=safe.directory") {
t.Error("gitEnv() must include GIT_CONFIG_KEY_0=safe.directory (no pre-existing config)")
}
if !envHas(env, "GIT_CONFIG_VALUE_0=*") {
t.Error("gitEnv() must include GIT_CONFIG_VALUE_0=*")
}
}
func TestGitEnvPreservesExistingConfig(t *testing.T) {
// GIT_CONFIG_COUNT env vars are process-wide; cannot use t.Setenv in
// parallel tests, so run sequentially.
t.Setenv("GIT_CONFIG_COUNT", "2")
t.Setenv("GIT_CONFIG_KEY_0", "url.https://github.com/.insteadOf")
t.Setenv("GIT_CONFIG_VALUE_0", "gh:")
t.Setenv("GIT_CONFIG_KEY_1", "http.extraHeader")
t.Setenv("GIT_CONFIG_VALUE_1", "Authorization: Bearer tok")
env := gitEnv()
envHas := func(want string) bool {
for _, e := range env {
if e == want {
return true
}
}
return false
}
// safe.directory must be appended at index 2 (next available).
if !envHas("GIT_CONFIG_COUNT=3") {
t.Error("expected GIT_CONFIG_COUNT=3")
}
if !envHas("GIT_CONFIG_KEY_2=safe.directory") {
t.Error("expected GIT_CONFIG_KEY_2=safe.directory")
}
if !envHas("GIT_CONFIG_VALUE_2=*") {
t.Error("expected GIT_CONFIG_VALUE_2=*")
}
// Original entries must still be present.
if !envHas("GIT_CONFIG_KEY_0=url.https://github.com/.insteadOf") {
t.Error("existing GIT_CONFIG_KEY_0 was lost")
}
if !envHas("GIT_CONFIG_VALUE_0=gh:") {
t.Error("existing GIT_CONFIG_VALUE_0 was lost")
}
if !envHas("GIT_CONFIG_KEY_1=http.extraHeader") {
t.Error("existing GIT_CONFIG_KEY_1 was lost")
}
}
func TestBareDirName(t *testing.T) {