Projet

Général

Profil

0001-manager-add-help-on-users-imports.patch

Benjamin Dauvergne, 23 juin 2019 13:49

Télécharger (9,29 ko)

Voir les différences:

Subject: [PATCH] manager: add help on users imports

 src/authentic2/attribute_kinds.py             |   1 +
 .../static/authentic2/manager/css/style.css   |   8 +
 .../authentic2/manager/user_imports.html      | 157 +++++++++++++++---
 src/authentic2/manager/user_views.py          |  30 ++++
 4 files changed, 173 insertions(+), 23 deletions(-)
src/authentic2/attribute_kinds.py
244 244
        },
245 245
        'html_value': profile_image_html_value,
246 246
        'attributes_ng_serialize': profile_attributes_ng_serialize,
247
        'csv_importable': False,
247 248
    },
248 249
]
249 250

  
src/authentic2/manager/static/authentic2/manager/css/style.css
52 52
.email, #user-table .first_name, #user-table .last_name, #user-table .ou {
53 53
        text-align: left;
54 54
}
55
table.main.left {
56
	padding-left: 1rem;
57
}
58
table.main.left td,
59
table.main.left th {
60
	text-align: left;
61
}
62

  
55 63
table.feeds td.url {
56 64
	text-align: left;
57 65
	padding-left: 1em;
src/authentic2/manager/templates/authentic2/manager/user_imports.html
21 21
{% endblock %}
22 22

  
23 23
{% block content %}
24
  <h3>{% trans "Imports" %}</h3>
25
  <table class="main">
26
    <thead>
27
      <tr>
28
        <td>{% trans "Filename" %}</td>
29
        <td>{% trans "Creation date" %}</td>
30
        <td>{% trans "By" %}</td>
31
        <td>{% trans "Rows" %}</td>
32
        <td></td>
33
      </tr>
34
    </thead>
35
    <tbody>
36
      {% for import in imports %}
37
        <tr>
38
          <td><a href="{% url "a2-manager-users-import" uuid=import.uuid %}">{{ import.filename }}</a></td>
39
          <td>{{ import.created }}</td>
40
          <td>{{ import.user }}</td>
41
          <td>{{ import.rows_count }}</td>
42
          <td><form method="post">{% csrf_token %}<button name="delete" value="{{ import.uuid }}">{% trans "Delete" %}</button></form></td>
43
        </tr>
44
      {% endfor %}
45
    </tbody>
46
  </table>
24

  
25
  <div class="section">
26
    <h3>{% trans "Imports" %}</h3>
27
    <table class="main left">
28
      <thead>
29
        <tr>
30
          <th>{% trans "Filename" %}</th>
31
          <th>{% trans "Creation date" %}</th>
32
          <th>{% trans "By" %}</th>
33
          <th>{% trans "Rows" %}</th>
34
          <th></th>
35
        </tr>
36
      </thead>
37
      <tbody>
38
        {% for import in imports %}
39
          <tr>
40
            <td><a href="{% url "a2-manager-users-import" uuid=import.uuid %}">{{ import.filename }}</a></td>
41
            <td>{{ import.created }}</td>
42
            <td>{{ import.user }}</td>
43
            <td>{{ import.rows_count }}</td>
44
            <td><form method="post">{% csrf_token %}<button name="delete" value="{{ import.uuid }}">{% trans "Delete" %}</button></form></td>
45
          </tr>
46
        {% endfor %}
47
      </tbody>
48
    </table>
49
  </div>
50

  
51
  <div class="section">
52
    <h3>{% trans "Help" %}</h3>
53
    <p>
54
      {% blocktrans trimmed %}
55
        You can use the following columns in your CSV import file.
56
      {% endblocktrans %}
57
    <p>
58
    <h4>{% trans "Columns" %}</h4>
59
    <table class="main left">
60
      <thead>
61
        <tr>
62
          <th>{% trans "Label" %}</th>
63
          <th>{% trans "Identifier" %}</th>
64
        </tr>
65
      </thead>
66
      <tbody>
67
        {% for column in help_columns %}
68
          <tr>
69
            <td>{{ column.label }}</td>
70
            <td>{{ column.name }}</td>
71
          </tr>
72
        {% endfor %}
73
      </tbody>
74
    </table>
75
    <h4>{% trans "Flags" %}</h4>
76
    <p>{% blocktrans trimmed %}Each column can receive flags after its name, separated by spaces. Each modifier can be prefixed by <tt>no-</tt> to set its value to false.{% endblocktrans %}</p>
77
    <table class="main left">
78
      <thead>
79
        <tr>
80
          <th>{% trans "Flag" %}</th>
81
          <th>{% trans "Meaning" %}</th>
82
          <th>{% trans "Default" %}</th>
83
        </tr>
84
      </thead>
85
      <tbody>
86
        <tr>
87
          <td>key</td>
88
          <td>
89
            {% blocktrans trimmed %}
90
            The column is an import key, it is used to match the row with an existing user. Only one column can be an import key.
91
            {% endblocktrans %}
92
          </td>
93
          <td>{% trans "False" %}</td>
94
        </tr>
95
        <tr>
96
          <td>create</td>
97
          <td>
98
            {% blocktrans trimmed %}
99
            Values will be used when creating a new user.
100
            {% endblocktrans %}
101
          </td>
102
          <td>{% trans "True" %}</td>
103
        </tr>
104
        <tr>
105
          <td>update</td>
106
          <td>
107
            {% blocktrans trimmed %}
108
            Values will be used when updating an existing user.
109
            {% endblocktrans %}
110
          </td>
111
          <td>{% trans "True" %}</td>
112
        </tr>
113
        <tr>
114
          <td>unique</td>
115
          <td>
116
            {% blocktrans trimmed %}
117
            Values must be unique in the target organizational unit.
118
            {% endblocktrans %}
119
          </td>
120
          <td>{% trans "True" %}</td>
121
        </tr>
122
        <tr>
123
          <td>globally-unique</td>
124
          <td>
125
            {% blocktrans trimmed %}
126
            Values must be unique among all users.
127
            {% endblocktrans %}
128
          </td>
129
          <td>{% trans "True" %}</td>
130
        </tr>
131
        <tr>
132
          <td>verified</td>
133
          <td>
134
            {% blocktrans trimmed %}
135
            Values are verified.
136
            {% endblocktrans %}
137
          </td>
138
          <td>{% trans "False" %} {% blocktrans %}(default is True for the <tt>email</tt> column){% endblocktrans %}</td>
139
        </tr>
140
      </tbody>
141
    </table>
142

  
143
    <h4>{% trans "External identifier" %}</h4>
144
    <p>
145
      {% blocktrans trimmed %}
146
        You can also use two special columns <tt>_source_name</tt> and
147
        <tt>_source_id</tt>. <tt>_source_name</tt> must be the name of the
148
        source directory from which the users are exported, it must not
149
        change between imports. <tt>_source_id</tt> is the unique identifier
150
        from the source directory from which the users are extracted, it must
151
        not change between imports and should never be reused for different
152
        users. <tt>_source_id</tt> is automatically the key column, and you
153
        cannot use another key column.
154
      {% endblocktrans %}
155
    </p>
156
  </div>
157

  
47 158
{% endblock %}
src/authentic2/manager/user_views.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import base64
17 18
import datetime
18 19
import collections
19 20
import operator
......
52 53
from .utils import get_ou_count, has_show_username
53 54
from . import app_settings
54 55

  
56
User = get_user_model()
57

  
55 58

  
56 59
class UsersView(HideOUColumnMixin, BaseTableView):
57 60
    template_name = 'authentic2/manager/users.html'
......
659 662

  
660 663
        ctx = super(UserImportsView, self).get_context_data(**kwargs)
661 664
        ctx['imports'] = sorted(user_import.UserImport.all(), key=operator.attrgetter('created'), reverse=True)
665
        help_columns = []
666
        field_columns = ['username', 'email', 'first_name', 'last_name']
667
        if not has_show_username:
668
            field_columns.remove('username')
669
        for field_column in field_columns:
670
            field = User._meta.get_field(field_column)
671
            help_columns.append({
672
                'label': field.verbose_name,
673
                'name': field.name
674
            })
675
        for attribute in Attribute.objects.all():
676
            kind = attribute.get_kind()
677
            if not kind.get('csv_importable', True):
678
                continue
679
            help_columns.append({
680
                'label': attribute.label,
681
                'name': attribute.name,
682
            })
683
        ctx['help_columns'] = help_columns
684
        example_data = u','.join(column['name'] for column in help_columns) + '\n'
685
        example_url = 'data:text/csv;base64,%s' % base64.b64encode(example_data.encode('utf-8'))
686
        ctx['form'].fields['import_file'].help_text = format_html(
687
            _('{0}. {1} <a download="{3}" href="{2}">{3}</a>'),
688
            ctx['form'].fields['import_file'].help_text,
689
            _('ex.:'),
690
            example_url,
691
            _('users.csv'))
662 692
        return ctx
663 693

  
664 694
user_imports = UserImportsView.as_view()
665
-