Changeset 1b51809


Ignore:
Timestamp:
Apr 10, 2012, 3:50:58 AM (14 years ago)
Author:
Alex Dehnert <adehnert@…>
Branches:
master, space-access, stable, stage
Children:
bb1a40e
Parents:
0c0dbf4
git-author:
Alex Dehnert <adehnert@…> (04/10/12 03:49:40)
git-committer:
Alex Dehnert <adehnert@…> (04/10/12 03:50:58)
Message:

Bulk add interface for OfficeHolders? (ASA Trac #90)

Location:
asadb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • asadb/groups/views.py

    r59a438a r1b51809  
    313313    return kept, kept_not
    314314
     315# Helper for manager_officers view
     316def manage_officers_table_update(
     317    group,
     318    request, context, msgs, changes,
     319    people, roles, officers_map, max_new, ):
     320
     321    context['kept'] = 0
     322    context['kept_not'] = 0
     323
     324    # Fill out moira_accounts with AthenaMoiraAccount objects for relevant people
     325    new_people, moira_accounts = manage_officers_load_accounts(max_new, people, request, msgs)
     326
     327    # Process changes
     328    for role in roles:
     329        key = "holders.%s" % (role.slug, )
     330        new_holders = set()
     331        if key in request.POST:
     332            new_holders = set(request.POST.getlist(key, ))
     333        if len(new_holders) > role.max_count:
     334            msgs.append("You selected %d people for %s; only %d are allowed. No changes to %s have been carried out in this update." %
     335                (len(new_holders), role.display_name, role.max_count, role.display_name, )
     336            )
     337        else:
     338            kept_delta, kept_not_delta = manage_officers_sync_role_people(
     339                group, role, new_holders,   # input arguments
     340                msgs, changes,              # output arguments
     341                officers_map, people, moira_accounts,   # ~background data
     342                new_people, max_new,                    # new people data
     343            )
     344            context['kept'] += kept_delta
     345            context['kept_not'] += kept_not_delta
     346
     347
     348class OfficersBulkManageForm(forms.Form):
     349    mode_choices = [
     350        ('add', 'Add new people', ),
     351        ('remove', 'Remove old people', ),
     352        ('sync', 'Set people (adding and removing as required)', ),
     353    ]
     354    mode = forms.ChoiceField(choices=mode_choices)
     355    role = forms.ChoiceField(initial='office-access', )
     356    people = forms.CharField(
     357        help_text='Usernames of people, one per line.',
     358        widget=forms.Textarea,
     359    )
     360
     361    def __init__(self, *args, **kwargs):
     362        self._roles = kwargs['roles']
     363        del kwargs['roles']
     364        super(OfficersBulkManageForm, self).__init__(*args, **kwargs)
     365        role_choices = [ (role.slug, role.display_name) for role in self._roles ]
     366        self.fields['role'].choices = role_choices
     367
     368    def get_role(self, ):
     369        role_slug = self.cleaned_data['role']
     370        for role in self._roles:
     371            if role.slug == role_slug:
     372                return role
     373        raise groups.OfficerRole.DoesNotExist
     374
     375def manage_officers_bulk_update(
     376        group, bulk_form,
     377        msgs, changes,
     378        officers_map, ):
     379
     380    # Load parameters
     381    mode = bulk_form.cleaned_data['mode']
     382    role = bulk_form.get_role()
     383    people_lst = bulk_form.cleaned_data['people'].split('\n')
     384    people_set = set([p.strip() for p in people_lst])
     385    if '' in people_set: people_set.remove('')
     386
     387    # Fill out moira_accounts
     388    moira_accounts = {}
     389    for username in people_set:
     390        try:
     391            moira_accounts[username] = groups.models.AthenaMoiraAccount.active_accounts.get(username=username)
     392        except groups.models.AthenaMoiraAccount.DoesNotExist:
     393            msgs.append('Athena account "%s" appears not to exist. Changes involving them have been ignored.' % (username, ))
     394
     395    # Find our target sets
     396    cur_holders = [user for user, map_role in officers_map if role == map_role]
     397    people = people_set.union(cur_holders)
     398    if mode == 'add':
     399        new_holders = people
     400    elif mode == 'remove':
     401        new_holders = people-people_set
     402    elif mode == 'sync':
     403        new_holders = people_set
     404    else:
     405        raise NotImplementedError("Unknown operation '%s'" % (mode, ))
     406
     407    # Make changes
     408    if len(new_holders) <= role.max_count:
     409        new_people = dict()
     410        max_new = 0
     411        manage_officers_sync_role_people(
     412            group, role, new_holders,
     413            msgs, changes,
     414            officers_map, people, moira_accounts, new_people, max_new,
     415        )
     416    else:
     417        too_many_tmpl = "You selected %d people for %s; only %d are allowed. No changes have been made in this update."
     418        error = too_many_tmpl % (len(new_holders), role.display_name, role.max_count, )
     419        msgs.append(error)
     420
    315421@login_required
    316422def manage_officers(request, pk, ):
     
    320426        raise PermissionDenied
    321427
     428    people, roles, name_map, officers_map = manage_officers_load_officers(group)
     429
    322430    max_new = 4
    323 
    324     people, roles, name_map, officers_map = manage_officers_load_officers(group)
    325 
    326431    msgs = []
    327432    changes = []
    328     edited = False
    329     kept = 0
    330     kept_not = 0
    331     if request.method == 'POST': # If the form has been submitted
     433
     434    context = {
     435        'group': group,
     436        'roles': roles,
     437        'people': people,
     438        'changes':   changes,
     439        'msgs': msgs,
     440    }
     441
     442    if request.method == 'POST' and 'opt-mode' in request.POST: # If the form has been submitted
    332443        edited = True
    333444
    334         # Fill out moira_accounts with AthenaMoiraAccount objects for relevant people
    335         new_people, moira_accounts = manage_officers_load_accounts(max_new, people, request, msgs)
    336 
    337         # Process changes
    338         for role in roles:
    339             key = "holders.%s" % (role.slug, )
    340             new_holders = set()
    341             if key in request.POST:
    342                 new_holders = set(request.POST.getlist(key, ))
    343             if len(new_holders) > role.max_count:
    344                 msgs.append("You selected %d people for %s; only %d are allowed. No changes to %s have been carried out in this update." %
    345                     (len(new_holders), role.display_name, role.max_count, role.display_name, )
    346                 )
    347             else:
    348                 kept_delta, kept_not_delta = manage_officers_sync_role_people(
    349                     group, role, new_holders,   # input arguments
    350                     msgs, changes,              # output arguments
    351                     officers_map, people, moira_accounts,   # ~background data
    352                     new_people, max_new,                    # new people data
    353                 )
    354                 kept += kept_delta
    355                 kept_not += kept_not_delta
     445        # Do the changes
     446        if request.POST['opt-mode'] == 'table':
     447            context['bulk_form'] = OfficersBulkManageForm(roles=roles, )
     448            manage_officers_table_update(
     449                group,
     450                request, context, msgs, changes,
     451                people, roles, officers_map, max_new,
     452            )
     453        elif request.POST['opt-mode'] == 'bulk':
     454            bulk_form = OfficersBulkManageForm(request.POST, roles=roles, )
     455            context['bulk_form'] = bulk_form
     456            if bulk_form.is_valid():
     457                manage_officers_bulk_update(
     458                    group, bulk_form,
     459                    msgs, changes,
     460                    officers_map, )
     461        else:
     462            raise NotImplementedError("Update mode must be table or bulk, was '%s'" % (request.POST['opt-mode'], ))
    356463
    357464        # mark as changed and reload the data
     
    360467            group.save()
    361468        people, roles, name_map, officers_map = manage_officers_load_officers(group)
     469    else:
     470        context['bulk_form'] = OfficersBulkManageForm(roles=roles, )
    362471
    363472    officers_data = []
     
    373482    for i in range(max_new):
    374483        officers_data.append((True, "extra.%d" % (i, ), "", null_role_list))
    375 
    376     context = {
    377         'group': group,
    378         'roles': roles,
    379         'people': people,
    380         'officers': officers_data,
    381         'edited': edited,
    382         'changes':   changes,
    383         'kept': kept,
    384         'kept_not': kept_not,
    385         'msgs': msgs,
    386     }
     484    context['officers'] = officers_data
     485
    387486    return render_to_response('groups/group_change_officers.html', context, context_instance=RequestContext(request), )
    388487
  • asadb/template/groups/group_change_officers.html

    r0c0dbf4 r1b51809  
    5252{% endif %}
    5353
    54 <h2>Update</h2>
     54<h2>Option 1: View and update signatories one at a time</h2>
    5555
    5656<p>Please note:</p>
     
    6262
    6363<form enctype="multipart/form-data" method="post" action="">
     64<input type='hidden' name='opt-mode' value='table' />
    6465{% csrf_token %}
    6566<table class='pretty-table group-change-officers-change'>
     
    9798{% endif %}
    9899
     100<h2>Option 2: Bulk update</h2>
     101
     102<form enctype="multipart/form-data" method="post" action="">
     103<input type='hidden' name='opt-mode' value='bulk' />
     104{% csrf_token %}
     105<table class='pretty-table'>
     106{{ bulk_form }}
     107<tr><th colspan='2'><input type='submit' value='Update' /></th></tr>
     108</table>
     109</form>
     110
    99111{% endblock %}
Note: See TracChangeset for help on using the changeset viewer.