updated mock sync group accordions: editing state; cancel editing

This commit is contained in:
2026-02-17 19:35:12 -07:00
parent 7ef4638daa
commit a3ae872e9d
5 changed files with 185 additions and 23 deletions
+31 -1
View File
@@ -501,7 +501,7 @@ func (db *Store) DeleteMockSyncGroup(ctx context.Context, acctID, syncGroupID in
return nil return nil
} }
func (db *Store) StartEditingMockSyncGroup(ctx context.Context, acctID, syncGroupID int64) (int64, bool, error) { func (db *Store) StartEditingMockSyncGroup(ctx context.Context, acctID, syncGroupID int64) (prevSyncGroupID int64, prevSyncGroupExists bool, err error) {
rows, err := db.db.Query( rows, err := db.db.Query(
ctx, ctx,
` `
@@ -561,6 +561,36 @@ func (db *Store) StartEditingMockSyncGroup(ctx context.Context, acctID, syncGrou
return v.Int64, v.Valid, nil return v.Int64, v.Valid, nil
} }
func (db *Store) CancelEditingOfMockSyncGroupForAccount(ctx context.Context, acctID int64) (prevSyncGroupID int64, prevSyncGroupExists bool, err error) {
rows, err := db.db.Query(
ctx,
`
DELETE FROM
mock.sync_group_editing
WHERE
account_id = @account_id
RETURNING
sync_group_id
`,
pgx.NamedArgs{
"account_id": acctID,
},
)
if err != nil {
return 0, false, fmt.Errorf("failed to perform query: %w", err)
}
prevSyncGroupID, err = pgx.CollectExactlyOneRow(rows, pgx.RowTo[int64])
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return 0, false, nil
}
return 0, false, fmt.Errorf("failed to scan rows: %w", err)
}
return prevSyncGroupID, true, nil
}
func (db *Store) MockSyncGroupIsBeingEdited(ctx context.Context, acctID, syncGroupID int64) (bool, error) { func (db *Store) MockSyncGroupIsBeingEdited(ctx context.Context, acctID, syncGroupID int64) (bool, error) {
rows, err := db.db.Query( rows, err := db.db.Query(
ctx, ctx,
+24 -1
View File
@@ -59,6 +59,7 @@ func Routes(
mockSyncGroups.POST("", pub.Publish("/:acctID/inventory/sync-groups/mock"), response.Handler(as.saveNewMockSyncGroup)) mockSyncGroups.POST("", pub.Publish("/:acctID/inventory/sync-groups/mock"), response.Handler(as.saveNewMockSyncGroup))
mockSyncGroups.DELETE("/:syncGroupID", pub.Publish("/:acctID/inventory/sync-groups/mock"), response.Handler(as.deleteMockSyncGroup)) mockSyncGroups.DELETE("/:syncGroupID", pub.Publish("/:acctID/inventory/sync-groups/mock"), response.Handler(as.deleteMockSyncGroup))
mockSyncGroups.PUT("/editing", pub.Publish("/:acctID/inventory/sync-groups/mock/editing"), response.Handler(as.selectMockSyncGroupForEditing)) mockSyncGroups.PUT("/editing", pub.Publish("/:acctID/inventory/sync-groups/mock/editing"), response.Handler(as.selectMockSyncGroupForEditing))
mockSyncGroups.DELETE("/editing", pub.Publish("/:acctID/inventory/sync-groups/mock/editing"), response.Handler(as.cancelMockSyncGroupEdits))
mockDraftListings := mockSyncGroups.Group("/draft/listings", pub.Publish("/:acctID/inventory/sync-groups/mock/draft/listings")) mockDraftListings := mockSyncGroups.Group("/draft/listings", pub.Publish("/:acctID/inventory/sync-groups/mock/draft/listings"))
mockDraftListings.POST("", response.Handler(as.createMockSyncGroupListingDraft)) mockDraftListings.POST("", response.Handler(as.createMockSyncGroupListingDraft))
@@ -552,7 +553,7 @@ func (s *accountSubrouter) selectMockSyncGroupForEditing(c *gin.Context) (respon
prevSyncGroupID, ok, err := s.accts.StartEditingMockSyncGroup(ctx, acctID, syncGroupID) prevSyncGroupID, ok, err := s.accts.StartEditingMockSyncGroup(ctx, acctID, syncGroupID)
if err != nil { if err != nil {
return nil, response.Errorf("failed to save new mock sync group: %w", response.ErrorFromConstant(err)) return nil, response.Errorf("failed to start editing mock sync group: %w", response.ErrorFromConstant(err))
} }
// emit events indicating sync groups being edited and no longer being edited // emit events indicating sync groups being edited and no longer being edited
@@ -570,6 +571,28 @@ func (s *accountSubrouter) selectMockSyncGroupForEditing(c *gin.Context) (respon
return response.StatusOK(), nil return response.StatusOK(), nil
} }
// DELETE /:acctID/inventory/sync-groups/mock/editing
func (s *accountSubrouter) cancelMockSyncGroupEdits(c *gin.Context) (response.Response, error) {
r := c.Request
ctx := r.Context()
acctID := auth.GetIdentity(ctx).Account.AccountID
prevSyncGroupID, deleted, err := s.accts.CancelEditingOfMockSyncGroupForAccount(ctx, acctID)
if err != nil {
return nil, response.Errorf("failed to stop editing mock sync group: %w", response.ErrorFromConstant(err))
}
// emit events indicating sync groups being edited and no longer being edited
if deleted {
evt := fmt.Sprintf("accounts_%d_inventory_sync-groups_mock_%d", acctID, prevSyncGroupID)
if err := s.pub.Push(c, acctID, evt); err != nil {
s.log.Errorf("failed to publish mock sync group editing events: %v", err)
}
}
return response.StatusOK(), nil
}
func lowerSnakeCase(s accounts.Platform) string { func lowerSnakeCase(s accounts.Platform) string {
return strings.ToLower(strings.Join(strings.Split(string(s), " "), "_")) return strings.ToLower(strings.Join(strings.Split(string(s), " "), "_"))
} }
+27
View File
@@ -363,9 +363,15 @@
.my-\[0\.5em\] { .my-\[0\.5em\] {
margin-block: 0.5em; margin-block: 0.5em;
} }
.my-\[1em\] {
margin-block: 1em;
}
.my-\[1rem\] { .my-\[1rem\] {
margin-block: 1rem; margin-block: 1rem;
} }
.mt-\[0\.5em\] {
margin-top: 0.5em;
}
.mt-\[0\.25em\] { .mt-\[0\.25em\] {
margin-top: 0.25em; margin-top: 0.25em;
} }
@@ -378,9 +384,18 @@
.mt-\[3em\] { .mt-\[3em\] {
margin-top: 3em; margin-top: 3em;
} }
.mb-\[-0\.5em\] {
margin-bottom: -0.5em;
}
.mb-\[-1em\] {
margin-bottom: -1em;
}
.mb-\[0\.5em\] { .mb-\[0\.5em\] {
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
.mb-\[0\] {
margin-bottom: 0;
}
.mb-\[1\.25rem\] { .mb-\[1\.25rem\] {
margin-bottom: 1.25rem; margin-bottom: 1.25rem;
} }
@@ -459,6 +474,9 @@
.flex-grow { .flex-grow {
flex-grow: 1; flex-grow: 1;
} }
.flex-grow-\[1\] {
flex-grow: 1;
}
.grow { .grow {
flex-grow: 1; flex-grow: 1;
} }
@@ -589,12 +607,21 @@
.bg-accent { .bg-accent {
background-color: var(--accent); background-color: var(--accent);
} }
.bg-accent-secondary {
background-color: var(--accent-secondary);
}
.bg-background { .bg-background {
background-color: var(--background); background-color: var(--background);
} }
.bg-card { .bg-card {
background-color: var(--card); background-color: var(--card);
} }
.bg-foreground {
background-color: var(--foreground);
}
.bg-primary {
background-color: var(--primary);
}
.p-\[0\.5em\] { .p-\[0\.5em\] {
padding: 0.5em; padding: 0.5em;
} }
@@ -2,10 +2,9 @@
{{- $syncGroupID := .PathParams.syncGroupID }} {{- $syncGroupID := .PathParams.syncGroupID }}
{{- $acctID := .PathParams.acctID }} {{- $acctID := .PathParams.acctID }}
{{- $open := false }} {{- $isBeingEditing := .Accounts.MockSyncGroupIsBeingEdited $acctID $syncGroupID }}
{{- if .Request }}
{{- $open = eq (.Request.URL.Query.Get "open") "true" }} {{- $open := or $isBeingEditing (and .Request (eq (.Request.URL.Query.Get "open") "true")) }}
{{- end }}
{{- $grp := .SyncGroup }} {{- $grp := .SyncGroup }}
{{- if not $grp }} {{- if not $grp }}
@@ -29,10 +28,21 @@
</h3> </h3>
{{- end }} {{- end }}
{{- define "sync-group-accordion-body" }} {{- define "sync-group-accordion-editing-header" }}
<div class="flex flex-col items-center">
<h3 class="text-center">
{{ .Group.Name }}
</h3>
<h5>
Editing
</h5>
</div>
{{- end }}
{{- define "sync-group-accordion-static-body" }}
{{- $acctID := .Identity.Account.AccountID }} {{- $acctID := .Identity.Account.AccountID }}
{{- $syncGroupID := .Group.SyncGroupID }} {{- $syncGroupID := .Group.SyncGroupID }}
<table> <table id="sync-group-data-{{$syncGroupID}}">
<thead> <thead>
<tr> <tr>
<th> <th>
@@ -71,34 +81,107 @@
</tbody> </tbody>
</table> </table>
<div> <div
{{- $isBeingEditing := .Accounts.MockSyncGroupIsBeingEdited $acctID $syncGroupID }} id="sync-group-{{$syncGroupID}}-buttons"
{{- if not $isBeingEditing }} class="flex justify-center flex-grow-[1] gap-[0.5em]"
{{- component "button" >
"Class" "mt-[1em]" {{- component "button"
"Text" "Edit Group" "Class" "mt-[1em]"
"HXPut" (printf "/api/accounts/%d/inventory/sync-groups/mock/editing" $acctID) "Text" "Edit"
"HXVals" (printf `js:{"syncGroupID":%d}` $syncGroupID) "HXPut" (printf "/api/accounts/%d/inventory/sync-groups/mock/editing" $acctID)
"HXSwap" "none" "HXVals" (printf `js:{"syncGroupID":%d}` $syncGroupID)
}} "HXSwap" "none"
{{- end }} }}
{{- component "button" {{- component "button"
"Class" "mt-[1em]" "Class" "mt-[1em]"
"Text" "Delete Group" "Text" "Delete"
"HXDelete" (printf "/api/accounts/%d/inventory/sync-groups/mock/%d" $acctID $syncGroupID) "HXDelete" (printf "/api/accounts/%d/inventory/sync-groups/mock/%d" $acctID $syncGroupID)
"HXSwap" "none" "HXSwap" "none"
}} }}
</div> </div>
{{- end }} {{- end }}
{{- define "sync-group-accordion-form-body" }}
{{- $acctID := .Identity.Account.AccountID }}
{{- $syncGroupID := .Group.SyncGroupID }}
<form>
<table id="sync-group-{{$syncGroupID}}-form">
<thead>
<tr>
<th>
Name
</th>
<th>
SKU
</th>
<th>
Description
</th>
<th>
Count
</th>
</tr>
</thead>
<tbody>
{{- $dot := . }}
{{- range $listing := .Group.Listings }}
<tr>
{{- $val := $dot.Accounts.GetMockListing $acctID $listing.Platform $listing.ShopID $listing.ListingID }}
<td>
{{ $val.Name }}
</td>
<td>
{{ $val.SKU }}
</td>
<td>
{{ $val.Description }}
</td>
<td>
{{ $val.Count }}
</td>
</tr>
{{- end }}
</tbody>
</table>
<div
id="sync-group-{{$syncGroupID}}-editing-buttons"
class="flex justify-center flex-grow-[1] gap-[0.5em]"
>
{{/* TODO: implement saving */}}
{{- component "button"
"Class" "mt-[1em]"
"Text" "Save"
"HXSwap" "none"
}}
{{- component "button"
"Class" "mt-[1em]"
"Text" "Cancel"
"HXDelete" (printf "/api/accounts/%d/inventory/sync-groups/mock/editing" $acctID)
"HXSwap" "none"
}}
</div>
</form>
{{- end }}
{{- $accordionHeader := "sync-group-accordion-header" }}
{{- $accordionBody := "sync-group-accordion-static-body" }}
{{- $summaryClass := "" }}
{{- if $isBeingEditing }}
{{- $accordionBody = "sync-group-accordion-form-body" }}
{{- $accordionHeader = "sync-group-accordion-editing-header" }}
{{- $summaryClass = "bg-accent-secondary" }}
{{- end }}
{{ component "accordion" {{ component "accordion"
"Name" "sync-group-page" "Name" "sync-group-page"
"Open" $open "Open" $open
"GroupName" "sync-group" "GroupName" "sync-group"
"Group" $grp "Group" $grp
"Smooth" false "Smooth" false
"#accordion-header" "sync-group-accordion-header" "SummaryClass" $summaryClass
"#accordion-body" "sync-group-accordion-body" "#accordion-header" $accordionHeader
"#accordion-body" $accordionBody
}} }}
</li> </li>
@@ -47,7 +47,6 @@
> >
{{ component "accordion" {{ component "accordion"
"Name" "sync-group-page" "Name" "sync-group-page"
"Open" true
"Class" ` "Class" `
mx-[1em] mx-[1em]
mb-[1em] mb-[1em]