From 8c7aed3263d1a42083529f7b65797bb903399ceb Mon Sep 17 00:00:00 2001 From: Raxel Gutierrez Date: Mon, 23 Aug 2021 18:28:32 +0000 Subject: [PATCH] views: Style modification forms as an action bar Add styling to the new patch list html code to make the change property and bundle action forms more usable. Before [1] and after [2] images for reference. [1] https://i.imgur.com/Pzelipp.png [2] https://i.imgur.com/UtNJXuf.png Signed-off-by: Raxel Gutierrez Signed-off-by: Stephen Finucane [stephenfin: Addressed merge conflicts, tweak CSS slightly] --- htdocs/css/style.css | 73 ++++++++++++++++++++++++++++++++++++-------- patchwork/forms.py | 42 ++++++++++++++++++++----- 2 files changed, 94 insertions(+), 21 deletions(-) diff --git a/htdocs/css/style.css b/htdocs/css/style.css index 57c52e05..268a8c37 100644 --- a/htdocs/css/style.css +++ b/htdocs/css/style.css @@ -174,10 +174,6 @@ a.col-inactive:hover { div.filters { } -div.patch-forms { - margin-top: 1em; -} - /* list order manipulation */ table.patch-list tr.draghover { @@ -201,7 +197,7 @@ input#reorder-change { .paginator { text-align: right; clear: both; - margin: 8px 0 15px; + margin: 16px 0; } .paginator .prev-na, @@ -433,13 +429,62 @@ table.bundlelist td padding-right: 2em; } +.patch-list-actions { + width: 100%; + display: inline-flex; + flex-wrap: wrap; + justify-content: space-between; +} + /* forms that appear for a patch */ +.patch-forms { + display: inline-flex; + flex-wrap: wrap; + margin: 16px 0; +} + div.patch-form { - border: thin solid #080808; - padding-left: 0.6em; - padding-right: 0.6em; - float: left; - margin: 0.5em 5em 0.5em 10px; + display: flex; + flex-wrap: wrap; + align-items: center; +} + +select[class^=change-property-], .archive-patch-select, .add-bundle { + padding: 4px; + margin-right: 8px; + box-sizing: border-box; + border-radius: 4px; + background-color: var(--light-color); +} + +#patch-form-archive { + display: flex; + align-items: center; + margin-right: 4px; +} + +#patch-form-archive > label { + margin: 0px; +} + +#patch-form-archive > select, #patch-form-archive > input { + margin: 0px 4px 0px 4px; +} + +.patch-form-submit { + font-weight: bold; + padding: 4px; +} + +#patch-form-bundle, #add-to-bundle, #remove-bundle { + margin-left: 16px; +} + +.create-bundle { + padding: 4px; + margin-right: 8px; + box-sizing: border-box; + border-radius: 4px; } div.patch-form h3 { @@ -458,15 +503,17 @@ div.patch-form ul { margin-top: 0em; } -/* forms */ -table.form { +.create-bundle { + padding: 4px; + margin-right: 8px; + box-sizing: border-box; + border-radius: 4px; } span.help_text { font-size: 80%; } - table.form td { padding: 0.6em; vertical-align: top; diff --git a/patchwork/forms.py b/patchwork/forms.py index 59e82ba0..cf77bdcc 100644 --- a/patchwork/forms.py +++ b/patchwork/forms.py @@ -66,6 +66,9 @@ class BundleForm(forms.ModelForm): max_length=50, required=False, error_messages={'invalid': "Bundle names can't contain slashes"}, + widget=forms.TextInput( + attrs={'class': 'create-bundle', 'placeholder': 'Bundle name'} + ), ) class Meta: @@ -136,19 +139,29 @@ class PatchForm(forms.ModelForm): def __init__(self, instance=None, project=None, *args, **kwargs): super(PatchForm, self).__init__(instance=instance, *args, **kwargs) self.fields['delegate'] = forms.ModelChoiceField( - queryset=_get_delegate_qs(project, instance), required=False + queryset=_get_delegate_qs(project, instance), + widget=forms.Select(attrs={'class': 'change-property-delegate'}), + required=False, ) class Meta: model = Patch fields = ['state', 'archived', 'delegate'] + widgets = { + 'state': forms.Select(attrs={'class': 'change-property-state'}), + 'archived': forms.CheckboxInput( + attrs={'class': 'archive-patch-check'} + ), + } class OptionalModelChoiceField(forms.ModelChoiceField): - no_change_choice = ('*', 'no change') + no_change_choice = ('*', 'No change') to_field_name = None - def __init__(self, *args, **kwargs): + def __init__(self, *args, placeholder, className, **kwargs): + self.no_change_choice = ('*', placeholder) + self.widget = forms.Select(attrs={'class': className}) super(OptionalModelChoiceField, self).__init__( initial=self.no_change_choice[0], *args, **kwargs ) @@ -181,6 +194,10 @@ def clean(self, value): class OptionalBooleanField(forms.TypedChoiceField): + def __init__(self, className, *args, **kwargs): + self.widget = forms.Select(attrs={'class': className}) + super(OptionalBooleanField, self).__init__(*args, **kwargs) + def is_no_change(self, value): return value == self.empty_value @@ -188,22 +205,31 @@ def is_no_change(self, value): class MultiplePatchForm(forms.Form): action = 'update' archived = OptionalBooleanField( + className='archive-patch-select', choices=[ - ('*', 'no change'), - ('True', 'Archived'), - ('False', 'Unarchived'), + ('*', 'No change'), + ('True', 'Archive'), + ('False', 'Unarchive'), ], coerce=lambda x: x == 'True', empty_value='*', + label='Archived', ) def __init__(self, project, *args, **kwargs): super(MultiplePatchForm, self).__init__(*args, **kwargs) self.fields['delegate'] = OptionalModelChoiceField( - queryset=_get_delegate_qs(project=project), required=False + queryset=_get_delegate_qs(project=project), + placeholder='Delegate to', + className='change-property-delegate', + label='Delegate to', + required=False, ) self.fields['state'] = OptionalModelChoiceField( - queryset=State.objects.all() + queryset=State.objects.all(), + placeholder='Change state', + className='change-property-state', + label='Change state', ) def save(self, instance, commit=True):