Add collapsible group tools section
This commit is contained in:
@@ -152,6 +152,7 @@ type ui struct {
|
|||||||
confirmDeleteGroup widget.Clickable
|
confirmDeleteGroup widget.Clickable
|
||||||
cancelDeleteGroup widget.Clickable
|
cancelDeleteGroup widget.Clickable
|
||||||
addCustomField widget.Clickable
|
addCustomField widget.Clickable
|
||||||
|
toggleGroupControls widget.Clickable
|
||||||
togglePasswordInline widget.Clickable
|
togglePasswordInline widget.Clickable
|
||||||
showEntries widget.Clickable
|
showEntries widget.Clickable
|
||||||
showTemplates widget.Clickable
|
showTemplates widget.Clickable
|
||||||
@@ -180,6 +181,8 @@ type ui struct {
|
|||||||
eyeIcon *widget.Icon
|
eyeIcon *widget.Icon
|
||||||
eyeOffIcon *widget.Icon
|
eyeOffIcon *widget.Icon
|
||||||
copyIcon *widget.Icon
|
copyIcon *widget.Icon
|
||||||
|
expandMoreIcon *widget.Icon
|
||||||
|
expandLessIcon *widget.Icon
|
||||||
clipboardWriter clipboard.Writer
|
clipboardWriter clipboard.Writer
|
||||||
loadingMessage string
|
loadingMessage string
|
||||||
lifecycleMode string
|
lifecycleMode string
|
||||||
@@ -187,6 +190,7 @@ type ui struct {
|
|||||||
defaultSaveAsPath string
|
defaultSaveAsPath string
|
||||||
recentVaultsPath string
|
recentVaultsPath string
|
||||||
editingEntry bool
|
editingEntry bool
|
||||||
|
groupControlsHidden bool
|
||||||
recentVaults []string
|
recentVaults []string
|
||||||
recentVaultGroups map[string][]string
|
recentVaultGroups map[string][]string
|
||||||
deleteGroupPath []string
|
deleteGroupPath []string
|
||||||
@@ -280,6 +284,8 @@ func newUIWithState(mode string, sess appstate.CurrentSession, paths statePaths)
|
|||||||
u.eyeIcon, _ = widget.NewIcon(icons.ActionVisibility)
|
u.eyeIcon, _ = widget.NewIcon(icons.ActionVisibility)
|
||||||
u.eyeOffIcon, _ = widget.NewIcon(icons.ActionVisibilityOff)
|
u.eyeOffIcon, _ = widget.NewIcon(icons.ActionVisibilityOff)
|
||||||
u.copyIcon, _ = widget.NewIcon(icons.ContentContentCopy)
|
u.copyIcon, _ = widget.NewIcon(icons.ContentContentCopy)
|
||||||
|
u.expandMoreIcon, _ = widget.NewIcon(icons.NavigationExpandMore)
|
||||||
|
u.expandLessIcon, _ = widget.NewIcon(icons.NavigationExpandLess)
|
||||||
u.passwordProfile.SetText("strong")
|
u.passwordProfile.SetText("strong")
|
||||||
u.keyboardFocus = focusSearch
|
u.keyboardFocus = focusSearch
|
||||||
u.setCustomFieldRows(nil)
|
u.setCustomFieldRows(nil)
|
||||||
@@ -1173,6 +1179,9 @@ func (u *ui) layout(gtx layout.Context) layout.Dimensions {
|
|||||||
u.clearDeleteGroupConfirmation()
|
u.clearDeleteGroupConfirmation()
|
||||||
u.runAction("create group", u.createGroupAction)
|
u.runAction("create group", u.createGroupAction)
|
||||||
}
|
}
|
||||||
|
for u.toggleGroupControls.Clicked(gtx) {
|
||||||
|
u.groupControlsHidden = !u.groupControlsHidden
|
||||||
|
}
|
||||||
for u.renameGroup.Clicked(gtx) {
|
for u.renameGroup.Clicked(gtx) {
|
||||||
u.clearDeleteGroupConfirmation()
|
u.clearDeleteGroupConfirmation()
|
||||||
u.runAction("rename group", u.renameGroupAction)
|
u.runAction("rename group", u.renameGroupAction)
|
||||||
@@ -1358,7 +1367,7 @@ func (u *ui) listPanel(gtx layout.Context) layout.Dimensions {
|
|||||||
if u.isVaultLocked() {
|
if u.isVaultLocked() {
|
||||||
return layout.Dimensions{}
|
return layout.Dimensions{}
|
||||||
}
|
}
|
||||||
return u.groupControls(gtx)
|
return u.groupControlsSection(gtx)
|
||||||
}),
|
}),
|
||||||
layout.Rigid(layout.Spacer{Height: spacing}.Layout),
|
layout.Rigid(layout.Spacer{Height: spacing}.Layout),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
|||||||
@@ -787,6 +787,27 @@ func TestUIGroupManagementAndPathNavigationAreControllerDriven(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUIGroupControlsCanBeCollapsed(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
u := newUIWithModel("desktop", vault.Model{})
|
||||||
|
u.showEntriesSection()
|
||||||
|
|
||||||
|
if u.groupControlsHidden {
|
||||||
|
t.Fatal("groupControlsHidden = true, want false by default")
|
||||||
|
}
|
||||||
|
|
||||||
|
u.groupControlsHidden = true
|
||||||
|
if !u.groupControlsHidden {
|
||||||
|
t.Fatal("groupControlsHidden = false, want true after collapsing")
|
||||||
|
}
|
||||||
|
|
||||||
|
u.groupControlsHidden = false
|
||||||
|
if u.groupControlsHidden {
|
||||||
|
t.Fatal("groupControlsHidden = true, want false after expanding")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUISavingEntryWithDifferentPathMovesItBetweenGroups(t *testing.T) {
|
func TestUISavingEntryWithDifferentPathMovesItBetweenGroups(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
+48
@@ -256,6 +256,54 @@ func (u *ui) groupControls(gtx layout.Context) layout.Dimensions {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ui) groupControlsSection(gtx layout.Context) layout.Dimensions {
|
||||||
|
if u.state.Section != appstate.SectionEntries {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.groupControlsDisclosure(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
if u.groupControlsHidden {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
||||||
|
layout.Rigid(u.groupControls),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) groupControlsDisclosure(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.toggleGroupControls.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return layout.Flex{Alignment: layout.Middle}.Layout(gtx,
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
icon := u.expandLessIcon
|
||||||
|
if u.groupControlsHidden {
|
||||||
|
icon = u.expandMoreIcon
|
||||||
|
}
|
||||||
|
if icon == nil {
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(16), ">")
|
||||||
|
if !u.groupControlsHidden {
|
||||||
|
lbl.Text = "v"
|
||||||
|
}
|
||||||
|
lbl.Color = accentColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
|
}
|
||||||
|
return icon.Layout(gtx, accentColor)
|
||||||
|
}),
|
||||||
|
layout.Rigid(layout.Spacer{Width: unit.Dp(4)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(13), "Group Tools")
|
||||||
|
lbl.Color = accentColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (u *ui) entryEditorPanel(gtx layout.Context) layout.Dimensions {
|
func (u *ui) entryEditorPanel(gtx layout.Context) layout.Dimensions {
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
layout.Rigid(labeledEditorWithFocus(u.theme, "Title", &u.entryTitle, false, u.isFocused(detailFocusID(detailFieldTitle)))),
|
layout.Rigid(labeledEditorWithFocus(u.theme, "Title", &u.entryTitle, false, u.isFocused(detailFocusID(detailFieldTitle)))),
|
||||||
|
|||||||
Reference in New Issue
Block a user