accrete 0.0.158__py3-none-any.whl → 0.0.160__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
accrete/consumer.py CHANGED
@@ -14,5 +14,8 @@ class WebsocketTenantConsumer(WebsocketConsumer):
14
14
 
15
15
  class JsonWebsocketTenantConsumer(JsonWebsocketConsumer):
16
16
 
17
- pass
18
-
17
+ def websocket_connect(self, message):
18
+ tenant = get_tenant()
19
+ if tenant is None:
20
+ raise ValueError('Tenant must be set.')
21
+ super().websocket_connect(message)
@@ -9,13 +9,13 @@ def get_nextval(name: str, create_if_none:bool = True) -> int:
9
9
  tenant = get_tenant()
10
10
  with transaction.atomic():
11
11
  seq = Sequence.objects.filter(
12
- tenant=tenant, name=name
12
+ tenant_id=tenant.pk, name=name
13
13
  ).select_for_update().first()
14
14
 
15
15
  if seq is None and not create_if_none:
16
16
  raise ValueError(f'Sequence "{name}" does not exist.')
17
17
  elif seq is None:
18
- seq = Sequence(name=name, tenant=tenant)
18
+ seq = Sequence(name=name, tenant_id=tenant.pk)
19
19
  seq.save()
20
20
 
21
21
  nextval = seq.nextval
@@ -58,18 +58,20 @@ class OobResponse(Response):
58
58
 
59
59
  oob_template = 'ui/oob.html'
60
60
 
61
- def __init__(self, *, template: str, context: dict, swap: str, tag: str = 'div'):
61
+ def __init__(self, *, template: str, context: dict, swap: str, tag: str = 'div', attrs: dict = None):
62
62
  super().__init__(template=self.oob_template, context=context)
63
63
  self.include_template = template
64
64
  self.swap = swap
65
65
  self.tag = tag
66
+ self.attrs = attrs or {}
66
67
 
67
68
  def get_context(self):
68
69
  context = super().get_context()
69
70
  context.update({'oob': {
70
71
  'template': self.include_template,
71
72
  'swap': self.swap,
72
- 'tag': self.tag
73
+ 'tag': self.tag,
74
+ 'attrs': self.attrs
73
75
  }})
74
76
  return context
75
77
 
@@ -207,6 +209,7 @@ class ListEntryResponse(Response):
207
209
  ):
208
210
  super().__init__(template=self.base_template, context=context or {})
209
211
  self.instance = instance
212
+ self.instance.refresh_from_db()
210
213
  self.list_entry_template = list_entry_template
211
214
  self.page = page
212
215
  self.is_new = is_new
@@ -244,6 +247,7 @@ class TableResponse(WindowResponse):
244
247
  context: dict,
245
248
  fields: list[str],
246
249
  instance_label: str | Promise | None = None,
250
+ active_instance: Model = None,
247
251
  footer: dict = None,
248
252
  page: paginator.Page = None,
249
253
  ui_filter: Filter = None,
@@ -253,6 +257,8 @@ class TableResponse(WindowResponse):
253
257
  overview_template: str = 'ui/table.html',
254
258
  detail_header_template: str = None,
255
259
  detail_data_template: str = None,
260
+ detail_enabled: bool = True,
261
+ can_compact: bool = True,
256
262
  config: WindowResponseConfig = None
257
263
  ):
258
264
  assert page is not None or ui_filter is not None, _(
@@ -267,6 +273,7 @@ class TableResponse(WindowResponse):
267
273
  config=config
268
274
  )
269
275
  self.instance_label = instance_label
276
+ self.active_instance = active_instance
270
277
  self.fields = fields
271
278
  self.footer = footer
272
279
  self.page = page or (ui_filter and ui_filter.get_page())
@@ -274,6 +281,8 @@ class TableResponse(WindowResponse):
274
281
  self.endless_scroll = endless_scroll
275
282
  self.detail_header_template = detail_header_template
276
283
  self.detail_data_template = detail_data_template
284
+ self.detail_enabled = detail_enabled
285
+ self.can_compact = can_compact
277
286
 
278
287
  def _has_panel(self):
279
288
  return bool(self.panel_template or self.ui_filter)
@@ -286,9 +295,12 @@ class TableResponse(WindowResponse):
286
295
  'endless_scroll': self.endless_scroll,
287
296
  'fields': self.fields,
288
297
  'instance_label': self.instance_label,
298
+ 'active_instance': self.active_instance,
289
299
  'footer': self.footer,
290
300
  'detail_header_template': self.detail_header_template,
291
301
  'detail_data_template': self.detail_data_template,
302
+ 'detail_enabled': self.detail_enabled,
303
+ 'can_compact': self.can_compact,
292
304
  'show_content_right': str(bool(
293
305
  self.detail_header_template or self.detail_data_template
294
306
  )).lower()
@@ -313,6 +325,7 @@ class TableRowResponse(Response):
313
325
  ):
314
326
  super().__init__(template=self.base_template, context={})
315
327
  self.instance = instance
328
+ self.instance.refresh_from_db()
316
329
  self.fields = fields
317
330
  self.instance_label = instance_label
318
331
  self.footer = footer
@@ -322,6 +335,7 @@ class TableRowResponse(Response):
322
335
  context = super().get_context()
323
336
  context.update({
324
337
  'instance': self.instance,
338
+ 'row_object': self.instance,
325
339
  'fields': self.fields,
326
340
  'instance_label': self.instance_label,
327
341
  'footer': self.footer,
@@ -3,11 +3,11 @@
3
3
  --bulma-body-size: .9em;
4
4
  --bulma-navbar-height: 40px;
5
5
  --bulma-menu-item-selected-h: var(--bulma-primary-h);
6
- --accrete-detail-width: 40em;
6
+ --accrete-detail-width: 38em;
7
+ --accrete-action-panel-width: 20em;
7
8
  --bulma-primary-h: 153.28deg;
8
9
  --bulma-primary-s: 52.89%;
9
10
  --bulma-primary-l: 52.55%;
10
- --accrete-action-panel-width: 320px;
11
11
  --bulma-input-arrow: var(--bulma-primary);
12
12
  --bulma-arrow-color: var(--bulma-primary);
13
13
  --accrete-hover-color: #F0F2F4; }
@@ -52,17 +52,23 @@ a {
52
52
  border-bottom-color: transparent;
53
53
  border-left-color: transparent; }
54
54
 
55
+ .button.is-static.is-primary {
56
+ background-color: var(--bulma-primary);
57
+ color: var(--bulma-button-disabled-border-color); }
58
+
55
59
  .input:focus, .input:focus-within {
56
60
  box-shadow: none;
57
61
  border: 1px solid var(--bulma-primary); }
58
62
 
59
63
  input[disabled] {
60
- background-color: transparent !important;
61
- cursor: unset !important; }
64
+ cursor: default !important; }
62
65
 
63
66
  input[disabled] ~ .helptext {
64
67
  font-weight: normal !important; }
65
68
 
69
+ select[disabled] {
70
+ cursor: default !important; }
71
+
66
72
  textarea {
67
73
  box-shadow: none !important; }
68
74
 
@@ -202,13 +208,6 @@ select:focus {
202
208
  background: var(--bulma-scheme-main);
203
209
  z-index: 40;
204
210
  box-shadow: 2px 0 20px 0 var(--bulma-grey-light); } }
205
- .menu-list a.is-active, .menu-list a.is-selected, .menu-list button.is-active, .menu-list button.is-selected, .menu-list .menu-item.is-active, .menu-list .menu-item.is-selected {
206
- --bulma-menu-item-h: var(--bulma-primary-h);
207
- --bulma-menu-item-s: var(--bulma-primary-s);
208
- --bulma-menu-item-l: var(--bulma-primary-l);
209
- --bulma-menu-item-background-l: var(--bulma-primary-l);
210
- --bulma-menu-item-color-l: var(--bulma-primary-invert-l); }
211
-
212
211
  .hoverable *:hover {
213
212
  background-color: var(--accrete-hover-color); }
214
213
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "mappings": "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",
3
+ "mappings": "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",
4
4
  "sources": ["accrete.scss"],
5
5
  "names": [],
6
6
  "file": "accrete.css"
@@ -4,11 +4,11 @@
4
4
  --bulma-body-size: .9em;
5
5
  --bulma-navbar-height: 40px;
6
6
  --bulma-menu-item-selected-h: var(--bulma-primary-h);
7
- --accrete-detail-width: 40em;
7
+ --accrete-detail-width: 38em;
8
+ --accrete-action-panel-width: 20em;
8
9
  --bulma-primary-h: 153.28deg;
9
10
  --bulma-primary-s: 52.89%;
10
11
  --bulma-primary-l: 52.55%;
11
- --accrete-action-panel-width: 320px;
12
12
  --bulma-input-arrow: var(--bulma-primary);
13
13
  --bulma-arrow-color: var(--bulma-primary);
14
14
  --accrete-hover-color: #F0F2F4;
@@ -70,20 +70,28 @@ a {
70
70
  border-left-color: transparent;
71
71
  }
72
72
 
73
+ .button.is-static.is-primary {
74
+ background-color: var(--bulma-primary);
75
+ color: var(--bulma-button-disabled-border-color);
76
+ }
77
+
73
78
  .input:focus, .input:focus-within {
74
79
  box-shadow: none;
75
80
  border: 1px solid var(--bulma-primary);
76
81
  }
77
82
 
78
83
  input[disabled] {
79
- background-color: transparent !important;
80
- cursor: unset !important;
84
+ cursor: default !important;
81
85
  }
82
86
 
83
87
  input[disabled] ~ .helptext {
84
88
  font-weight: normal !important;
85
89
  }
86
90
 
91
+ select[disabled] {
92
+ cursor: default !important;
93
+ }
94
+
87
95
  textarea {
88
96
  box-shadow: none!important;
89
97
  }
@@ -263,14 +271,6 @@ select:focus {
263
271
  }
264
272
  }
265
273
 
266
- .menu-list a.is-active, .menu-list a.is-selected, .menu-list button.is-active, .menu-list button.is-selected, .menu-list .menu-item.is-active, .menu-list .menu-item.is-selected {
267
- --bulma-menu-item-h: var(--bulma-primary-h);
268
- --bulma-menu-item-s: var(--bulma-primary-s);
269
- --bulma-menu-item-l: var(--bulma-primary-l);
270
- --bulma-menu-item-background-l: var(--bulma-primary-l);
271
- --bulma-menu-item-color-l: var(--bulma-primary-invert-l);
272
- }
273
-
274
274
  .hoverable *:hover {
275
275
  background-color: var(--accrete-hover-color);
276
276
  }
@@ -11,7 +11,7 @@
11
11
  <meta charset="utf-8">
12
12
  <meta name="viewport" content="width=device-width, initial-scale=1">
13
13
  {% include 'ui/favicon.html' %}
14
- <link rel="stylesheet" type="text/css" href="{% static "css/accrete.css" %}?v=0.0.154">
14
+ <link rel="stylesheet" type="text/css" href="{% static "css/accrete.css" %}?v=0.0.159">
15
15
  <link rel="stylesheet" type="text/css" href="{% static "css/icons.css" %}">
16
16
  <link rel="stylesheet" type="text/css" href="{% static "css/fa.css" %}">
17
17
  {% if style_template %}{% include style_template %}{% endif %}
@@ -166,7 +166,7 @@
166
166
  {% if config.display_header %}
167
167
  <div id="overview-header">
168
168
  <div class="is-flex is-justify-content-space-between is-flex-wrap-wrap {% if is_centered %}container{% endif %}">
169
- <div class="is-flex is-flex-wrap-wrap is-flex-grow-5 is-align-self-center py-2 mx-1 header-items">
169
+ <div id="overview-header-items" class="is-flex is-flex-wrap-wrap is-flex-grow-5 is-align-self-center py-2 mx-1 header-items">
170
170
  {% block overview_header %}
171
171
  <div class="" style="align-self: center">
172
172
  <p class="title is-5">{{ title }}</p>
@@ -199,7 +199,7 @@
199
199
  <button id="pagination-next-button" class="button"
200
200
  hx-get="{% if page.has_next %}{% querystring page=page.next_page_number %}{% else %}{% querystring page=1 %}{% endif %}"
201
201
  hx-replace-url="true"
202
- hx-select-oob="#overview,#pagination,#overview-buttons"
202
+ hx-select-oob="#overview-header-items,#overview,#pagination,#overview-buttons"
203
203
  >
204
204
  &gt;
205
205
  </button>
@@ -221,7 +221,7 @@
221
221
  x-transition:enter.duration.200ms x-transition:leave.duration.50ms
222
222
  >
223
223
  <div id="detail-indicator" class="htmx-indicator">
224
- <progress class="progress is-success" max="100"></progress>
224
+ <progress class="progress is-primary" max="100"></progress>
225
225
  </div>
226
226
  <div class="is-flex is-flex-direction-column" style="height: 100%">
227
227
  <div class="is-flex is-flex-wrap-nowrap is-justify-content-space-between m-2">
@@ -38,7 +38,7 @@
38
38
  hx-swap="beforeend"
39
39
  hx-replace-url="true"
40
40
  hx-indicator="#endless-scroll-indicator"></div>
41
- <progress id="endless-scroll-indicator" class="htmx-indicator progress is-small is-success" max="100">15%</progress>
41
+ <progress id="endless-scroll-indicator" class="htmx-indicator progress is-small is-primary" max="100">15%</progress>
42
42
  {% endif %}
43
43
  </div>
44
44
  {% endblock %}
@@ -41,7 +41,7 @@
41
41
  {% endblock %}
42
42
  </footer>
43
43
  <div id="{{ modal_id }}-indicator" x-ref="{{ modal_id|xrefsave }}Indicator" class="htmx-indicator modal-request-overlay" style="position: absolute; inset: 0; background: rgba(47, 47, 62, 0.2)">
44
- <progress class="progress is-success" max="100" style="position: absolute; inset: 0; min-width: 300px; max-width: 20vw; margin: auto;"></progress>
44
+ <progress class="progress is-primary" max="100" style="position: absolute; inset: 0; min-width: 300px; max-width: 20vw; margin: auto;"></progress>
45
45
  </div>
46
46
  </div>
47
47
  </div>
@@ -1,3 +1,3 @@
1
- <{{ oob.tag|default_if_none:'div' }} {% if oob.id %}id="{{ oob.id }}"{% endif %} hx-swap-oob="{{ oob.swap|default_if_none:'true' }}" {% if oob.select %}hx-select-oob="{{ oob.select }}"{% endif %}>
1
+ <{{ oob.tag|default_if_none:'div' }} hx-swap-oob="{{ oob.swap|default_if_none:'true' }}" {% for k, v in oob.attrs.items %}{{ k }}="{{ v }}"{% endfor %}>
2
2
  {% include oob.template %}
3
- </{{ oob.tag|default_if_none:'div' }}>
3
+ </{{ oob.tag|default_if_none:'div' }}>
@@ -3,7 +3,7 @@
3
3
  {% load partials %}
4
4
 
5
5
  {% block table %}
6
- <table id="content-table" class="table can-compact is-fullwidth is-hoverable is-narrow my-0" hx-indicator=".htmx-indicator" x-data="">
6
+ <table id="content-table" class="table is-fullwidth is-hoverable is-narrow my-0 {% if can_compact %}can-compact{% endif %}" style="{% if not can_compact %}white-space: nowrap{% endif %}" hx-indicator=".htmx-indicator" x-data="">
7
7
  <thead style="position: sticky; top: 0; z-index: 10; background-color: var(--bulma-scheme-main)">
8
8
  <tr>
9
9
  {% if instance_label %}<th>{{ instance_label }}</th>{% endif %}
@@ -13,24 +13,24 @@
13
13
  </tr>
14
14
  </thead>
15
15
  <tbody id="content-table-body" style="z-index: 9" x-ref="tbody">
16
- {% for instance in page.object_list %}
16
+ {% for row_object in page.object_list %}
17
17
  {% partialdef tr inline=True %}
18
- <tr id="tr-{{ instance.pk }}"
19
- {% if instance.get_absolute_url %}
18
+ <tr id="tr-{{ row_object.pk }}"
19
+ {% if row_object.get_absolute_url and detail_enabled %}
20
20
  style="cursor: pointer;"
21
- hx-get="{{ instance.get_absolute_url }}{% querystring %}" hx-swap="none"
22
- hx-replace-url="{% querystring detail=instance.pk %}"
23
- x-data="{selected: false}" @unselect-tr.window="selected = false"
21
+ hx-get="{{ row_object.get_absolute_url }}{% querystring %}" hx-swap="none"
22
+ hx-replace-url="{% querystring detail=row_object.pk %}"
23
+ x-data="{selected: {% if row_object == active_instance %}true{% else %}false{% endif %}}" @unselect-tr.window="selected = false"
24
24
  x-on:click="$dispatch('unselect-tr'); selected = true; $nextTick(() => { $el.scrollIntoView( {block: 'nearest'} ) });" x-bind:class="selected ? 'is-primary' : ''"
25
25
  {% endif %}
26
26
  >
27
27
  {% partialdef td inline=True %}
28
- {% if instance_label %}<td>{{ instance }}</td>{% endif %}
28
+ {% if instance_label %}<td><span class="has-text-weight-bold">{{ row_object }}</span></td>{% endif %}
29
29
  {% for field in fields %}
30
- <td style="text-align: {{ instance|table_alignment:field }}">
30
+ <td style="text-align: {{ row_object|table_alignment:field }}">
31
31
  <span>
32
- <span class="responsive-heading has-text-weight-light" style="margin-right: .2rem">{{ instance|verbose_field_name:field }}:</span>
33
- {{ instance|table_display:field|default_if_none:'' }}
32
+ {% if can_compact %}<span class="responsive-heading has-text-weight-medium mr-2" style="margin-right: .2rem">{{ row_object|verbose_field_name:field }}:</span>{% endif %}
33
+ <span>{{ row_object|table_display:field|default_if_none:'' }}</span>
34
34
  </span>
35
35
  </td>
36
36
  {% endfor %}
@@ -59,19 +59,20 @@
59
59
  </tr>
60
60
  </tfoot>
61
61
  </table>
62
-
62
+ {% if endless_scroll %}
63
63
  <div id="endless-scroller"
64
64
  {% if page.has_next %}
65
65
  hx-get="{% querystring page=page.next_page_number %}"
66
66
  hx-trigger="intersect once"
67
- hx-select="tbody > tr"
67
+ hx-select="#content-table > tbody > tr"
68
68
  hx-target="#content-table-body"
69
69
  hx-swap="beforeend"
70
- hx-select-oob="#pagination-next-button,#pagination-end-index,#endless-scroller"
70
+ hx-select-oob="#overview-header-items,#pagination-next-button,#pagination-end-index,#endless-scroller"
71
71
  hx-indicator="#endless-scroll-indicator"
72
72
  hx-replace-url="true"
73
73
  {% endif %}
74
74
  >
75
75
  </div>
76
76
  <progress id="endless-scroll-indicator" class="htmx-indicator progress is-small is-primary" max="100">15%</progress>
77
+ {% endif %}
77
78
  {% endblock %}
@@ -5,9 +5,9 @@
5
5
  <article class="box p-1" style="position: fixed; top: var(--bulma-navbar-height); left: 0; min-width: 150px; border-top-left-radius: 0; border-top-right-radius: 0;"
6
6
  x-show="showQuickSwitch" x-cloak="" x-on:click.outside="showQuickSwitch = false"
7
7
  >
8
- <ul class="hoverable mr-1">
8
+ <ul class="hoverable">
9
9
  {% for t in tenants %}
10
- <li class="navbar-item" style="cursor: pointer; border-radius: var(--bulma-radius);"><a href="{{ switch_url }}?tenant_id={{ t.pk }}" hx-boost="false" style="width: 100%; display: inline-block">{{ t.name }}</a></li>
10
+ <li class="navbar-item has-text-weight-medium" style="cursor: pointer; border-radius: var(--bulma-radius); color: unset;"><a href="{{ switch_url }}?tenant_id={{ t.pk }}" hx-boost="false" style="width: 100%; display: inline-block">{{ t.name }}</a></li>
11
11
  {% endfor %}
12
12
  </ul>
13
13
  </article>
@@ -18,13 +18,11 @@
18
18
  <div style="position: relative; top: .5rem; z-index: 90;">
19
19
  <div x-show="open" x-effect="if (open) {$nextTick(() => { $refs.dropdownContent.scrollIntoView(true) });}" x-cloak="" class="box pt-3 px-3 mb-2" x-ref="dropdownContent" tabindex="-1" x-transition style="position: absolute; width: 100%">
20
20
  <input id="id_{{ widget.name }}_search" type="search" autocomplete="off" class="input my-2" x-ref="searchInput" aria-label="search"
21
- name="{{ widget.search_parameter }}"
22
- placeholder="{% translate 'Type to search' %}"
23
- hx-get="{{ widget.search_url }}"
24
- hx-trigger="input changed delay:500ms, search"
25
- hx-target="#{{ widget.name }}_dropdown_items"
21
+ name="{{ widget.search_parameter }}" placeholder="{% translate 'Type to search' %}" hx-get="{{ widget.search_url }}"
22
+ hx-trigger="input changed delay:500ms, search" hx-target="#{{ widget.name }}_dropdown_items"
23
+ style="border-radius: 0; border-top: none; border-right: none; border-left: none"
26
24
  >
27
- <div x-on:click="$refs.inputValue.setAttribute('value', $event.target.value); $refs.inputDisplay.value = $event.target.innerText; htmx.trigger($refs.inputValue, 'submit'); open = false; {% if widget.hx_trigger_on_change %}htmx.trigger('#id_{{ widget.name }}_value', 'change');{% endif %}"
25
+ <div x-on:click="$refs.inputValue.setAttribute('value', $event.target.value); $refs.inputDisplay.value = $event.target.innerText; htmx.trigger($refs.inputValue, 'submit'); open = false; htmx.trigger('#id_{{ widget.name }}_value', 'change');"
28
26
  x-on:keydown="if (![9, 27, 38, 40].includes($event.keyCode)) {$refs.searchInput.focus();}"
29
27
  @keyup.escape="if (open) {$event.stopPropagation();} open = false;"
30
28
  >
@@ -1,7 +1,7 @@
1
1
  {% load i18n %}
2
2
  {% load ui %}
3
3
 
4
- <div class="is-fullwidth" x-data="{open: false}"
4
+ <div class="is-fullwidth" x-data="{open: false, changed: false}"
5
5
  @click.outside="open = false" hx-disinherit="*" @keyup.escape="if (open) {$event.stopPropagation();} open = false;"
6
6
  x-on:keydown="if (!open && [38, 40].includes($event.keyCode)) {open = true};"
7
7
  >
@@ -21,7 +21,10 @@
21
21
  let val = $event.target.getAttribute('data-value');
22
22
  $refs.inputValue.querySelector(`option[value=${CSS.escape(val)}]`).remove();
23
23
  $event.target.parentElement.remove();
24
- $dispatch('change');
24
+ changed = true;
25
+ if (!open) {
26
+ htmx.trigger('#{{ widget.attrs.id }}', 'change');
27
+ }
25
28
  }
26
29
  "
27
30
  >
@@ -34,7 +37,7 @@
34
37
  </div>
35
38
  </div>
36
39
  <div style="position: relative; top: .5rem; z-index: 9">
37
- <div x-show="open" x-effect="if (open) {$nextTick(() => { $refs.dropdownContent.scrollIntoView(true) });}" class="box pt-3 px-3 mb-2" x-ref="dropdownContent" x-cloak="" tabindex="-1" x-transition style="position: absolute; width: 100%">
40
+ <div x-show="open" x-effect="if (open) {$nextTick(() => { $refs.dropdownContent.scrollIntoView(true) });} if(!open & changed) {htmx.trigger('#{{ widget.attrs.id }}', 'change');}" class="box pt-3 px-3 mb-2" x-ref="dropdownContent" x-cloak="" tabindex="-1" x-transition style="position: absolute; width: 100%">
38
41
  <input id="id_{{ widget.uuid }}_search" type="search" autocomplete="off" class="input mb-2" x-ref="searchInput" aria-label="search"
39
42
  name="{{ widget.search_parameter }}"
40
43
  placeholder="{% translate 'Type to search' %}"
@@ -42,7 +45,7 @@
42
45
  hx-trigger="input changed delay:300ms, search"
43
46
  hx-target="#id_{{ widget.uuid }}_dropdown_items"
44
47
  hx-swap="innerHTML"
45
- style="border-radius: var(--bulma-radius)"
48
+ style="border-radius: 0; border-top: none; border-right: none; border-left: none"
46
49
  x-on:keydown="if (![9, 27, 38, 40].includes($event.keyCode)) {$refs.searchInput.focus();}"
47
50
  @change.stop=""
48
51
  >
@@ -63,10 +66,9 @@
63
66
  tag.appendChild(delButton);
64
67
  $refs.inputValue.appendChild(option);
65
68
  $refs.inputDisplayTags.appendChild(tag);
66
- $dispatch('change');
69
+ changed = true;
67
70
  }
68
71
  $refs.inputDisplay.focus();
69
- {% if widget.hx_trigger_on_change %}htmx.trigger('#{{ widget.attrs.id }}_value', 'change');{% endif %}
70
72
  "
71
73
  x-on:keydown="
72
74
  if ($event.keyCode == 27) {$event.stopPropagation; document.activeElement.blur()}
@@ -7,7 +7,8 @@ from django.shortcuts import resolve_url
7
7
  from django.utils.translation import gettext_lazy as _
8
8
  from django import template
9
9
  from django.db.models import (
10
- Manager, DecimalField, IntegerField, FloatField, Model, Q
10
+ Manager, DecimalField, IntegerField, FloatField, Model,
11
+ ManyToManyRel, ManyToManyField
11
12
  )
12
13
  from django.apps import apps
13
14
  from django.template.loader import render_to_string
@@ -62,6 +63,8 @@ def get_attr_from_string(param: object, value: str):
62
63
  except (AttributeError,):
63
64
  _logger.warning(f'Object {param} has no attribute {value}')
64
65
  attribute = None
66
+ if attribute and callable(attribute):
67
+ attribute = attribute()
65
68
  return return_save(attribute)
66
69
 
67
70
 
@@ -85,9 +88,18 @@ def verbose_field_name(param: object, value: str):
85
88
  if not param:
86
89
  return ''
87
90
  if isinstance(param, Model):
88
- name = param._meta.get_field(value).verbose_name
91
+ field = param._meta.get_field(value)
92
+ if isinstance(field, ManyToManyRel):
93
+ name = field.related_model._meta.verbose_name_plural
94
+ else:
95
+ name = param._meta.get_field(value).verbose_name
89
96
  else:
90
- name = getattr(param.model, value).field.verbose_name
97
+ field = getattr(param.model, value).field
98
+ if isinstance(field, ManyToManyField):
99
+ name = field.model._meta.verbose_name_plural
100
+ else:
101
+ name = getattr(param.model, value).field.verbose_name
102
+
91
103
  return name
92
104
 
93
105
 
@@ -102,6 +114,13 @@ def table_display(param: object, value: str):
102
114
  </div>
103
115
  </span>
104
116
  """)
117
+ try:
118
+ has_choices = param._meta.get_field(value).choices
119
+ except Exception as e:
120
+ _logger.error(repr(e))
121
+ has_choices = False
122
+ if has_choices:
123
+ value = f'get_{value}_display'
105
124
  return get_attr_from_string(param, value)
106
125
 
107
126
 
@@ -14,7 +14,6 @@ class ModelSearchSelect(widgets.NumberInput):
14
14
  search_kwargs: dict = None,
15
15
  search_parameter: str = 'search',
16
16
  limit: int | None = 5,
17
- hx_trigger_on_change: bool = False,
18
17
  choices=()
19
18
  ):
20
19
  super().__init__()
@@ -22,7 +21,6 @@ class ModelSearchSelect(widgets.NumberInput):
22
21
  self.search_kwargs = search_kwargs or {}
23
22
  self.search_parameter = search_parameter
24
23
  self.limit = limit
25
- self.hx_trigger_on_change = hx_trigger_on_change # trigger htmx request on change
26
24
  self.choices = choices
27
25
 
28
26
  def get_context(self, name, value, attrs):
@@ -42,7 +40,6 @@ class ModelSearchSelect(widgets.NumberInput):
42
40
  "template_name": self.template_name,
43
41
  'search_url': resolve_url(self.search_url, **self.search_kwargs),
44
42
  'search_parameter': self.search_parameter,
45
- 'hx_trigger_on_change': self.hx_trigger_on_change,
46
43
  'uuid': uuid
47
44
  },
48
45
  'options': qs
@@ -74,7 +71,6 @@ class ModelSearchSelectMulti(widgets.SelectMultiple):
74
71
  search_kwargs: dict = None,
75
72
  search_parameter: str = 'search',
76
73
  limit: int | None = 5,
77
- hx_trigger_on_change: bool = False,
78
74
  choices=()
79
75
  ):
80
76
  super().__init__()
@@ -82,7 +78,6 @@ class ModelSearchSelectMulti(widgets.SelectMultiple):
82
78
  self.search_kwargs = search_kwargs or {}
83
79
  self.search_parameter = search_parameter
84
80
  self.limit = limit
85
- self.hx_trigger_on_change = hx_trigger_on_change # trigger 'change' event on the actual input field
86
81
  self.choices = choices
87
82
 
88
83
  def get_context(self, name, value, attrs):
@@ -101,7 +96,6 @@ class ModelSearchSelectMulti(widgets.SelectMultiple):
101
96
  "template_name": self.template_name,
102
97
  'search_url': resolve_url(self.search_url, **self.search_kwargs),
103
98
  'search_parameter': self.search_parameter,
104
- 'hx_trigger_on_change': self.hx_trigger_on_change,
105
99
  'uuid': uuid
106
100
  },
107
101
  'options': qs,
@@ -1,6 +1,6 @@
1
1
  {% load i18n %}
2
2
 
3
- <a class="navbar-item" href="{% url 'user:detail' %}" hx-boost="false">{% translate 'Preferences' %}</a>
3
+ <a class="navbar-item" href="{% url 'user:detail' %}?tenant_id={{ request.tenant.pk }}" hx-boost="false">{% translate 'Preferences' %}</a>
4
4
  {% if request.user.is_staff %}
5
5
  <a class="navbar-item" hx-boost="false" href="/admin/">Admin</a>
6
6
  {% endif %}
accrete/managers.py CHANGED
@@ -8,7 +8,7 @@ class TenantManager(models.Manager):
8
8
  queryset = super().get_queryset()
9
9
  tenant = get_tenant()
10
10
  if tenant:
11
- queryset = queryset.filter(tenant=tenant)
11
+ queryset = queryset.filter(tenant_id=tenant.pk)
12
12
  return queryset
13
13
 
14
14
  def bulk_create(
accrete/middleware.py CHANGED
@@ -45,7 +45,7 @@ class TenantMiddleware(MiddlewareMixin):
45
45
  request.member = memberships.first()
46
46
  request.tenant = request.member.tenant
47
47
  set_member(request.member)
48
- self.update_post_data(request)
48
+ self.update_request_data(request)
49
49
  return
50
50
  if membership_count > 1:
51
51
  set_member(None)
@@ -54,13 +54,18 @@ class TenantMiddleware(MiddlewareMixin):
54
54
  set_member(None)
55
55
  set_tenant(tenant)
56
56
  request.tenant = tenant
57
+ self.update_request_data(request)
57
58
  return
58
59
  set_member(None)
59
60
  return
60
61
 
61
62
  @staticmethod
62
- def update_post_data(request):
63
- if request.POST and not request.POST.get('tenant') and request.tenant:
63
+ def update_request_data(request):
64
+ if not request.tenant:
65
+ return
66
+ request.GET = request.GET.copy()
67
+ request.GET['tenant_id'] = request.tenant.pk
68
+ if request.POST and not request.POST.get('tenant'):
64
69
  request.POST = request.POST.copy()
65
70
  request.POST['tenant'] = request.tenant.pk
66
71
 
accrete/models.py CHANGED
@@ -29,7 +29,7 @@ class TenantModel(models.Model):
29
29
  update_fields=None
30
30
  ):
31
31
  tenant = get_tenant()
32
- if self.pk and tenant and self.tenant != tenant:
32
+ if self.pk and tenant and self.tenant_id != tenant.pk:
33
33
  raise ValueError('Current tenant differs from tenant of the record!')
34
34
  if self.pk and not self.tenant and not tenant:
35
35
  raise ValueError(
@@ -38,7 +38,7 @@ class TenantModel(models.Model):
38
38
  'or set the tenant explicitly on the instance.'
39
39
  )
40
40
  if tenant:
41
- self.tenant = tenant
41
+ self.tenant_id = tenant.pk
42
42
  super().save(
43
43
  force_insert=force_insert,
44
44
  force_update=force_update,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: accrete
3
- Version: 0.0.158
3
+ Version: 0.0.160
4
4
  Summary: Django Shared Schema Multi Tenant
5
5
  Author-email: Benedikt Jilek <benedikt.jilek@pm.me>
6
6
  License: Copyright (c) 2025 Benedikt Jilek
@@ -3,13 +3,13 @@ accrete/admin.py,sha256=sK7jzjVTdAPim3TnOluRdorRZYVt2Rv8vx7Bw7dix-I,1308
3
3
  accrete/apps.py,sha256=F7ynMLHJr_6bRujWtZVUzCliY2CGKiDvyUmL4F68L2E,146
4
4
  accrete/channels.py,sha256=GCatQ4JM0Ailophvuf02xjfdhS4z5U90l4BoSCDKLIs,1291
5
5
  accrete/config.py,sha256=1Yubvz5PVdCsX0tA7HvazhtnvCvgCoEl33_dR8SHpb8,392
6
- accrete/consumer.py,sha256=Vnxete60NfUxogyBiI3kwULbSyeEOF93JYvq6L_cgEg,441
6
+ accrete/consumer.py,sha256=jFO0fZWaMzvUBtz_Qu4G6ShYzV93cDNEEpTI15RxVCo,625
7
7
  accrete/context_processors.py,sha256=DySglwyD2TwPsxhElVkYDvyBBUJabEKGMiKCLe0KN4Q,148
8
8
  accrete/fields.py,sha256=6eH1ipmdqxpCRhDcAkfICffWkM0WkzWIADTsD2SXCm0,5149
9
9
  accrete/forms.py,sha256=H2hPQemslRLvTVV0Wl1TfUmTc5wU3Z98nQTMiLMliqo,1288
10
- accrete/managers.py,sha256=p5HGN2EPjIeI9R263kKprDZcBd3IMMKT8Jfq8w2CB7g,1846
11
- accrete/middleware.py,sha256=CaqGfDLUd1hvOtx1XJlR6M5sgSYgl2sTPbBivvXw0aM,2306
12
- accrete/models.py,sha256=24NxD9kvgu1PrwuxdWFRT-29X11BLY8IxcFLHn57MLk,5755
10
+ accrete/managers.py,sha256=Wk-zgqiL4orFi_sN_93E24FM9HLuEHchFbTAWp4qvkg,1852
11
+ accrete/middleware.py,sha256=f67dLonBSoM0JDAECVjWWlhStLJjM9W983Z-mEakbsU,2483
12
+ accrete/models.py,sha256=VYCvDVW38sJj0vvZlnWw5SjcJ6dSWNHDAH3ldN1l_ws,5767
13
13
  accrete/storage.py,sha256=Jp3oE_uPMqgarjS_G49KDFrR2eSe4XuIJK9oAF_QBxk,1288
14
14
  accrete/tenant.py,sha256=2H38-M9xBkChWpZ3swjQ08StCmZp5DNDmm19jHVDDSY,2290
15
15
  accrete/tests.py,sha256=Agltbzwwh5htvq_Qi9vqvxutzmg_GwgPS_N19xJZRlw,7197
@@ -47,7 +47,7 @@ accrete/contrib/sequence/admin.py,sha256=mTjab5cVklRUIQcSrsUo-_JgtXEsSdcFj_gfWhl
47
47
  accrete/contrib/sequence/apps.py,sha256=2SalOz9piCrbOPudCh0grN1eojN9kEC4-jcNzBmfqEk,164
48
48
  accrete/contrib/sequence/forms.py,sha256=cdjLIytH7WlJK-B2Y6xRRPjOijkK36XpqUuIe4yLLj0,248
49
49
  accrete/contrib/sequence/models.py,sha256=UEuPvg1StovPW1n9yF-f31nBq4aTj5zpfS10oqcf60E,887
50
- accrete/contrib/sequence/queries.py,sha256=6BI2VGerXkeblZleII8Z2hsLOgzlSguvPGa3VNUSTC4,702
50
+ accrete/contrib/sequence/queries.py,sha256=oA53itK4HmLaQKja1kYXO6acmBYnTwQOTjb8RH7-CAw,714
51
51
  accrete/contrib/sequence/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
52
52
  accrete/contrib/sequence/views.py,sha256=xc1IQHrsij7j33TUbo-_oewy3vs03pw_etpBWaMYJl0,63
53
53
  accrete/contrib/sequence/migrations/0001_initial.py,sha256=iAR_hhGN2wDAk40IS9PwEsm7iYqfgasoKRrTLFEpOY8,1352
@@ -72,7 +72,7 @@ accrete/contrib/ui/filter.py,sha256=MZfy6p4Q6TVvtjl5nF7_6CemOe1twbk0Bj5LWptjcwM,
72
72
  accrete/contrib/ui/forms.py,sha256=Ul3daXNwWLN1G3ppwOvNztrilIAGeLwNY1a-g-njrjQ,2049
73
73
  accrete/contrib/ui/middleware.py,sha256=fVjKeDXnGiJw7NRYZK3nCkj7g-MAainiBl-VhpE3XdQ,1792
74
74
  accrete/contrib/ui/models.py,sha256=ikwd7vHuq0R_qcr_gczcHHRvkXwr-zJMrfrriIUJD7U,3426
75
- accrete/contrib/ui/response.py,sha256=q6V6vSHbioUYbkIUtYbRidmbryTE84Qb9Nu4oZetwJ8,14809
75
+ accrete/contrib/ui/response.py,sha256=bP8hfx5VftGLVx0afIYyJ6oqSUV61kjCnEwiuhK9Go4,15406
76
76
  accrete/contrib/ui/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
77
77
  accrete/contrib/ui/urls.py,sha256=5XUfK85HYWYf7oopMoJEEYmQ6pNgHgZBErBEn97pBt4,337
78
78
  accrete/contrib/ui/views.py,sha256=foVB7rx3_FWU9fkPdUKiqkVsWraAyfenC2OTNyYt7lI,4644
@@ -178,9 +178,9 @@ accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.scss,sha256=1tXoYLlK
178
178
  accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.scss,sha256=NRrD7Euz_mfDI02D92a63M6H4UhArjhWy3g5DIhQr5o,366
179
179
  accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.scss,sha256=gyRiEug6frpDJEaxZ7VybdApnmNS5R5A9Zn1R0yWLJg,335
180
180
  accrete/contrib/ui/static/bulma/versions/bulma-prefixed.scss,sha256=cDhte1VyFupdjYFXpUyQb7wGB8aUKDGYuKluZCY5CtA,133
181
- accrete/contrib/ui/static/css/accrete.css,sha256=6WhaocfxQeQktiY3nZWOTdXNMNypiJzN5DbOe7fSqMk,6743
182
- accrete/contrib/ui/static/css/accrete.css.map,sha256=oXBXlTSW-A2AG9N0WwMHFsghRlzW--p5ISNriXiD66Y,3985
183
- accrete/contrib/ui/static/css/accrete.scss,sha256=XhkFO6NjHBFY4E9IPFnwHG34s9l3hWs6R8sVGNPz2mY,6705
181
+ accrete/contrib/ui/static/css/accrete.css,sha256=-rL94s4L3ng0GUH2MAPPfom40FICCXmuN-2DIKgm-Ho,6439
182
+ accrete/contrib/ui/static/css/accrete.css.map,sha256=1H7pNeMlZIFD0QPBzht7Ty6nGlXdyCyMjFN-DsUdvt0,3919
183
+ accrete/contrib/ui/static/css/accrete.scss,sha256=xryEk4MrLDOYMFwsIDlZd1xr5AcJBkb6UVvvltjBPO8,6401
184
184
  accrete/contrib/ui/static/css/fa.css,sha256=wiz7ZSCn_btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac,102641
185
185
  accrete/contrib/ui/static/css/icons.css,sha256=5550KHsaayeEtRaUdf0h7esQhyec-_5ZfecZ_sOC6v0,6334
186
186
  accrete/contrib/ui/static/icons/Logo.svg,sha256=hGZuxrAa-LRpFavFiF8Lnc7X9OQcqmb6Xl_dxx-27hM,1861
@@ -214,13 +214,13 @@ accrete/contrib/ui/templates/ui/custom_theme.html,sha256=son43yhp-7ROTpRU9SY3pSg
214
214
  accrete/contrib/ui/templates/ui/detail.html,sha256=V0HccLE0Pb-5haQFpvIoWZfF1UOrvMwPYv2UTwRnt_A,293
215
215
  accrete/contrib/ui/templates/ui/favicon.html,sha256=ZSK6qDGV4Cexgt0VA3KOHYN100yZHOFjfOiFZVudWg0,90
216
216
  accrete/contrib/ui/templates/ui/form_error.html,sha256=xIBoM45w_KQWrLDmXh4vibXz5w2_VEYrRCFrAEqdAl0,473
217
- accrete/contrib/ui/templates/ui/layout.html,sha256=JjIDwzsJkXvq8jtgf-7ZMUv17jS_gRhIvow-LolfX3E,14988
218
- accrete/contrib/ui/templates/ui/list.html,sha256=CcVQBxRmBZWFbTI9Lq0S_myIBB-bJpIIi9dHoDUwnJ4,2388
217
+ accrete/contrib/ui/templates/ui/layout.html,sha256=TsZiSNYt0y7ELGXfM03JPqsP3zyTQ5ytFuMMbRU2VeQ,15038
218
+ accrete/contrib/ui/templates/ui/list.html,sha256=5Xg6ewNiFDH89bxxBJMxr6APy7hEj94BO2ENyocc8bs,2388
219
219
  accrete/contrib/ui/templates/ui/list_update.html,sha256=CUV-OJCieOBrtSbh0vAoyZYL-_e9lP7vQrY4j1TlT7M,276
220
220
  accrete/contrib/ui/templates/ui/message.html,sha256=H0JC3qoLO-M6vb9TcEPY-TNGHtgqcG5yOxSUP2sSb7g,824
221
- accrete/contrib/ui/templates/ui/modal.html,sha256=sJI7YwTHPvirNlig69A08z7sk_5aYRmyeAUWzm1ceVs,3464
222
- accrete/contrib/ui/templates/ui/oob.html,sha256=lZHIBBYclefbGkKguS1A7vrtOhODJizbSRaGAAHDvG8,267
223
- accrete/contrib/ui/templates/ui/table.html,sha256=ATxvStGMsc0Fz4FkUD2xZs_xhbY1-Zn1zGTrBE_w62s,3792
221
+ accrete/contrib/ui/templates/ui/modal.html,sha256=Y3m8F_oawByc7HqX-OmMnHkzrUaXQqu0MJDfjXdl9zg,3464
222
+ accrete/contrib/ui/templates/ui/oob.html,sha256=bMqcvwtiGtoP3Or_tfPDNCgUAjrReTY8j7jeyVpYMn4,222
223
+ accrete/contrib/ui/templates/ui/table.html,sha256=5IxR8Q-bdB-QhfiSW_7DG7BMU_4f0_cgu9x8h2zn314,4153
224
224
  accrete/contrib/ui/templates/ui/table_row_update.html,sha256=v3YHCzQbGbp3zC6zmJ_EvNvtgvCH_84R6gUsH5mpC0k,439
225
225
  accrete/contrib/ui/templates/ui/filter/filter.html,sha256=GOTXouHH4RSCFsIzg1UPFAcmKaNNxTPmRj5Bx9K1m4o,759
226
226
  accrete/contrib/ui/templates/ui/filter/query_input.html,sha256=OYXO0l5kVOvsnOYUsa8KaME6tC5AV8C1mJgDtW7nQHE,1975
@@ -228,16 +228,16 @@ accrete/contrib/ui/templates/ui/filter/query_operator.html,sha256=h4WWLDnse6DK5R
228
228
  accrete/contrib/ui/templates/ui/filter/query_params.html,sha256=9Kyb-dQRitjeruIEx1HJUI0elznb0KSV5fJR6keWi_4,9994
229
229
  accrete/contrib/ui/templates/ui/filter/query_tags.html,sha256=ooeIwIwvhT0fG5SMAuLoMquTVUmYf5n50DM-3gC_iAo,1567
230
230
  accrete/contrib/ui/templates/ui/templatetags/field.html,sha256=p0h2213KOx3lB3hrHvjeFC-KPE9NF81jihVKkeC83Lg,2710
231
- accrete/contrib/ui/templates/ui/templatetags/tenant_quick_switch.html,sha256=Vqp4fdv0jKp5cAP4ruH9a70BwRGSXfYu2NEotl6IJIU,828
231
+ accrete/contrib/ui/templates/ui/templatetags/tenant_quick_switch.html,sha256=1qp8Qpjb3bbRwjmlFlOrJo_xuamHFKabuHzN77DLAXw,860
232
232
  accrete/contrib/ui/templates/ui/widgets/date_weekday.html,sha256=l5k7lFJjdao49Q6oyGf20go-bXJFlidTuUVKYOuISGE,628
233
- accrete/contrib/ui/templates/ui/widgets/model_search_select.html,sha256=Pv28g0CRBTeW--v9LoP39NDDc18RGEC8Hu9MAN-Tsi0,2996
234
- accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html,sha256=stEhZXCvaj8jjRTg1chwQmyWPeseQaDrLPr257vNtGo,4697
233
+ accrete/contrib/ui/templates/ui/widgets/model_search_select.html,sha256=ERxzL7ozISlnLIEoRLXnHRoCPc-oroMl88ptprccSyA,2993
234
+ accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html,sha256=sHyv4GUyIwOLnNGI49_bkyy8ZOhU_UYDvLIItJyrE9w,4820
235
235
  accrete/contrib/ui/templates/ui/widgets/model_search_select_options.html,sha256=4Wky0XkYWZlIKXTXzGjJkJTX3H9rhjXTY1hYai3Q3TA,242
236
236
  accrete/contrib/ui/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
237
- accrete/contrib/ui/templatetags/ui.py,sha256=pgg9BRlPS0ogsFEl-4DjLhSeE3ThaRWMmbpyv9xm7sQ,7695
237
+ accrete/contrib/ui/templatetags/ui.py,sha256=_4xAE6wHaPbkrT1EuSlimtc74NJosLXO5Sed-nGXsO0,8369
238
238
  accrete/contrib/ui/widgets/__init__.py,sha256=2mcvXyFNdFkqOVHGUBDbLmbaJnWnoFaS1uc4dqmdtpE,106
239
239
  accrete/contrib/ui/widgets/date_weekday.py,sha256=r6VNE8dwGVZq4jJLGF_MP320-yp482Iykh-WsjeY9XU,148
240
- accrete/contrib/ui/widgets/search_select.py,sha256=CnWQp2JpzjNJy9arG_sFWoRvVs29x9OzdgULm7yh7d0,3745
240
+ accrete/contrib/ui/widgets/search_select.py,sha256=u3YZT-6gg_RYHdrpmFbF-bCdlW4a7-gIocl6fGcdNfU,3323
241
241
  accrete/contrib/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
242
242
  accrete/contrib/user/admin.py,sha256=0SGhVB5RcIsbCvrLf9ZSgIFH68XmGlPzovisMP8bb6c,710
243
243
  accrete/contrib/user/apps.py,sha256=oHDrAiHf-G57mZLyxqGJzRY2DbPprGFD-QgyVJG_ruI,156
@@ -262,7 +262,7 @@ accrete/contrib/user/migrations/0009_alter_user_theme.py,sha256=o5s0NCEhauE72Z35
262
262
  accrete/contrib/user/migrations/0010_alter_user_theme.py,sha256=l2raJRmLErPCBqep9-v7kor4jzmG27wAT0ZWTwkFTk0,510
263
263
  accrete/contrib/user/migrations/0011_alter_user_theme.py,sha256=LzosJbgzGRWgiYGytM220OFrLN6RS0yPdH00o8eI0B8,520
264
264
  accrete/contrib/user/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
265
- accrete/contrib/user/templates/user/accrete_navbar_end_dropdown.html,sha256=kp0_IGY3aRXktrlauruW0ciF84rpR0VzI0PUw7rzSag,351
265
+ accrete/contrib/user/templates/user/accrete_navbar_end_dropdown.html,sha256=FyQg_5ckzQAiBFUoVuYY2ZQe0TMQ7AjJmH5nVy5H7-E,385
266
266
  accrete/contrib/user/templates/user/change_email.html,sha256=frkoUCUwNtVSe9fhxmFmiM8T3RaFzLKOpAv5gZ7F-AY,473
267
267
  accrete/contrib/user/templates/user/change_password.html,sha256=e9_8pGJoEj8FqfgrC_IcDiHuP3gB9BD8ayj-BU-R8kA,538
268
268
  accrete/contrib/user/templates/user/login.html,sha256=kzdRosCXadRKdwVRulQTjtVCDx1wmp1VRNsBOKCvCs8,1986
@@ -298,7 +298,7 @@ accrete/utils/forms.py,sha256=naV4urdfvmpxcx5Vf3Fo72M5Fy8DjGg5-vkysMKptbA,3914
298
298
  accrete/utils/log.py,sha256=BH0MBDweAjx30wGBO4F3sFhbgkSoEs7T1lLLjlYZNnA,407
299
299
  accrete/utils/models.py,sha256=o_nvvwXf8L9hg_6mkFmC9ok7eFZ0auZ0kUC7Buw7du8,2205
300
300
  accrete/utils/views.py,sha256=LE9pZ1x9f7ioaPYydbrN4t1b0o6NIIq0qUjPTb1Qkbw,5022
301
- accrete-0.0.158.dist-info/METADATA,sha256=osIV2xm1eTG6dC3XwXWe5WoizG5DbJALcQBaIvPOgo8,4953
302
- accrete-0.0.158.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
303
- accrete-0.0.158.dist-info/licenses/LICENSE,sha256=vHwb4Qnv8UfYKFiCWyTuRGsi49x19UQwHRCky3b2_NE,1057
304
- accrete-0.0.158.dist-info/RECORD,,
301
+ accrete-0.0.160.dist-info/METADATA,sha256=cMcQrixi4GDZ0Eur6bZ8wske65rMAqIeKQO8he3w41k,4953
302
+ accrete-0.0.160.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
303
+ accrete-0.0.160.dist-info/licenses/LICENSE,sha256=vHwb4Qnv8UfYKFiCWyTuRGsi49x19UQwHRCky3b2_NE,1057
304
+ accrete-0.0.160.dist-info/RECORD,,