mirror of
https://github.com/hay-kot/homebox.git
synced 2024-11-16 21:58:40 +00:00
feat: add archive item options (#122)
Add archive option feature. Archived items can only be seen on the items page when including archived is selected. Archived items are excluded from the count and from other views
This commit is contained in:
parent
c722495fdd
commit
a886fa86ca
27 changed files with 325 additions and 38 deletions
|
@ -47,15 +47,24 @@ func (ctrl *V1Controller) HandleItemsGetAll() server.HandlerFunc {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBool := func(s string) bool {
|
||||||
|
b, err := strconv.ParseBool(s)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
extractQuery := func(r *http.Request) repo.ItemQuery {
|
extractQuery := func(r *http.Request) repo.ItemQuery {
|
||||||
params := r.URL.Query()
|
params := r.URL.Query()
|
||||||
|
|
||||||
return repo.ItemQuery{
|
return repo.ItemQuery{
|
||||||
Page: intOrNegativeOne(params.Get("page")),
|
Page: intOrNegativeOne(params.Get("page")),
|
||||||
PageSize: intOrNegativeOne(params.Get("perPage")),
|
PageSize: intOrNegativeOne(params.Get("perPage")),
|
||||||
Search: params.Get("q"),
|
Search: params.Get("q"),
|
||||||
LocationIDs: uuidList(params, "locations"),
|
LocationIDs: uuidList(params, "locations"),
|
||||||
LabelIDs: uuidList(params, "labels"),
|
LabelIDs: uuidList(params, "labels"),
|
||||||
|
IncludeArchived: getBool(params.Get("includeArchived")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1274,6 +1274,9 @@ const docTemplate = `{
|
||||||
"repo.ItemOut": {
|
"repo.ItemOut": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"archived": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"attachments": {
|
"attachments": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
@ -1383,6 +1386,9 @@ const docTemplate = `{
|
||||||
"repo.ItemSummary": {
|
"repo.ItemSummary": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"archived": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -1421,6 +1427,9 @@ const docTemplate = `{
|
||||||
"repo.ItemUpdate": {
|
"repo.ItemUpdate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"archived": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1266,6 +1266,9 @@
|
||||||
"repo.ItemOut": {
|
"repo.ItemOut": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"archived": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"attachments": {
|
"attachments": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
@ -1375,6 +1378,9 @@
|
||||||
"repo.ItemSummary": {
|
"repo.ItemSummary": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"archived": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -1413,6 +1419,9 @@
|
||||||
"repo.ItemUpdate": {
|
"repo.ItemUpdate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"archived": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
|
@ -85,6 +85,8 @@ definitions:
|
||||||
type: object
|
type: object
|
||||||
repo.ItemOut:
|
repo.ItemOut:
|
||||||
properties:
|
properties:
|
||||||
|
archived:
|
||||||
|
type: boolean
|
||||||
attachments:
|
attachments:
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/repo.ItemAttachment'
|
$ref: '#/definitions/repo.ItemAttachment'
|
||||||
|
@ -161,6 +163,8 @@ definitions:
|
||||||
type: object
|
type: object
|
||||||
repo.ItemSummary:
|
repo.ItemSummary:
|
||||||
properties:
|
properties:
|
||||||
|
archived:
|
||||||
|
type: boolean
|
||||||
createdAt:
|
createdAt:
|
||||||
type: string
|
type: string
|
||||||
description:
|
description:
|
||||||
|
@ -187,6 +191,8 @@ definitions:
|
||||||
type: object
|
type: object
|
||||||
repo.ItemUpdate:
|
repo.ItemUpdate:
|
||||||
properties:
|
properties:
|
||||||
|
archived:
|
||||||
|
type: boolean
|
||||||
description:
|
description:
|
||||||
type: string
|
type: string
|
||||||
fields:
|
fields:
|
||||||
|
|
|
@ -35,6 +35,8 @@ type Item struct {
|
||||||
Quantity int `json:"quantity,omitempty"`
|
Quantity int `json:"quantity,omitempty"`
|
||||||
// Insured holds the value of the "insured" field.
|
// Insured holds the value of the "insured" field.
|
||||||
Insured bool `json:"insured,omitempty"`
|
Insured bool `json:"insured,omitempty"`
|
||||||
|
// Archived holds the value of the "archived" field.
|
||||||
|
Archived bool `json:"archived,omitempty"`
|
||||||
// SerialNumber holds the value of the "serial_number" field.
|
// SerialNumber holds the value of the "serial_number" field.
|
||||||
SerialNumber string `json:"serial_number,omitempty"`
|
SerialNumber string `json:"serial_number,omitempty"`
|
||||||
// ModelNumber holds the value of the "model_number" field.
|
// ModelNumber holds the value of the "model_number" field.
|
||||||
|
@ -170,7 +172,7 @@ func (*Item) scanValues(columns []string) ([]any, error) {
|
||||||
values := make([]any, len(columns))
|
values := make([]any, len(columns))
|
||||||
for i := range columns {
|
for i := range columns {
|
||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
case item.FieldInsured, item.FieldLifetimeWarranty:
|
case item.FieldInsured, item.FieldArchived, item.FieldLifetimeWarranty:
|
||||||
values[i] = new(sql.NullBool)
|
values[i] = new(sql.NullBool)
|
||||||
case item.FieldPurchasePrice, item.FieldSoldPrice:
|
case item.FieldPurchasePrice, item.FieldSoldPrice:
|
||||||
values[i] = new(sql.NullFloat64)
|
values[i] = new(sql.NullFloat64)
|
||||||
|
@ -257,6 +259,12 @@ func (i *Item) assignValues(columns []string, values []any) error {
|
||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
i.Insured = value.Bool
|
i.Insured = value.Bool
|
||||||
}
|
}
|
||||||
|
case item.FieldArchived:
|
||||||
|
if value, ok := values[j].(*sql.NullBool); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field archived", values[j])
|
||||||
|
} else if value.Valid {
|
||||||
|
i.Archived = value.Bool
|
||||||
|
}
|
||||||
case item.FieldSerialNumber:
|
case item.FieldSerialNumber:
|
||||||
if value, ok := values[j].(*sql.NullString); !ok {
|
if value, ok := values[j].(*sql.NullString); !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field serial_number", values[j])
|
return fmt.Errorf("unexpected type %T for field serial_number", values[j])
|
||||||
|
@ -443,6 +451,9 @@ func (i *Item) String() string {
|
||||||
builder.WriteString("insured=")
|
builder.WriteString("insured=")
|
||||||
builder.WriteString(fmt.Sprintf("%v", i.Insured))
|
builder.WriteString(fmt.Sprintf("%v", i.Insured))
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("archived=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", i.Archived))
|
||||||
|
builder.WriteString(", ")
|
||||||
builder.WriteString("serial_number=")
|
builder.WriteString("serial_number=")
|
||||||
builder.WriteString(i.SerialNumber)
|
builder.WriteString(i.SerialNumber)
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
|
|
@ -29,6 +29,8 @@ const (
|
||||||
FieldQuantity = "quantity"
|
FieldQuantity = "quantity"
|
||||||
// FieldInsured holds the string denoting the insured field in the database.
|
// FieldInsured holds the string denoting the insured field in the database.
|
||||||
FieldInsured = "insured"
|
FieldInsured = "insured"
|
||||||
|
// FieldArchived holds the string denoting the archived field in the database.
|
||||||
|
FieldArchived = "archived"
|
||||||
// FieldSerialNumber holds the string denoting the serial_number field in the database.
|
// FieldSerialNumber holds the string denoting the serial_number field in the database.
|
||||||
FieldSerialNumber = "serial_number"
|
FieldSerialNumber = "serial_number"
|
||||||
// FieldModelNumber holds the string denoting the model_number field in the database.
|
// FieldModelNumber holds the string denoting the model_number field in the database.
|
||||||
|
@ -125,6 +127,7 @@ var Columns = []string{
|
||||||
FieldNotes,
|
FieldNotes,
|
||||||
FieldQuantity,
|
FieldQuantity,
|
||||||
FieldInsured,
|
FieldInsured,
|
||||||
|
FieldArchived,
|
||||||
FieldSerialNumber,
|
FieldSerialNumber,
|
||||||
FieldModelNumber,
|
FieldModelNumber,
|
||||||
FieldManufacturer,
|
FieldManufacturer,
|
||||||
|
@ -188,6 +191,8 @@ var (
|
||||||
DefaultQuantity int
|
DefaultQuantity int
|
||||||
// DefaultInsured holds the default value on creation for the "insured" field.
|
// DefaultInsured holds the default value on creation for the "insured" field.
|
||||||
DefaultInsured bool
|
DefaultInsured bool
|
||||||
|
// DefaultArchived holds the default value on creation for the "archived" field.
|
||||||
|
DefaultArchived bool
|
||||||
// SerialNumberValidator is a validator for the "serial_number" field. It is called by the builders before save.
|
// SerialNumberValidator is a validator for the "serial_number" field. It is called by the builders before save.
|
||||||
SerialNumberValidator func(string) error
|
SerialNumberValidator func(string) error
|
||||||
// ModelNumberValidator is a validator for the "model_number" field. It is called by the builders before save.
|
// ModelNumberValidator is a validator for the "model_number" field. It is called by the builders before save.
|
||||||
|
|
|
@ -138,6 +138,13 @@ func Insured(v bool) predicate.Item {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Archived applies equality check predicate on the "archived" field. It's identical to ArchivedEQ.
|
||||||
|
func Archived(v bool) predicate.Item {
|
||||||
|
return predicate.Item(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.EQ(s.C(FieldArchived), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// SerialNumber applies equality check predicate on the "serial_number" field. It's identical to SerialNumberEQ.
|
// SerialNumber applies equality check predicate on the "serial_number" field. It's identical to SerialNumberEQ.
|
||||||
func SerialNumber(v string) predicate.Item {
|
func SerialNumber(v string) predicate.Item {
|
||||||
return predicate.Item(func(s *sql.Selector) {
|
return predicate.Item(func(s *sql.Selector) {
|
||||||
|
@ -873,6 +880,20 @@ func InsuredNEQ(v bool) predicate.Item {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ArchivedEQ applies the EQ predicate on the "archived" field.
|
||||||
|
func ArchivedEQ(v bool) predicate.Item {
|
||||||
|
return predicate.Item(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.EQ(s.C(FieldArchived), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArchivedNEQ applies the NEQ predicate on the "archived" field.
|
||||||
|
func ArchivedNEQ(v bool) predicate.Item {
|
||||||
|
return predicate.Item(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.NEQ(s.C(FieldArchived), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// SerialNumberEQ applies the EQ predicate on the "serial_number" field.
|
// SerialNumberEQ applies the EQ predicate on the "serial_number" field.
|
||||||
func SerialNumberEQ(v string) predicate.Item {
|
func SerialNumberEQ(v string) predicate.Item {
|
||||||
return predicate.Item(func(s *sql.Selector) {
|
return predicate.Item(func(s *sql.Selector) {
|
||||||
|
|
|
@ -130,6 +130,20 @@ func (ic *ItemCreate) SetNillableInsured(b *bool) *ItemCreate {
|
||||||
return ic
|
return ic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetArchived sets the "archived" field.
|
||||||
|
func (ic *ItemCreate) SetArchived(b bool) *ItemCreate {
|
||||||
|
ic.mutation.SetArchived(b)
|
||||||
|
return ic
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableArchived sets the "archived" field if the given value is not nil.
|
||||||
|
func (ic *ItemCreate) SetNillableArchived(b *bool) *ItemCreate {
|
||||||
|
if b != nil {
|
||||||
|
ic.SetArchived(*b)
|
||||||
|
}
|
||||||
|
return ic
|
||||||
|
}
|
||||||
|
|
||||||
// SetSerialNumber sets the "serial_number" field.
|
// SetSerialNumber sets the "serial_number" field.
|
||||||
func (ic *ItemCreate) SetSerialNumber(s string) *ItemCreate {
|
func (ic *ItemCreate) SetSerialNumber(s string) *ItemCreate {
|
||||||
ic.mutation.SetSerialNumber(s)
|
ic.mutation.SetSerialNumber(s)
|
||||||
|
@ -528,6 +542,10 @@ func (ic *ItemCreate) defaults() {
|
||||||
v := item.DefaultInsured
|
v := item.DefaultInsured
|
||||||
ic.mutation.SetInsured(v)
|
ic.mutation.SetInsured(v)
|
||||||
}
|
}
|
||||||
|
if _, ok := ic.mutation.Archived(); !ok {
|
||||||
|
v := item.DefaultArchived
|
||||||
|
ic.mutation.SetArchived(v)
|
||||||
|
}
|
||||||
if _, ok := ic.mutation.LifetimeWarranty(); !ok {
|
if _, ok := ic.mutation.LifetimeWarranty(); !ok {
|
||||||
v := item.DefaultLifetimeWarranty
|
v := item.DefaultLifetimeWarranty
|
||||||
ic.mutation.SetLifetimeWarranty(v)
|
ic.mutation.SetLifetimeWarranty(v)
|
||||||
|
@ -583,6 +601,9 @@ func (ic *ItemCreate) check() error {
|
||||||
if _, ok := ic.mutation.Insured(); !ok {
|
if _, ok := ic.mutation.Insured(); !ok {
|
||||||
return &ValidationError{Name: "insured", err: errors.New(`ent: missing required field "Item.insured"`)}
|
return &ValidationError{Name: "insured", err: errors.New(`ent: missing required field "Item.insured"`)}
|
||||||
}
|
}
|
||||||
|
if _, ok := ic.mutation.Archived(); !ok {
|
||||||
|
return &ValidationError{Name: "archived", err: errors.New(`ent: missing required field "Item.archived"`)}
|
||||||
|
}
|
||||||
if v, ok := ic.mutation.SerialNumber(); ok {
|
if v, ok := ic.mutation.SerialNumber(); ok {
|
||||||
if err := item.SerialNumberValidator(v); err != nil {
|
if err := item.SerialNumberValidator(v); err != nil {
|
||||||
return &ValidationError{Name: "serial_number", err: fmt.Errorf(`ent: validator failed for field "Item.serial_number": %w`, err)}
|
return &ValidationError{Name: "serial_number", err: fmt.Errorf(`ent: validator failed for field "Item.serial_number": %w`, err)}
|
||||||
|
@ -720,6 +741,14 @@ func (ic *ItemCreate) createSpec() (*Item, *sqlgraph.CreateSpec) {
|
||||||
})
|
})
|
||||||
_node.Insured = value
|
_node.Insured = value
|
||||||
}
|
}
|
||||||
|
if value, ok := ic.mutation.Archived(); ok {
|
||||||
|
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||||
|
Type: field.TypeBool,
|
||||||
|
Value: value,
|
||||||
|
Column: item.FieldArchived,
|
||||||
|
})
|
||||||
|
_node.Archived = value
|
||||||
|
}
|
||||||
if value, ok := ic.mutation.SerialNumber(); ok {
|
if value, ok := ic.mutation.SerialNumber(); ok {
|
||||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||||
Type: field.TypeString,
|
Type: field.TypeString,
|
||||||
|
|
|
@ -121,6 +121,20 @@ func (iu *ItemUpdate) SetNillableInsured(b *bool) *ItemUpdate {
|
||||||
return iu
|
return iu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetArchived sets the "archived" field.
|
||||||
|
func (iu *ItemUpdate) SetArchived(b bool) *ItemUpdate {
|
||||||
|
iu.mutation.SetArchived(b)
|
||||||
|
return iu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableArchived sets the "archived" field if the given value is not nil.
|
||||||
|
func (iu *ItemUpdate) SetNillableArchived(b *bool) *ItemUpdate {
|
||||||
|
if b != nil {
|
||||||
|
iu.SetArchived(*b)
|
||||||
|
}
|
||||||
|
return iu
|
||||||
|
}
|
||||||
|
|
||||||
// SetSerialNumber sets the "serial_number" field.
|
// SetSerialNumber sets the "serial_number" field.
|
||||||
func (iu *ItemUpdate) SetSerialNumber(s string) *ItemUpdate {
|
func (iu *ItemUpdate) SetSerialNumber(s string) *ItemUpdate {
|
||||||
iu.mutation.SetSerialNumber(s)
|
iu.mutation.SetSerialNumber(s)
|
||||||
|
@ -795,6 +809,13 @@ func (iu *ItemUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
Column: item.FieldInsured,
|
Column: item.FieldInsured,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if value, ok := iu.mutation.Archived(); ok {
|
||||||
|
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||||
|
Type: field.TypeBool,
|
||||||
|
Value: value,
|
||||||
|
Column: item.FieldArchived,
|
||||||
|
})
|
||||||
|
}
|
||||||
if value, ok := iu.mutation.SerialNumber(); ok {
|
if value, ok := iu.mutation.SerialNumber(); ok {
|
||||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||||
Type: field.TypeString,
|
Type: field.TypeString,
|
||||||
|
@ -1387,6 +1408,20 @@ func (iuo *ItemUpdateOne) SetNillableInsured(b *bool) *ItemUpdateOne {
|
||||||
return iuo
|
return iuo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetArchived sets the "archived" field.
|
||||||
|
func (iuo *ItemUpdateOne) SetArchived(b bool) *ItemUpdateOne {
|
||||||
|
iuo.mutation.SetArchived(b)
|
||||||
|
return iuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableArchived sets the "archived" field if the given value is not nil.
|
||||||
|
func (iuo *ItemUpdateOne) SetNillableArchived(b *bool) *ItemUpdateOne {
|
||||||
|
if b != nil {
|
||||||
|
iuo.SetArchived(*b)
|
||||||
|
}
|
||||||
|
return iuo
|
||||||
|
}
|
||||||
|
|
||||||
// SetSerialNumber sets the "serial_number" field.
|
// SetSerialNumber sets the "serial_number" field.
|
||||||
func (iuo *ItemUpdateOne) SetSerialNumber(s string) *ItemUpdateOne {
|
func (iuo *ItemUpdateOne) SetSerialNumber(s string) *ItemUpdateOne {
|
||||||
iuo.mutation.SetSerialNumber(s)
|
iuo.mutation.SetSerialNumber(s)
|
||||||
|
@ -2091,6 +2126,13 @@ func (iuo *ItemUpdateOne) sqlSave(ctx context.Context) (_node *Item, err error)
|
||||||
Column: item.FieldInsured,
|
Column: item.FieldInsured,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if value, ok := iuo.mutation.Archived(); ok {
|
||||||
|
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||||
|
Type: field.TypeBool,
|
||||||
|
Value: value,
|
||||||
|
Column: item.FieldArchived,
|
||||||
|
})
|
||||||
|
}
|
||||||
if value, ok := iuo.mutation.SerialNumber(); ok {
|
if value, ok := iuo.mutation.SerialNumber(); ok {
|
||||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||||
Type: field.TypeString,
|
Type: field.TypeString,
|
||||||
|
|
|
@ -170,6 +170,7 @@ var (
|
||||||
{Name: "notes", Type: field.TypeString, Nullable: true, Size: 1000},
|
{Name: "notes", Type: field.TypeString, Nullable: true, Size: 1000},
|
||||||
{Name: "quantity", Type: field.TypeInt, Default: 1},
|
{Name: "quantity", Type: field.TypeInt, Default: 1},
|
||||||
{Name: "insured", Type: field.TypeBool, Default: false},
|
{Name: "insured", Type: field.TypeBool, Default: false},
|
||||||
|
{Name: "archived", Type: field.TypeBool, Default: false},
|
||||||
{Name: "serial_number", Type: field.TypeString, Nullable: true, Size: 255},
|
{Name: "serial_number", Type: field.TypeString, Nullable: true, Size: 255},
|
||||||
{Name: "model_number", Type: field.TypeString, Nullable: true, Size: 255},
|
{Name: "model_number", Type: field.TypeString, Nullable: true, Size: 255},
|
||||||
{Name: "manufacturer", Type: field.TypeString, Nullable: true, Size: 255},
|
{Name: "manufacturer", Type: field.TypeString, Nullable: true, Size: 255},
|
||||||
|
@ -195,19 +196,19 @@ var (
|
||||||
ForeignKeys: []*schema.ForeignKey{
|
ForeignKeys: []*schema.ForeignKey{
|
||||||
{
|
{
|
||||||
Symbol: "items_groups_items",
|
Symbol: "items_groups_items",
|
||||||
Columns: []*schema.Column{ItemsColumns[22]},
|
Columns: []*schema.Column{ItemsColumns[23]},
|
||||||
RefColumns: []*schema.Column{GroupsColumns[0]},
|
RefColumns: []*schema.Column{GroupsColumns[0]},
|
||||||
OnDelete: schema.Cascade,
|
OnDelete: schema.Cascade,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Symbol: "items_items_children",
|
Symbol: "items_items_children",
|
||||||
Columns: []*schema.Column{ItemsColumns[23]},
|
Columns: []*schema.Column{ItemsColumns[24]},
|
||||||
RefColumns: []*schema.Column{ItemsColumns[0]},
|
RefColumns: []*schema.Column{ItemsColumns[0]},
|
||||||
OnDelete: schema.SetNull,
|
OnDelete: schema.SetNull,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Symbol: "items_locations_items",
|
Symbol: "items_locations_items",
|
||||||
Columns: []*schema.Column{ItemsColumns[24]},
|
Columns: []*schema.Column{ItemsColumns[25]},
|
||||||
RefColumns: []*schema.Column{LocationsColumns[0]},
|
RefColumns: []*schema.Column{LocationsColumns[0]},
|
||||||
OnDelete: schema.Cascade,
|
OnDelete: schema.Cascade,
|
||||||
},
|
},
|
||||||
|
@ -221,16 +222,21 @@ var (
|
||||||
{
|
{
|
||||||
Name: "item_manufacturer",
|
Name: "item_manufacturer",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{ItemsColumns[11]},
|
Columns: []*schema.Column{ItemsColumns[12]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "item_model_number",
|
Name: "item_model_number",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{ItemsColumns[10]},
|
Columns: []*schema.Column{ItemsColumns[11]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "item_serial_number",
|
Name: "item_serial_number",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
|
Columns: []*schema.Column{ItemsColumns[10]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "item_archived",
|
||||||
|
Unique: false,
|
||||||
Columns: []*schema.Column{ItemsColumns[9]},
|
Columns: []*schema.Column{ItemsColumns[9]},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -4133,6 +4133,7 @@ type ItemMutation struct {
|
||||||
quantity *int
|
quantity *int
|
||||||
addquantity *int
|
addquantity *int
|
||||||
insured *bool
|
insured *bool
|
||||||
|
archived *bool
|
||||||
serial_number *string
|
serial_number *string
|
||||||
model_number *string
|
model_number *string
|
||||||
manufacturer *string
|
manufacturer *string
|
||||||
|
@ -4623,6 +4624,42 @@ func (m *ItemMutation) ResetInsured() {
|
||||||
m.insured = nil
|
m.insured = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetArchived sets the "archived" field.
|
||||||
|
func (m *ItemMutation) SetArchived(b bool) {
|
||||||
|
m.archived = &b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Archived returns the value of the "archived" field in the mutation.
|
||||||
|
func (m *ItemMutation) Archived() (r bool, exists bool) {
|
||||||
|
v := m.archived
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldArchived returns the old "archived" field's value of the Item entity.
|
||||||
|
// If the Item object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *ItemMutation) OldArchived(ctx context.Context) (v bool, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldArchived is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldArchived requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldArchived: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.Archived, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetArchived resets all changes to the "archived" field.
|
||||||
|
func (m *ItemMutation) ResetArchived() {
|
||||||
|
m.archived = nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetSerialNumber sets the "serial_number" field.
|
// SetSerialNumber sets the "serial_number" field.
|
||||||
func (m *ItemMutation) SetSerialNumber(s string) {
|
func (m *ItemMutation) SetSerialNumber(s string) {
|
||||||
m.serial_number = &s
|
m.serial_number = &s
|
||||||
|
@ -5613,7 +5650,7 @@ func (m *ItemMutation) Type() string {
|
||||||
// order to get all numeric fields that were incremented/decremented, call
|
// order to get all numeric fields that were incremented/decremented, call
|
||||||
// AddedFields().
|
// AddedFields().
|
||||||
func (m *ItemMutation) Fields() []string {
|
func (m *ItemMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 21)
|
fields := make([]string, 0, 22)
|
||||||
if m.created_at != nil {
|
if m.created_at != nil {
|
||||||
fields = append(fields, item.FieldCreatedAt)
|
fields = append(fields, item.FieldCreatedAt)
|
||||||
}
|
}
|
||||||
|
@ -5638,6 +5675,9 @@ func (m *ItemMutation) Fields() []string {
|
||||||
if m.insured != nil {
|
if m.insured != nil {
|
||||||
fields = append(fields, item.FieldInsured)
|
fields = append(fields, item.FieldInsured)
|
||||||
}
|
}
|
||||||
|
if m.archived != nil {
|
||||||
|
fields = append(fields, item.FieldArchived)
|
||||||
|
}
|
||||||
if m.serial_number != nil {
|
if m.serial_number != nil {
|
||||||
fields = append(fields, item.FieldSerialNumber)
|
fields = append(fields, item.FieldSerialNumber)
|
||||||
}
|
}
|
||||||
|
@ -5701,6 +5741,8 @@ func (m *ItemMutation) Field(name string) (ent.Value, bool) {
|
||||||
return m.Quantity()
|
return m.Quantity()
|
||||||
case item.FieldInsured:
|
case item.FieldInsured:
|
||||||
return m.Insured()
|
return m.Insured()
|
||||||
|
case item.FieldArchived:
|
||||||
|
return m.Archived()
|
||||||
case item.FieldSerialNumber:
|
case item.FieldSerialNumber:
|
||||||
return m.SerialNumber()
|
return m.SerialNumber()
|
||||||
case item.FieldModelNumber:
|
case item.FieldModelNumber:
|
||||||
|
@ -5752,6 +5794,8 @@ func (m *ItemMutation) OldField(ctx context.Context, name string) (ent.Value, er
|
||||||
return m.OldQuantity(ctx)
|
return m.OldQuantity(ctx)
|
||||||
case item.FieldInsured:
|
case item.FieldInsured:
|
||||||
return m.OldInsured(ctx)
|
return m.OldInsured(ctx)
|
||||||
|
case item.FieldArchived:
|
||||||
|
return m.OldArchived(ctx)
|
||||||
case item.FieldSerialNumber:
|
case item.FieldSerialNumber:
|
||||||
return m.OldSerialNumber(ctx)
|
return m.OldSerialNumber(ctx)
|
||||||
case item.FieldModelNumber:
|
case item.FieldModelNumber:
|
||||||
|
@ -5843,6 +5887,13 @@ func (m *ItemMutation) SetField(name string, value ent.Value) error {
|
||||||
}
|
}
|
||||||
m.SetInsured(v)
|
m.SetInsured(v)
|
||||||
return nil
|
return nil
|
||||||
|
case item.FieldArchived:
|
||||||
|
v, ok := value.(bool)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetArchived(v)
|
||||||
|
return nil
|
||||||
case item.FieldSerialNumber:
|
case item.FieldSerialNumber:
|
||||||
v, ok := value.(string)
|
v, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -6127,6 +6178,9 @@ func (m *ItemMutation) ResetField(name string) error {
|
||||||
case item.FieldInsured:
|
case item.FieldInsured:
|
||||||
m.ResetInsured()
|
m.ResetInsured()
|
||||||
return nil
|
return nil
|
||||||
|
case item.FieldArchived:
|
||||||
|
m.ResetArchived()
|
||||||
|
return nil
|
||||||
case item.FieldSerialNumber:
|
case item.FieldSerialNumber:
|
||||||
m.ResetSerialNumber()
|
m.ResetSerialNumber()
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -271,36 +271,40 @@ func init() {
|
||||||
itemDescInsured := itemFields[3].Descriptor()
|
itemDescInsured := itemFields[3].Descriptor()
|
||||||
// item.DefaultInsured holds the default value on creation for the insured field.
|
// item.DefaultInsured holds the default value on creation for the insured field.
|
||||||
item.DefaultInsured = itemDescInsured.Default.(bool)
|
item.DefaultInsured = itemDescInsured.Default.(bool)
|
||||||
|
// itemDescArchived is the schema descriptor for archived field.
|
||||||
|
itemDescArchived := itemFields[4].Descriptor()
|
||||||
|
// item.DefaultArchived holds the default value on creation for the archived field.
|
||||||
|
item.DefaultArchived = itemDescArchived.Default.(bool)
|
||||||
// itemDescSerialNumber is the schema descriptor for serial_number field.
|
// itemDescSerialNumber is the schema descriptor for serial_number field.
|
||||||
itemDescSerialNumber := itemFields[4].Descriptor()
|
itemDescSerialNumber := itemFields[5].Descriptor()
|
||||||
// item.SerialNumberValidator is a validator for the "serial_number" field. It is called by the builders before save.
|
// item.SerialNumberValidator is a validator for the "serial_number" field. It is called by the builders before save.
|
||||||
item.SerialNumberValidator = itemDescSerialNumber.Validators[0].(func(string) error)
|
item.SerialNumberValidator = itemDescSerialNumber.Validators[0].(func(string) error)
|
||||||
// itemDescModelNumber is the schema descriptor for model_number field.
|
// itemDescModelNumber is the schema descriptor for model_number field.
|
||||||
itemDescModelNumber := itemFields[5].Descriptor()
|
itemDescModelNumber := itemFields[6].Descriptor()
|
||||||
// item.ModelNumberValidator is a validator for the "model_number" field. It is called by the builders before save.
|
// item.ModelNumberValidator is a validator for the "model_number" field. It is called by the builders before save.
|
||||||
item.ModelNumberValidator = itemDescModelNumber.Validators[0].(func(string) error)
|
item.ModelNumberValidator = itemDescModelNumber.Validators[0].(func(string) error)
|
||||||
// itemDescManufacturer is the schema descriptor for manufacturer field.
|
// itemDescManufacturer is the schema descriptor for manufacturer field.
|
||||||
itemDescManufacturer := itemFields[6].Descriptor()
|
itemDescManufacturer := itemFields[7].Descriptor()
|
||||||
// item.ManufacturerValidator is a validator for the "manufacturer" field. It is called by the builders before save.
|
// item.ManufacturerValidator is a validator for the "manufacturer" field. It is called by the builders before save.
|
||||||
item.ManufacturerValidator = itemDescManufacturer.Validators[0].(func(string) error)
|
item.ManufacturerValidator = itemDescManufacturer.Validators[0].(func(string) error)
|
||||||
// itemDescLifetimeWarranty is the schema descriptor for lifetime_warranty field.
|
// itemDescLifetimeWarranty is the schema descriptor for lifetime_warranty field.
|
||||||
itemDescLifetimeWarranty := itemFields[7].Descriptor()
|
itemDescLifetimeWarranty := itemFields[8].Descriptor()
|
||||||
// item.DefaultLifetimeWarranty holds the default value on creation for the lifetime_warranty field.
|
// item.DefaultLifetimeWarranty holds the default value on creation for the lifetime_warranty field.
|
||||||
item.DefaultLifetimeWarranty = itemDescLifetimeWarranty.Default.(bool)
|
item.DefaultLifetimeWarranty = itemDescLifetimeWarranty.Default.(bool)
|
||||||
// itemDescWarrantyDetails is the schema descriptor for warranty_details field.
|
// itemDescWarrantyDetails is the schema descriptor for warranty_details field.
|
||||||
itemDescWarrantyDetails := itemFields[9].Descriptor()
|
itemDescWarrantyDetails := itemFields[10].Descriptor()
|
||||||
// item.WarrantyDetailsValidator is a validator for the "warranty_details" field. It is called by the builders before save.
|
// item.WarrantyDetailsValidator is a validator for the "warranty_details" field. It is called by the builders before save.
|
||||||
item.WarrantyDetailsValidator = itemDescWarrantyDetails.Validators[0].(func(string) error)
|
item.WarrantyDetailsValidator = itemDescWarrantyDetails.Validators[0].(func(string) error)
|
||||||
// itemDescPurchasePrice is the schema descriptor for purchase_price field.
|
// itemDescPurchasePrice is the schema descriptor for purchase_price field.
|
||||||
itemDescPurchasePrice := itemFields[12].Descriptor()
|
itemDescPurchasePrice := itemFields[13].Descriptor()
|
||||||
// item.DefaultPurchasePrice holds the default value on creation for the purchase_price field.
|
// item.DefaultPurchasePrice holds the default value on creation for the purchase_price field.
|
||||||
item.DefaultPurchasePrice = itemDescPurchasePrice.Default.(float64)
|
item.DefaultPurchasePrice = itemDescPurchasePrice.Default.(float64)
|
||||||
// itemDescSoldPrice is the schema descriptor for sold_price field.
|
// itemDescSoldPrice is the schema descriptor for sold_price field.
|
||||||
itemDescSoldPrice := itemFields[15].Descriptor()
|
itemDescSoldPrice := itemFields[16].Descriptor()
|
||||||
// item.DefaultSoldPrice holds the default value on creation for the sold_price field.
|
// item.DefaultSoldPrice holds the default value on creation for the sold_price field.
|
||||||
item.DefaultSoldPrice = itemDescSoldPrice.Default.(float64)
|
item.DefaultSoldPrice = itemDescSoldPrice.Default.(float64)
|
||||||
// itemDescSoldNotes is the schema descriptor for sold_notes field.
|
// itemDescSoldNotes is the schema descriptor for sold_notes field.
|
||||||
itemDescSoldNotes := itemFields[16].Descriptor()
|
itemDescSoldNotes := itemFields[17].Descriptor()
|
||||||
// item.SoldNotesValidator is a validator for the "sold_notes" field. It is called by the builders before save.
|
// item.SoldNotesValidator is a validator for the "sold_notes" field. It is called by the builders before save.
|
||||||
item.SoldNotesValidator = itemDescSoldNotes.Validators[0].(func(string) error)
|
item.SoldNotesValidator = itemDescSoldNotes.Validators[0].(func(string) error)
|
||||||
// itemDescID is the schema descriptor for id field.
|
// itemDescID is the schema descriptor for id field.
|
||||||
|
|
|
@ -28,6 +28,7 @@ func (Item) Indexes() []ent.Index {
|
||||||
index.Fields("manufacturer"),
|
index.Fields("manufacturer"),
|
||||||
index.Fields("model_number"),
|
index.Fields("model_number"),
|
||||||
index.Fields("serial_number"),
|
index.Fields("serial_number"),
|
||||||
|
index.Fields("archived"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +46,8 @@ func (Item) Fields() []ent.Field {
|
||||||
Default(1),
|
Default(1),
|
||||||
field.Bool("insured").
|
field.Bool("insured").
|
||||||
Default(false),
|
Default(false),
|
||||||
|
field.Bool("archived").
|
||||||
|
Default(false),
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// item identification
|
// item identification
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
-- disable the enforcement of foreign-keys constraints
|
||||||
|
PRAGMA foreign_keys = off;
|
||||||
|
-- create "new_items" table
|
||||||
|
CREATE TABLE `new_items` (`id` uuid NOT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, `name` text NOT NULL, `description` text NULL, `import_ref` text NULL, `notes` text NULL, `quantity` integer NOT NULL DEFAULT 1, `insured` bool NOT NULL DEFAULT false, `archived` bool NOT NULL DEFAULT false, `serial_number` text NULL, `model_number` text NULL, `manufacturer` text NULL, `lifetime_warranty` bool NOT NULL DEFAULT false, `warranty_expires` datetime NULL, `warranty_details` text NULL, `purchase_time` datetime NULL, `purchase_from` text NULL, `purchase_price` real NOT NULL DEFAULT 0, `sold_time` datetime NULL, `sold_to` text NULL, `sold_price` real NOT NULL DEFAULT 0, `sold_notes` text NULL, `group_items` uuid NOT NULL, `item_children` uuid NULL, `location_items` uuid NULL, PRIMARY KEY (`id`), CONSTRAINT `items_groups_items` FOREIGN KEY (`group_items`) REFERENCES `groups` (`id`) ON DELETE CASCADE, CONSTRAINT `items_items_children` FOREIGN KEY (`item_children`) REFERENCES `items` (`id`) ON DELETE SET NULL, CONSTRAINT `items_locations_items` FOREIGN KEY (`location_items`) REFERENCES `locations` (`id`) ON DELETE CASCADE);
|
||||||
|
-- copy rows from old table "items" to new temporary table "new_items"
|
||||||
|
INSERT INTO `new_items` (`id`, `created_at`, `updated_at`, `name`, `description`, `import_ref`, `notes`, `quantity`, `insured`, `serial_number`, `model_number`, `manufacturer`, `lifetime_warranty`, `warranty_expires`, `warranty_details`, `purchase_time`, `purchase_from`, `purchase_price`, `sold_time`, `sold_to`, `sold_price`, `sold_notes`, `group_items`, `item_children`, `location_items`) SELECT `id`, `created_at`, `updated_at`, `name`, `description`, `import_ref`, `notes`, `quantity`, `insured`, `serial_number`, `model_number`, `manufacturer`, `lifetime_warranty`, `warranty_expires`, `warranty_details`, `purchase_time`, `purchase_from`, `purchase_price`, `sold_time`, `sold_to`, `sold_price`, `sold_notes`, `group_items`, `item_children`, `location_items` FROM `items`;
|
||||||
|
-- drop "items" table after copying rows
|
||||||
|
DROP TABLE `items`;
|
||||||
|
-- rename temporary table "new_items" to "items"
|
||||||
|
ALTER TABLE `new_items` RENAME TO `items`;
|
||||||
|
-- create index "item_name" to table: "items"
|
||||||
|
CREATE INDEX `item_name` ON `items` (`name`);
|
||||||
|
-- create index "item_manufacturer" to table: "items"
|
||||||
|
CREATE INDEX `item_manufacturer` ON `items` (`manufacturer`);
|
||||||
|
-- create index "item_model_number" to table: "items"
|
||||||
|
CREATE INDEX `item_model_number` ON `items` (`model_number`);
|
||||||
|
-- create index "item_serial_number" to table: "items"
|
||||||
|
CREATE INDEX `item_serial_number` ON `items` (`serial_number`);
|
||||||
|
-- create index "item_archived" to table: "items"
|
||||||
|
CREATE INDEX `item_archived` ON `items` (`archived`);
|
||||||
|
-- enable back the enforcement of foreign-keys constraints
|
||||||
|
PRAGMA foreign_keys = on;
|
|
@ -1,5 +1,6 @@
|
||||||
h1:mYTnmyrnBDST/r93NGJM33mIJqhp/U9qR440zI99eqQ=
|
h1:i76VRMDIPdcmQtXTe9bzrgITAzLGjjVy9y8XaXIchAs=
|
||||||
20220929052825_init.sql h1:ZlCqm1wzjDmofeAcSX3jE4h4VcdTNGpRg2eabztDy9Q=
|
20220929052825_init.sql h1:ZlCqm1wzjDmofeAcSX3jE4h4VcdTNGpRg2eabztDy9Q=
|
||||||
20221001210956_group_invitations.sql h1:YQKJFtE39wFOcRNbZQ/d+ZlHwrcfcsZlcv/pLEYdpjw=
|
20221001210956_group_invitations.sql h1:YQKJFtE39wFOcRNbZQ/d+ZlHwrcfcsZlcv/pLEYdpjw=
|
||||||
20221009173029_add_user_roles.sql h1:vWmzAfgEWQeGk0Vn70zfVPCcfEZth3E0JcvyKTjpYyU=
|
20221009173029_add_user_roles.sql h1:vWmzAfgEWQeGk0Vn70zfVPCcfEZth3E0JcvyKTjpYyU=
|
||||||
20221020043305_allow_nesting_types.sql h1:4AyJpZ7l7SSJtJAQETYY802FHJ64ufYPJTqvwdiGn3M=
|
20221020043305_allow_nesting_types.sql h1:4AyJpZ7l7SSJtJAQETYY802FHJ64ufYPJTqvwdiGn3M=
|
||||||
|
20221101041931_add_archived_field.sql h1:L2WxiOh1svRn817cNURgqnEQg6DIcodZ1twK4tvxW94=
|
||||||
|
|
|
@ -20,12 +20,13 @@ type ItemsRepository struct {
|
||||||
|
|
||||||
type (
|
type (
|
||||||
ItemQuery struct {
|
ItemQuery struct {
|
||||||
Page int
|
Page int
|
||||||
PageSize int
|
PageSize int
|
||||||
Search string `json:"search"`
|
Search string `json:"search"`
|
||||||
LocationIDs []uuid.UUID `json:"locationIds"`
|
LocationIDs []uuid.UUID `json:"locationIds"`
|
||||||
LabelIDs []uuid.UUID `json:"labelIds"`
|
LabelIDs []uuid.UUID `json:"labelIds"`
|
||||||
SortBy string `json:"sortBy"`
|
SortBy string `json:"sortBy"`
|
||||||
|
IncludeArchived bool `json:"includeArchived"`
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemField struct {
|
ItemField struct {
|
||||||
|
@ -55,6 +56,7 @@ type (
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Quantity int `json:"quantity"`
|
Quantity int `json:"quantity"`
|
||||||
Insured bool `json:"insured"`
|
Insured bool `json:"insured"`
|
||||||
|
Archived bool `json:"archived"`
|
||||||
|
|
||||||
// Edges
|
// Edges
|
||||||
LocationID uuid.UUID `json:"locationId"`
|
LocationID uuid.UUID `json:"locationId"`
|
||||||
|
@ -93,6 +95,7 @@ type (
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Quantity int `json:"quantity"`
|
Quantity int `json:"quantity"`
|
||||||
Insured bool `json:"insured"`
|
Insured bool `json:"insured"`
|
||||||
|
Archived bool `json:"archived"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
UpdatedAt time.Time `json:"updatedAt"`
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
|
|
||||||
|
@ -157,6 +160,7 @@ func mapItemSummary(item *ent.Item) ItemSummary {
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
CreatedAt: item.CreatedAt,
|
CreatedAt: item.CreatedAt,
|
||||||
UpdatedAt: item.UpdatedAt,
|
UpdatedAt: item.UpdatedAt,
|
||||||
|
Archived: item.Archived,
|
||||||
|
|
||||||
// Edges
|
// Edges
|
||||||
Location: location,
|
Location: location,
|
||||||
|
@ -276,7 +280,20 @@ func (e *ItemsRepository) GetOneByGroup(ctx context.Context, gid, id uuid.UUID)
|
||||||
|
|
||||||
// QueryByGroup returns a list of items that belong to a specific group based on the provided query.
|
// QueryByGroup returns a list of items that belong to a specific group based on the provided query.
|
||||||
func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q ItemQuery) (PaginationResult[ItemSummary], error) {
|
func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q ItemQuery) (PaginationResult[ItemSummary], error) {
|
||||||
qb := e.db.Item.Query().Where(item.HasGroupWith(group.ID(gid)))
|
qb := e.db.Item.Query().Where(
|
||||||
|
item.HasGroupWith(group.ID(gid)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if q.IncludeArchived {
|
||||||
|
qb = qb.Where(
|
||||||
|
item.Or(
|
||||||
|
item.Archived(true),
|
||||||
|
item.Archived(false),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
qb = qb.Where(item.Archived(false))
|
||||||
|
}
|
||||||
|
|
||||||
if len(q.LabelIDs) > 0 {
|
if len(q.LabelIDs) > 0 {
|
||||||
labels := make([]predicate.Item, 0, len(q.LabelIDs))
|
labels := make([]predicate.Item, 0, len(q.LabelIDs))
|
||||||
|
@ -384,6 +401,7 @@ func (e *ItemsRepository) UpdateByGroup(ctx context.Context, gid uuid.UUID, data
|
||||||
SetSerialNumber(data.SerialNumber).
|
SetSerialNumber(data.SerialNumber).
|
||||||
SetModelNumber(data.ModelNumber).
|
SetModelNumber(data.ModelNumber).
|
||||||
SetManufacturer(data.Manufacturer).
|
SetManufacturer(data.Manufacturer).
|
||||||
|
SetArchived(data.Archived).
|
||||||
SetPurchaseTime(data.PurchaseTime).
|
SetPurchaseTime(data.PurchaseTime).
|
||||||
SetPurchaseFrom(data.PurchaseFrom).
|
SetPurchaseFrom(data.PurchaseFrom).
|
||||||
SetPurchasePrice(data.PurchasePrice).
|
SetPurchasePrice(data.PurchasePrice).
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||||
)
|
)
|
||||||
|
@ -68,7 +69,9 @@ func (r *LabelRepository) getOne(ctx context.Context, where ...predicate.Label)
|
||||||
return mapLabelOutErr(r.db.Label.Query().
|
return mapLabelOutErr(r.db.Label.Query().
|
||||||
Where(where...).
|
Where(where...).
|
||||||
WithGroup().
|
WithGroup().
|
||||||
WithItems().
|
WithItems(func(iq *ent.ItemQuery) {
|
||||||
|
iq.Where(item.Archived(false))
|
||||||
|
}).
|
||||||
Only(ctx),
|
Only(ctx),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||||
)
|
)
|
||||||
|
@ -105,6 +106,7 @@ func (r *LocationRepository) GetAll(ctx context.Context, groupId uuid.UUID) ([]L
|
||||||
items
|
items
|
||||||
WHERE
|
WHERE
|
||||||
items.location_items = locations.id
|
items.location_items = locations.id
|
||||||
|
AND items.archived = false
|
||||||
) as item_count
|
) as item_count
|
||||||
FROM
|
FROM
|
||||||
locations
|
locations
|
||||||
|
@ -139,7 +141,7 @@ func (r *LocationRepository) getOne(ctx context.Context, where ...predicate.Loca
|
||||||
Where(where...).
|
Where(where...).
|
||||||
WithGroup().
|
WithGroup().
|
||||||
WithItems(func(iq *ent.ItemQuery) {
|
WithItems(func(iq *ent.ItemQuery) {
|
||||||
iq.WithLabel()
|
iq.Where(item.Archived(false)).WithLabel()
|
||||||
}).
|
}).
|
||||||
WithParent().
|
WithParent().
|
||||||
WithChildren().
|
WithChildren().
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div v-if="!inline" class="form-control w-full">
|
<div v-if="!inline" class="form-control w-full">
|
||||||
<label class="label cursor-pointer">
|
<label class="label cursor-pointer">
|
||||||
<span class="label-text"> {{ label }}</span>
|
<span class="label-text"> {{ label }}</span>
|
||||||
<input v-model="value" type="checkbox" class="checkbox" />
|
<input v-model="value" type="checkbox" class="checkbox checkbox-primary" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="label cursor-pointer sm:grid sm:grid-cols-4 sm:items-start sm:gap-4">
|
<div v-else class="label cursor-pointer sm:grid sm:grid-cols-4 sm:items-start sm:gap-4">
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<input v-model="value" type="checkbox" class="checkbox" />
|
<input v-model="value" type="checkbox" class="checkbox checkbox-primary" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<h2 class="card-title">
|
<h2 class="card-title">
|
||||||
<Icon name="mdi-package-variant" />
|
<Icon name="mdi-package-variant" />
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
|
<Icon v-if="item.archived" class="ml-auto" name="mdi-archive-outline" />
|
||||||
</h2>
|
</h2>
|
||||||
<p>{{ description }}</p>
|
<p>{{ description }}</p>
|
||||||
<div class="flex gap-2 flex-wrap justify-end">
|
<div class="flex gap-2 flex-wrap justify-end">
|
||||||
|
|
3
frontend/components/global/Spacer.vue
Normal file
3
frontend/components/global/Spacer.vue
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<template>
|
||||||
|
<div class="grow-1 max-w-full"></div>
|
||||||
|
</template>
|
|
@ -10,13 +10,19 @@ export function useItemSearch(client: UserClient, opts?: SearchOptions) {
|
||||||
const locations = ref<LocationSummary[]>([]);
|
const locations = ref<LocationSummary[]>([]);
|
||||||
const labels = ref<LabelSummary[]>([]);
|
const labels = ref<LabelSummary[]>([]);
|
||||||
const results = ref<ItemSummary[]>([]);
|
const results = ref<ItemSummary[]>([]);
|
||||||
|
const includeArchived = ref(false);
|
||||||
|
|
||||||
watchDebounced(query, search, { debounce: 250, maxWait: 1000 });
|
watchDebounced(query, search, { debounce: 250, maxWait: 1000 });
|
||||||
async function search() {
|
async function search() {
|
||||||
const locIds = locations.value.map(l => l.id);
|
const locIds = locations.value.map(l => l.id);
|
||||||
const labelIds = labels.value.map(l => l.id);
|
const labelIds = labels.value.map(l => l.id);
|
||||||
|
|
||||||
const { data, error } = await client.items.getAll({ q: query.value, locations: locIds, labels: labelIds });
|
const { data, error } = await client.items.getAll({
|
||||||
|
q: query.value,
|
||||||
|
locations: locIds,
|
||||||
|
labels: labelIds,
|
||||||
|
includeArchived: includeArchived.value,
|
||||||
|
});
|
||||||
if (error) {
|
if (error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
import { AttachmentTypes, PaginationResult } from "../types/non-generated";
|
import { AttachmentTypes, PaginationResult } from "../types/non-generated";
|
||||||
|
|
||||||
export type ItemsQuery = {
|
export type ItemsQuery = {
|
||||||
|
includeArchived?: boolean;
|
||||||
page?: number;
|
page?: number;
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
locations?: string[];
|
locations?: string[];
|
||||||
|
|
|
@ -63,6 +63,7 @@ export interface ItemField {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ItemOut {
|
export interface ItemOut {
|
||||||
|
archived: boolean;
|
||||||
attachments: ItemAttachment[];
|
attachments: ItemAttachment[];
|
||||||
children: ItemSummary[];
|
children: ItemSummary[];
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
@ -107,6 +108,7 @@ export interface ItemOut {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ItemSummary {
|
export interface ItemSummary {
|
||||||
|
archived: boolean;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
description: string;
|
description: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -121,6 +123,7 @@ export interface ItemSummary {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ItemUpdate {
|
export interface ItemUpdate {
|
||||||
|
archived: boolean;
|
||||||
description: string;
|
description: string;
|
||||||
fields: ItemField[];
|
fields: ItemField[];
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -115,6 +115,11 @@
|
||||||
label: "Insured",
|
label: "Insured",
|
||||||
ref: "insured",
|
ref: "insured",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "checkbox",
|
||||||
|
label: "Archived",
|
||||||
|
ref: "archived",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const purchaseFields: FormField[] = [
|
const purchaseFields: FormField[] = [
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Detail, Details } from "~~/components/global/DetailsSection/types";
|
import { CustomDetail, Detail, Details } from "~~/components/global/DetailsSection/types";
|
||||||
import { ItemAttachment } from "~~/lib/api/types/data-contracts";
|
import { ItemAttachment } from "~~/lib/api/types/data-contracts";
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const itemDetails = computed(() => {
|
const itemDetails = computed<Details>(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: "Description",
|
name: "Description",
|
||||||
|
@ -107,11 +107,11 @@
|
||||||
const url = maybeUrl(field.textValue);
|
const url = maybeUrl(field.textValue);
|
||||||
if (url.isUrl) {
|
if (url.isUrl) {
|
||||||
return {
|
return {
|
||||||
|
type: "link",
|
||||||
name: field.name,
|
name: field.name,
|
||||||
text: url.text,
|
text: url.text,
|
||||||
type: "link",
|
|
||||||
href: url.url,
|
href: url.url,
|
||||||
};
|
} as CustomDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -23,7 +23,12 @@
|
||||||
const locations = selectedLocations.value.map(l => l.id);
|
const locations = selectedLocations.value.map(l => l.id);
|
||||||
const labels = selectedLabels.value.map(l => l.id);
|
const labels = selectedLabels.value.map(l => l.id);
|
||||||
|
|
||||||
const { data, error } = await api.items.getAll({ q: query.value, locations, labels });
|
const { data, error } = await api.items.getAll({
|
||||||
|
q: query.value,
|
||||||
|
locations,
|
||||||
|
labels,
|
||||||
|
includeArchived: includeArchived.value,
|
||||||
|
});
|
||||||
if (error) {
|
if (error) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
return;
|
return;
|
||||||
|
@ -46,6 +51,7 @@
|
||||||
const advanced = ref(false);
|
const advanced = ref(false);
|
||||||
const selectedLocations = ref([]);
|
const selectedLocations = ref([]);
|
||||||
const selectedLabels = ref([]);
|
const selectedLabels = ref([]);
|
||||||
|
const includeArchived = ref(false);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (!advanced.value) {
|
if (!advanced.value) {
|
||||||
|
@ -57,6 +63,7 @@
|
||||||
watchDebounced(query, search, { debounce: 250, maxWait: 1000 });
|
watchDebounced(query, search, { debounce: 250, maxWait: 1000 });
|
||||||
watchDebounced(selectedLocations, search, { debounce: 250, maxWait: 1000 });
|
watchDebounced(selectedLocations, search, { debounce: 250, maxWait: 1000 });
|
||||||
watchDebounced(selectedLabels, search, { debounce: 250, maxWait: 1000 });
|
watchDebounced(selectedLabels, search, { debounce: 250, maxWait: 1000 });
|
||||||
|
watch(includeArchived, search);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -77,6 +84,13 @@
|
||||||
<div class="px-4 pb-4">
|
<div class="px-4 pb-4">
|
||||||
<FormMultiselect v-model="selectedLabels" label="Labels" :items="labels ?? []" />
|
<FormMultiselect v-model="selectedLabels" label="Labels" :items="labels ?? []" />
|
||||||
<FormMultiselect v-model="selectedLocations" label="Locations" :items="locations ?? []" />
|
<FormMultiselect v-model="selectedLocations" label="Locations" :items="locations ?? []" />
|
||||||
|
<div class="flex pb-2 pt-5">
|
||||||
|
<label class="label cursor-pointer mr-auto">
|
||||||
|
<input v-model="includeArchived" type="checkbox" class="toggle toggle-primary" />
|
||||||
|
<span class="label-text ml-4"> Include Archived Items </span>
|
||||||
|
</label>
|
||||||
|
<Spacer />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</BaseCard>
|
</BaseCard>
|
||||||
<section class="mt-10">
|
<section class="mt-10">
|
||||||
|
|
Loading…
Reference in a new issue