Containing Group/Sub-Group relationships (#5105)

* Add UI support for setting containing groups
* Show containing groups in group details panel
* Move tag hierarchical filter code into separate type
* Add depth to scene_count and add sub_group_count
* Add sub-groups tab to groups page
* Add containing groups to edit groups dialog
* Show containing group description in sub-group view
* Show group scene number in group scenes view
* Add ability to drag move grid cards
* Add sub group order option
* Add reorder sub-groups interface
* Separate page size selector component
* Add interfaces to add and remove sub-groups to a group
* Separate MultiSet components
* Allow setting description while setting containing groups
This commit is contained in:
WithoutPants
2024-08-30 11:43:44 +10:00
committed by GitHub
parent 96fdd94a01
commit bcf0fda7ac
99 changed files with 5388 additions and 935 deletions

View File

@@ -2,6 +2,8 @@ package models
import (
"context"
"github.com/stashapp/stash/pkg/sliceutil"
)
type SceneIDLoader interface {
@@ -37,6 +39,14 @@ type SceneGroupLoader interface {
GetGroups(ctx context.Context, id int) ([]GroupsScenes, error)
}
type ContainingGroupLoader interface {
GetContainingGroupDescriptions(ctx context.Context, id int) ([]GroupIDDescription, error)
}
type SubGroupLoader interface {
GetSubGroupDescriptions(ctx context.Context, id int) ([]GroupIDDescription, error)
}
type StashIDLoader interface {
GetStashIDs(ctx context.Context, relatedID int) ([]StashID, error)
}
@@ -185,6 +195,82 @@ func (r *RelatedGroups) load(fn func() ([]GroupsScenes, error)) error {
return nil
}
type RelatedGroupDescriptions struct {
list []GroupIDDescription
}
// NewRelatedGroups returns a loaded RelateGroups object with the provided groups.
// Loaded will return true when called on the returned object if the provided slice is not nil.
func NewRelatedGroupDescriptions(list []GroupIDDescription) RelatedGroupDescriptions {
return RelatedGroupDescriptions{
list: list,
}
}
// Loaded returns true if the relationship has been loaded.
func (r RelatedGroupDescriptions) Loaded() bool {
return r.list != nil
}
func (r RelatedGroupDescriptions) mustLoaded() {
if !r.Loaded() {
panic("list has not been loaded")
}
}
// List returns the related Groups. Panics if the relationship has not been loaded.
func (r RelatedGroupDescriptions) List() []GroupIDDescription {
r.mustLoaded()
return r.list
}
// List returns the related Groups. Panics if the relationship has not been loaded.
func (r RelatedGroupDescriptions) IDs() []int {
r.mustLoaded()
return sliceutil.Map(r.list, func(d GroupIDDescription) int { return d.GroupID })
}
// Add adds the provided ids to the list. Panics if the relationship has not been loaded.
func (r *RelatedGroupDescriptions) Add(groups ...GroupIDDescription) {
r.mustLoaded()
r.list = append(r.list, groups...)
}
// ForID returns the GroupsScenes object for the given group ID. Returns nil if not found.
func (r *RelatedGroupDescriptions) ForID(id int) *GroupIDDescription {
r.mustLoaded()
for _, v := range r.list {
if v.GroupID == id {
return &v
}
}
return nil
}
func (r *RelatedGroupDescriptions) load(fn func() ([]GroupIDDescription, error)) error {
if r.Loaded() {
return nil
}
ids, err := fn()
if err != nil {
return err
}
if ids == nil {
ids = []GroupIDDescription{}
}
r.list = ids
return nil
}
type RelatedStashIDs struct {
list []StashID
}