| @ -0,0 +1,695 @@ | |||||
| package astdialogs | |||||
| import ( | |||||
| "fmt" | |||||
| "slices" | |||||
| "strconv" | |||||
| "strings" | |||||
| "git.brettb.xyz/goinv/client/internal/api" | |||||
| "git.brettb.xyz/goinv/client/internal/types" | |||||
| "git.brettb.xyz/goinv/client/internal/ui/dialogs" | |||||
| "git.brettb.xyz/goinv/client/internal/ui/style" | |||||
| "git.brettb.xyz/goinv/client/internal/ui/utils" | |||||
| "github.com/gdamore/tcell/v2" | |||||
| "github.com/rivo/tview" | |||||
| "go.uber.org/zap" | |||||
| ) | |||||
| const ( | |||||
| assetEditDialogMaxWidth = 100 | |||||
| assetEditDialogHeight = 17 | |||||
| ) | |||||
| const ( | |||||
| editAssetFormFocus = 0 + iota | |||||
| editCategoriesFocus | |||||
| editCategoryPagesFocus | |||||
| editAssetNameFieldFocus | |||||
| editAssetQuantityFieldFocus | |||||
| editAssetLengthFieldFocus | |||||
| editAssetManufacturerFieldFocus | |||||
| editAssetModelFieldFocus | |||||
| editAssetPriceFieldFocus | |||||
| editAssetCategoryFieldFocus | |||||
| editAssetShelfFieldFocus | |||||
| editAssetCommentFieldFocus | |||||
| ) | |||||
| type AssetEditDialog struct { | |||||
| *tview.Box | |||||
| layout *tview.Flex | |||||
| editCategoryLabels []string | |||||
| categories *tview.TextView | |||||
| categoryPages *tview.Pages | |||||
| generalInfoPage *tview.Flex | |||||
| locationPage *tview.Flex | |||||
| commentsPage *tview.Flex | |||||
| form *tview.Form | |||||
| display bool | |||||
| activePageIndex int | |||||
| focusElement int | |||||
| logger *zap.Logger | |||||
| client *api.APIClient | |||||
| asset *types.Asset | |||||
| categoryList []*types.Category | |||||
| shelfList []*types.ShelfLocation | |||||
| assetNameField *tview.InputField | |||||
| assetQuantityField *tview.InputField | |||||
| assetLengthField *tview.InputField | |||||
| assetManufacturerField *tview.InputField | |||||
| assetModelField *tview.InputField | |||||
| assetPriceField *tview.InputField | |||||
| assetCategoryField *tview.DropDown | |||||
| assetShelfField *tview.DropDown | |||||
| assetCommentsArea *tview.TextArea | |||||
| focusMap map[int]tview.Primitive | |||||
| cancelHandler func() | |||||
| editHandler func() | |||||
| } | |||||
| func NewAssetEditDialog(logger *zap.Logger, client *api.APIClient) *AssetEditDialog { | |||||
| editDialog := AssetEditDialog{ | |||||
| Box: tview.NewBox(), | |||||
| layout: tview.NewFlex(), | |||||
| editCategoryLabels: []string{ | |||||
| "General", | |||||
| "Location", | |||||
| "Comments", | |||||
| }, | |||||
| categories: tview.NewTextView(), | |||||
| categoryPages: tview.NewPages(), | |||||
| generalInfoPage: tview.NewFlex(), | |||||
| locationPage: tview.NewFlex(), | |||||
| commentsPage: tview.NewFlex(), | |||||
| form: tview.NewForm(), | |||||
| display: false, | |||||
| activePageIndex: 0, | |||||
| logger: logger, | |||||
| client: client, | |||||
| assetNameField: tview.NewInputField(), | |||||
| assetQuantityField: tview.NewInputField(), | |||||
| assetLengthField: tview.NewInputField(), | |||||
| assetManufacturerField: tview.NewInputField(), | |||||
| assetModelField: tview.NewInputField(), | |||||
| assetPriceField: tview.NewInputField(), | |||||
| assetCategoryField: tview.NewDropDown(), | |||||
| assetShelfField: tview.NewDropDown(), | |||||
| assetCommentsArea: tview.NewTextArea(), | |||||
| } | |||||
| editDialog.focusMap = map[int]tview.Primitive{ | |||||
| editAssetNameFieldFocus: editDialog.assetNameField, | |||||
| editAssetQuantityFieldFocus: editDialog.assetQuantityField, | |||||
| editAssetLengthFieldFocus: editDialog.assetLengthField, | |||||
| editAssetManufacturerFieldFocus: editDialog.assetManufacturerField, | |||||
| editAssetModelFieldFocus: editDialog.assetModelField, | |||||
| editAssetPriceFieldFocus: editDialog.assetPriceField, | |||||
| editAssetCategoryFieldFocus: editDialog.assetCategoryField, | |||||
| editAssetShelfFieldFocus: editDialog.assetShelfField, | |||||
| editAssetCommentFieldFocus: editDialog.assetCommentsArea, | |||||
| } | |||||
| editDialog.setupLayout() | |||||
| editDialog.setActiveCategory(0) | |||||
| editDialog.initCustomInputHandlers() | |||||
| return &editDialog | |||||
| } | |||||
| func (d *AssetEditDialog) Display() { | |||||
| d.display = true | |||||
| d.initData() | |||||
| d.focusElement = editCategoryPagesFocus | |||||
| } | |||||
| func (d *AssetEditDialog) IsDisplay() bool { | |||||
| return d.display | |||||
| } | |||||
| func (d *AssetEditDialog) Hide() { | |||||
| d.display = false | |||||
| } | |||||
| func (d *AssetEditDialog) HasFocus() bool { | |||||
| return utils.CheckFocus(d.categories, d.categoryPages, d.Box, d.form) | |||||
| } | |||||
| func (d *AssetEditDialog) Focus(delegate func(tview.Primitive)) { | |||||
| switch d.focusElement { | |||||
| case editAssetFormFocus: | |||||
| button := d.form.GetButton(d.form.GetButtonCount() - 1) | |||||
| button.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { | |||||
| if event.Key() == utils.SwitchFocusKey.EventKey() { | |||||
| d.focusElement = editCategoriesFocus | |||||
| d.Focus(delegate) | |||||
| d.form.SetFocus(0) | |||||
| return nil | |||||
| } | |||||
| if event.Key() == tcell.KeyEnter { | |||||
| return nil | |||||
| } | |||||
| return event | |||||
| }) | |||||
| delegate(d.form) | |||||
| case editCategoriesFocus: | |||||
| d.categories.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { | |||||
| if event.Key() == utils.SwitchFocusKey.EventKey() { | |||||
| d.focusElement = editCategoryPagesFocus | |||||
| d.Focus(delegate) | |||||
| return nil | |||||
| } | |||||
| event = utils.ParseKeyEventKey(d.logger, event) | |||||
| if event.Key() == tcell.KeyDown { | |||||
| d.nextCategory() | |||||
| } | |||||
| if event.Key() == tcell.KeyUp { | |||||
| d.previousCategory() | |||||
| } | |||||
| return event | |||||
| }) | |||||
| delegate(d.categories) | |||||
| case editCategoryPagesFocus: | |||||
| delegate(d.categoryPages) | |||||
| default: | |||||
| delegate(d.focusMap[d.focusElement]) | |||||
| } | |||||
| } | |||||
| func (d *AssetEditDialog) InputHandler() func(*tcell.EventKey, func(tview.Primitive)) { | |||||
| return d.WrapInputHandler(func(event *tcell.EventKey, setFocus func(tview.Primitive)) { | |||||
| d.logger.Sugar().Debugf("asset edit dialog event %v received", event) | |||||
| if event.Key() == utils.CloseDialogKey.EventKey() && !d.dropdownHasFocus() { | |||||
| d.cancelHandler() | |||||
| return | |||||
| } | |||||
| if d.generalInfoPage.HasFocus() { | |||||
| if handler := d.generalInfoPage.InputHandler(); handler != nil { | |||||
| if event.Key() == utils.SwitchFocusKey.EventKey() { | |||||
| d.setGeneralInfoNextFocus() | |||||
| } | |||||
| handler(event, setFocus) | |||||
| return | |||||
| } | |||||
| } | |||||
| if d.locationPage.HasFocus() { | |||||
| if handler := d.locationPage.InputHandler(); handler != nil { | |||||
| if event.Key() == utils.SwitchFocusKey.EventKey() { | |||||
| d.setLocationNextFocus() | |||||
| } | |||||
| handler(event, setFocus) | |||||
| return | |||||
| } | |||||
| } | |||||
| if d.commentsPage.HasFocus() { | |||||
| if handler := d.commentsPage.InputHandler(); handler != nil { | |||||
| if event.Key() == utils.SwitchFocusKey.EventKey() { | |||||
| d.setCommentsNextFocus() | |||||
| } | |||||
| handler(event, setFocus) | |||||
| return | |||||
| } | |||||
| } | |||||
| if d.categories.HasFocus() { | |||||
| if categoryHandler := d.categories.InputHandler(); categoryHandler != nil { | |||||
| categoryHandler(event, setFocus) | |||||
| return | |||||
| } | |||||
| } | |||||
| if d.form.HasFocus() { | |||||
| if formHandler := d.form.InputHandler(); formHandler != nil { | |||||
| if event.Key() == tcell.KeyEnter { | |||||
| enterButton := d.form.GetButton(d.form.GetButtonCount() - 1) | |||||
| if enterButton.HasFocus() { | |||||
| d.editHandler() | |||||
| } | |||||
| } | |||||
| formHandler(event, setFocus) | |||||
| return | |||||
| } | |||||
| } | |||||
| }) | |||||
| } | |||||
| func (d *AssetEditDialog) SetRect(x, y, width, height int) { | |||||
| if width > assetEditDialogMaxWidth { | |||||
| emptySpace := (width - assetEditDialogMaxWidth) / 2 | |||||
| x += emptySpace | |||||
| width = assetEditDialogMaxWidth | |||||
| } | |||||
| if height > assetEditDialogHeight { | |||||
| emptySpace := (height - assetEditDialogHeight) / 2 | |||||
| y += emptySpace | |||||
| height = assetEditDialogHeight | |||||
| } | |||||
| d.Box.SetRect(x, y, width, height) | |||||
| } | |||||
| func (d *AssetEditDialog) Draw(screen tcell.Screen) { | |||||
| if !d.display { | |||||
| return | |||||
| } | |||||
| d.Box.DrawForSubclass(screen, d) | |||||
| x, y, width, height := d.Box.GetInnerRect() | |||||
| d.layout.SetRect(x, y, width, height) | |||||
| d.layout.Draw(screen) | |||||
| } | |||||
| func (d *AssetEditDialog) SetEditFunc(f func()) *AssetEditDialog { | |||||
| d.editHandler = f | |||||
| enterButton := d.form.GetButton(d.form.GetButtonCount() - 1) | |||||
| enterButton.SetSelectedFunc(f) | |||||
| return d | |||||
| } | |||||
| func (d *AssetEditDialog) SetCancelFunc(f func()) *AssetEditDialog { | |||||
| d.cancelHandler = f | |||||
| cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) | |||||
| cancelButton.SetSelectedFunc(f) | |||||
| return d | |||||
| } | |||||
| func (d *AssetEditDialog) dropdownHasFocus() bool { | |||||
| return utils.CheckFocus(d.assetCategoryField, d.assetShelfField) | |||||
| } | |||||
| func (d *AssetEditDialog) SetAsset(a *types.Asset) { | |||||
| d.asset = a | |||||
| } | |||||
| func (d *AssetEditDialog) initData() { | |||||
| // Get available shelves | |||||
| shelfList, _ := d.client.RetrieveAllShelves() | |||||
| d.shelfList = shelfList | |||||
| shelfOptions := []string{""} | |||||
| for _, shelf := range d.shelfList { | |||||
| shelfOptions = append(shelfOptions, shelf.Name) // In case we want to do custom formatting later | |||||
| } | |||||
| // Get available categories | |||||
| categoryList, _ := d.client.RetrieveAllCategories() | |||||
| d.categoryList = categoryList | |||||
| categoryOptions := []string{""} | |||||
| for _, category := range d.categoryList { | |||||
| categoryOptions = append(categoryOptions, category.Name) | |||||
| } | |||||
| d.setActiveCategory(0) | |||||
| // General category | |||||
| if d.asset == nil { | |||||
| d.assetNameField.SetText("") | |||||
| d.assetQuantityField.SetText("") | |||||
| d.assetLengthField.SetText("") | |||||
| d.assetManufacturerField.SetText("") | |||||
| d.assetModelField.SetText("") | |||||
| d.assetPriceField.SetText("") | |||||
| // Location category | |||||
| d.assetShelfField.SetOptions(shelfOptions, nil) | |||||
| d.assetShelfField.SetCurrentOption(0) | |||||
| d.assetCategoryField.SetOptions(categoryOptions, nil) | |||||
| d.assetCategoryField.SetCurrentOption(0) | |||||
| // Comments category | |||||
| d.assetCommentsArea.SetText("", true) | |||||
| } else { | |||||
| d.assetNameField.SetText(d.asset.Name) | |||||
| d.assetQuantityField.SetText(fmt.Sprintf("%d", d.asset.Quantity)) | |||||
| d.assetLengthField.SetText(d.asset.Length) | |||||
| d.assetManufacturerField.SetText(d.asset.Manufacturer) | |||||
| d.assetModelField.SetText(d.asset.ModelName) | |||||
| d.assetPriceField.SetText(fmt.Sprintf("%.2f", d.asset.Price)) | |||||
| // Location category | |||||
| d.assetShelfField.SetOptions(shelfOptions, nil) | |||||
| d.assetShelfField.SetCurrentOption(findOption(shelfOptions, d.asset.ShelfLocation.Name)) | |||||
| d.assetCategoryField.SetOptions(categoryOptions, nil) | |||||
| d.assetCategoryField.SetCurrentOption(findOption(categoryOptions, d.asset.Category.Name)) | |||||
| // Comments category | |||||
| d.assetCommentsArea.SetText("", true) | |||||
| } | |||||
| } | |||||
| func findOption(options []string, search string) int { | |||||
| return slices.Index(options, search) | |||||
| } | |||||
| func (d *AssetEditDialog) setupLayout() { | |||||
| bgColor := style.DialogBgColor | |||||
| fgColor := style.DialogFgColor | |||||
| d.categories.SetDynamicColors(true). | |||||
| SetWrap(true). | |||||
| SetTextAlign(tview.AlignLeft) | |||||
| d.categories.SetBackgroundColor(fgColor) | |||||
| d.categories.SetTextColor(bgColor) | |||||
| d.categories.SetBorder(true) | |||||
| d.categories.SetBorderColor(style.DialogSubBoxBorderColor) | |||||
| d.categoryPages.SetBackgroundColor(bgColor) | |||||
| d.categoryPages.SetBorder(true) | |||||
| d.categoryPages.SetBorderColor(style.DialogSubBoxBorderColor) | |||||
| d.setupGeneralInfoPageUI() | |||||
| d.setupLocationPageUI() | |||||
| d.setupCommentsPageUI() | |||||
| activatedStyle := tcell.StyleDefault. | |||||
| Background(style.ButtonSelectedBgColor). | |||||
| Foreground(style.ButtonSelectedFgColor) | |||||
| d.form.SetBackgroundColor(bgColor) | |||||
| d.form.AddButton("Cancel", nil) | |||||
| d.form.AddButton("Edit", nil) | |||||
| d.form.SetButtonsAlign(tview.AlignRight) | |||||
| d.form.SetButtonBackgroundColor(style.ButtonBgColor) | |||||
| d.form.SetButtonTextColor(style.ButtonFgColor) | |||||
| d.form.SetButtonActivatedStyle(activatedStyle) | |||||
| d.categoryPages.AddPage(d.editCategoryLabels[generalPageIndex], d.generalInfoPage, true, true) | |||||
| d.categoryPages.AddPage(d.editCategoryLabels[locationPageIndex], d.locationPage, true, true) | |||||
| d.categoryPages.AddPage(d.editCategoryLabels[commentPageIndex], d.commentsPage, true, true) | |||||
| d.layout.SetBackgroundColor(bgColor) | |||||
| d.layout.SetBorder(true) | |||||
| d.layout.SetBorderColor(style.DialogBorderColor) | |||||
| d.layout.SetTitle("ASSET EDIT") | |||||
| d.layout.SetTitleColor(style.DialogFgColor) | |||||
| _, layoutWidth := utils.AlignStringListWidth(d.editCategoryLabels) | |||||
| layout := tview.NewFlex().SetDirection(tview.FlexColumn) | |||||
| layout.AddItem(d.categories, layoutWidth+6, 0, true) | |||||
| layout.AddItem(d.categoryPages, 0, 1, true) | |||||
| layout.SetBackgroundColor(bgColor) | |||||
| d.layout.SetDirection(tview.FlexRow) | |||||
| d.layout.AddItem(layout, 0, 1, true) | |||||
| d.layout.AddItem(d.form, dialogs.DialogFormHeight, 0, true) | |||||
| } | |||||
| func (d *AssetEditDialog) setupGeneralInfoPageUI() { | |||||
| bgColor := style.DialogBgColor | |||||
| inputFieldBgColor := style.InputFieldBgColor | |||||
| pageLabelWidth := 12 | |||||
| d.assetNameField.SetLabel("name:") | |||||
| d.assetNameField.SetLabelWidth(pageLabelWidth) | |||||
| d.assetNameField.SetLabelColor(bgColor) | |||||
| d.assetNameField.SetBackgroundColor(style.DialogFgColor) | |||||
| d.assetNameField.SetFieldBackgroundColor(inputFieldBgColor) | |||||
| d.assetQuantityField.SetLabel("quantity:") | |||||
| d.assetQuantityField.SetLabelWidth(pageLabelWidth) | |||||
| d.assetQuantityField.SetLabelColor(bgColor) | |||||
| d.assetQuantityField.SetBackgroundColor(style.DialogFgColor) | |||||
| d.assetQuantityField.SetFieldBackgroundColor(inputFieldBgColor) | |||||
| d.assetLengthField.SetLabel("length:") | |||||
| d.assetLengthField.SetLabelWidth(pageLabelWidth) | |||||
| d.assetLengthField.SetLabelColor(bgColor) | |||||
| d.assetLengthField.SetBackgroundColor(style.DialogFgColor) | |||||
| d.assetLengthField.SetFieldBackgroundColor(inputFieldBgColor) | |||||
| d.assetManufacturerField.SetLabel("manufacturer:") | |||||
| d.assetManufacturerField.SetLabelWidth(pageLabelWidth) | |||||
| d.assetManufacturerField.SetLabelColor(bgColor) | |||||
| d.assetManufacturerField.SetBackgroundColor(style.DialogFgColor) | |||||
| d.assetManufacturerField.SetFieldBackgroundColor(inputFieldBgColor) | |||||
| d.assetModelField.SetLabel("model:") | |||||
| d.assetModelField.SetLabelWidth(pageLabelWidth) | |||||
| d.assetModelField.SetLabelColor(bgColor) | |||||
| d.assetModelField.SetBackgroundColor(style.DialogFgColor) | |||||
| d.assetModelField.SetFieldBackgroundColor(inputFieldBgColor) | |||||
| d.assetPriceField.SetLabel("price:") | |||||
| d.assetPriceField.SetLabelWidth(pageLabelWidth) | |||||
| d.assetPriceField.SetLabelColor(bgColor) | |||||
| d.assetPriceField.SetBackgroundColor(style.DialogFgColor) | |||||
| d.assetPriceField.SetFieldBackgroundColor(inputFieldBgColor) | |||||
| d.generalInfoPage.SetDirection(tview.FlexRow) | |||||
| d.generalInfoPage.AddItem(d.assetNameField, 1, 0, true) | |||||
| d.generalInfoPage.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true) | |||||
| d.generalInfoPage.AddItem(d.assetQuantityField, 1, 0, true) | |||||
| d.generalInfoPage.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true) | |||||
| d.generalInfoPage.AddItem(d.assetLengthField, 1, 0, true) | |||||
| d.generalInfoPage.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true) | |||||
| d.generalInfoPage.AddItem(d.assetManufacturerField, 1, 0, true) | |||||
| d.generalInfoPage.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true) | |||||
| d.generalInfoPage.AddItem(d.assetModelField, 1, 0, true) | |||||
| d.generalInfoPage.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true) | |||||
| d.generalInfoPage.AddItem(d.assetPriceField, 1, 0, true) | |||||
| d.generalInfoPage.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true) | |||||
| } | |||||
| func (d *AssetEditDialog) setupLocationPageUI() { | |||||
| bgColor := style.DialogBgColor | |||||
| inputFieldBgColor := style.InputFieldBgColor | |||||
| pageLabelWidth := 12 | |||||
| ddUnselectedStyle := style.DropdownUnselected | |||||
| ddSelectedStyle := style.DropdownSelected | |||||
| d.assetCategoryField.SetLabel("category:") | |||||
| d.assetCategoryField.SetLabelWidth(pageLabelWidth) | |||||
| d.assetCategoryField.SetBackgroundColor(bgColor) | |||||
| d.assetCategoryField.SetLabelColor(style.DialogFgColor) | |||||
| d.assetCategoryField.SetListStyles(ddUnselectedStyle, ddSelectedStyle) | |||||
| d.assetCategoryField.SetFieldBackgroundColor(inputFieldBgColor) | |||||
| d.assetShelfField.SetLabel("shelf:") | |||||
| d.assetShelfField.SetLabelWidth(pageLabelWidth) | |||||
| d.assetShelfField.SetBackgroundColor(bgColor) | |||||
| d.assetShelfField.SetLabelColor(style.DialogFgColor) | |||||
| d.assetShelfField.SetListStyles(ddUnselectedStyle, ddSelectedStyle) | |||||
| d.assetShelfField.SetFieldBackgroundColor(inputFieldBgColor) | |||||
| d.locationPage.SetDirection(tview.FlexRow) | |||||
| d.locationPage.AddItem(d.assetCategoryField, 1, 0, true) | |||||
| d.locationPage.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true) | |||||
| d.locationPage.AddItem(d.assetShelfField, 1, 0, true) | |||||
| d.locationPage.SetBackgroundColor(bgColor) | |||||
| } | |||||
| func (d *AssetEditDialog) setupCommentsPageUI() { | |||||
| bgColor := style.DialogBgColor | |||||
| inputFieldBgColor := style.InputFieldBgColor | |||||
| pageLabelWidth := 12 | |||||
| d.assetCommentsArea.SetLabel("comments:") | |||||
| d.assetCommentsArea.SetLabelWidth(pageLabelWidth) | |||||
| d.assetCommentsArea.SetBackgroundColor(inputFieldBgColor) | |||||
| d.assetCommentsArea.SetLabelStyle(tcell.StyleDefault.Foreground(style.DialogFgColor).Background(bgColor)) | |||||
| d.assetCommentsArea.SetWrap(true) | |||||
| d.commentsPage.AddItem(d.assetCommentsArea, 0, 1, true) | |||||
| d.commentsPage.SetBackgroundColor(bgColor) | |||||
| } | |||||
| func (d *AssetEditDialog) setActiveCategory(idx int) { | |||||
| fgColor := style.ButtonSelectedFgColor | |||||
| bgBolor := style.ButtonSelectedBgColor | |||||
| ctgTextColor := style.GetColorHex(fgColor) | |||||
| ctgBgColor := style.GetColorHex(bgBolor) | |||||
| d.activePageIndex = idx | |||||
| d.categories.Clear() | |||||
| alignedList, _ := utils.AlignStringListWidth(d.editCategoryLabels) | |||||
| var ctgList []string | |||||
| for i, lbl := range alignedList { | |||||
| if i == idx { | |||||
| ctgList = append(ctgList, fmt.Sprintf("[%s:%s:b]-> %s ", ctgTextColor, ctgBgColor, lbl)) | |||||
| continue | |||||
| } | |||||
| ctgList = append(ctgList, fmt.Sprintf("[-:-:-] %s ", lbl)) | |||||
| } | |||||
| d.categories.SetText(strings.Join(ctgList, "\n")) | |||||
| d.categoryPages.SwitchToPage(d.editCategoryLabels[idx]) | |||||
| } | |||||
| func (d *AssetEditDialog) nextCategory() { | |||||
| activePage := d.activePageIndex | |||||
| if d.activePageIndex < len(d.editCategoryLabels)-1 { | |||||
| activePage++ | |||||
| d.setActiveCategory(activePage) | |||||
| return | |||||
| } | |||||
| d.setActiveCategory(0) | |||||
| } | |||||
| func (d *AssetEditDialog) previousCategory() { | |||||
| activePage := d.activePageIndex | |||||
| if d.activePageIndex > 0 { | |||||
| activePage-- | |||||
| d.setActiveCategory(activePage) | |||||
| return | |||||
| } | |||||
| d.setActiveCategory(len(d.editCategoryLabels) - 1) | |||||
| } | |||||
| func (d *AssetEditDialog) initCustomInputHandlers() { | |||||
| d.assetShelfField.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { | |||||
| event = utils.ParseKeyEventKey(d.logger, event) | |||||
| return event | |||||
| }) | |||||
| d.assetCategoryField.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { | |||||
| event = utils.ParseKeyEventKey(d.logger, event) | |||||
| return event | |||||
| }) | |||||
| } | |||||
| func (d *AssetEditDialog) setGeneralInfoNextFocus() { | |||||
| // Name -> Quantity -> Length -> Manufacturer -> Model -> Price | |||||
| if d.assetNameField.HasFocus() { | |||||
| d.focusElement = editAssetQuantityFieldFocus | |||||
| return | |||||
| } | |||||
| if d.assetQuantityField.HasFocus() { | |||||
| d.focusElement = editAssetLengthFieldFocus | |||||
| return | |||||
| } | |||||
| if d.assetLengthField.HasFocus() { | |||||
| d.focusElement = editAssetManufacturerFieldFocus | |||||
| return | |||||
| } | |||||
| if d.assetManufacturerField.HasFocus() { | |||||
| d.focusElement = editAssetModelFieldFocus | |||||
| return | |||||
| } | |||||
| if d.assetModelField.HasFocus() { | |||||
| d.focusElement = editAssetPriceFieldFocus | |||||
| return | |||||
| } | |||||
| d.focusElement = editAssetFormFocus | |||||
| } | |||||
| func (d *AssetEditDialog) setLocationNextFocus() { | |||||
| // Category -> Shelf | |||||
| if d.assetCategoryField.HasFocus() { | |||||
| d.focusElement = editAssetShelfFieldFocus | |||||
| return | |||||
| } | |||||
| d.focusElement = editAssetFormFocus | |||||
| } | |||||
| func (d *AssetEditDialog) setCommentsNextFocus() { | |||||
| d.focusElement = editAssetFormFocus | |||||
| } | |||||
| func (d *AssetEditDialog) EditAssetOptions() types.CreateAssetRequest { | |||||
| var ( | |||||
| quantity int | |||||
| categoryID *uint64 | |||||
| shelfID *uint64 | |||||
| price float64 | |||||
| ) | |||||
| var err error | |||||
| selectedCategoryIndex, _ := d.assetCategoryField.GetCurrentOption() | |||||
| if len(d.categoryList) > 0 && selectedCategoryIndex > 0 { | |||||
| categoryID = &d.categoryList[selectedCategoryIndex-1].ID | |||||
| } | |||||
| selectedShelfIndex, _ := d.assetShelfField.GetCurrentOption() | |||||
| if len(d.shelfList) > 0 && selectedShelfIndex > 0 { | |||||
| shelfID = &d.shelfList[selectedShelfIndex-1].ID | |||||
| } | |||||
| quantityStr := d.assetQuantityField.GetText() | |||||
| quantity, err = strconv.Atoi(quantityStr) | |||||
| if err != nil { | |||||
| quantity = 0 | |||||
| } | |||||
| priceStr := d.assetPriceField.GetText() | |||||
| price, err = strconv.ParseFloat(priceStr, 64) | |||||
| if err != nil { | |||||
| price = 0.0 | |||||
| } | |||||
| req := types.CreateAssetRequest{ | |||||
| Name: d.assetNameField.GetText(), | |||||
| Quantity: quantity, | |||||
| Length: d.assetLengthField.GetText(), | |||||
| Manufacturer: d.assetManufacturerField.GetText(), | |||||
| ModelName: d.assetModelField.GetText(), | |||||
| Price: price, | |||||
| Comments: d.assetCommentsArea.GetText(), | |||||
| ShelfLocationID: shelfID, | |||||
| CategoryID: categoryID, | |||||
| } | |||||
| return req | |||||
| } | |||||