updated mock sync group accordions: editing state; cancel editing
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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), " "), "_"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+103
-20
@@ -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]
|
||||||
|
|||||||
Reference in New Issue
Block a user