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 +5 -2
- accrete/contrib/sequence/queries.py +2 -2
- accrete/contrib/ui/response.py +16 -2
- accrete/contrib/ui/static/css/accrete.css +10 -11
- accrete/contrib/ui/static/css/accrete.css.map +1 -1
- accrete/contrib/ui/static/css/accrete.scss +12 -12
- accrete/contrib/ui/templates/ui/layout.html +4 -4
- accrete/contrib/ui/templates/ui/list.html +1 -1
- accrete/contrib/ui/templates/ui/modal.html +1 -1
- accrete/contrib/ui/templates/ui/oob.html +2 -2
- accrete/contrib/ui/templates/ui/table.html +15 -14
- accrete/contrib/ui/templates/ui/templatetags/tenant_quick_switch.html +2 -2
- accrete/contrib/ui/templates/ui/widgets/model_search_select.html +4 -6
- accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html +8 -6
- accrete/contrib/ui/templatetags/ui.py +22 -3
- accrete/contrib/ui/widgets/search_select.py +0 -6
- accrete/contrib/user/templates/user/accrete_navbar_end_dropdown.html +1 -1
- accrete/managers.py +1 -1
- accrete/middleware.py +8 -3
- accrete/models.py +2 -2
- {accrete-0.0.158.dist-info → accrete-0.0.160.dist-info}/METADATA +1 -1
- {accrete-0.0.158.dist-info → accrete-0.0.160.dist-info}/RECORD +24 -24
- {accrete-0.0.158.dist-info → accrete-0.0.160.dist-info}/WHEEL +0 -0
- {accrete-0.0.158.dist-info → accrete-0.0.160.dist-info}/licenses/LICENSE +0 -0
accrete/consumer.py
CHANGED
|
@@ -14,5 +14,8 @@ class WebsocketTenantConsumer(WebsocketConsumer):
|
|
|
14
14
|
|
|
15
15
|
class JsonWebsocketTenantConsumer(JsonWebsocketConsumer):
|
|
16
16
|
|
|
17
|
-
|
|
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
|
-
|
|
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,
|
|
18
|
+
seq = Sequence(name=name, tenant_id=tenant.pk)
|
|
19
19
|
seq.save()
|
|
20
20
|
|
|
21
21
|
nextval = seq.nextval
|
accrete/contrib/ui/response.py
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
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": "AAAQ,uCAA4B;AAEpC,KAAM;EACJ,iBAAiB,CAAC,KAAK;EACvB,qBAAqB,CAAC,KAAK;EAC3B,4BAA4B,CAAC,uBAAuB;EACpD,sBAAsB,CAAC,KAAK;EAC5B,iBAAiB,CAAC,UAAU;EAC5B,iBAAiB,CAAC,OAAO;EACzB,iBAAiB,CAAC,OAAO;EACzB,
|
|
3
|
+
"mappings": "AAAQ,uCAA4B;AAEpC,KAAM;EACJ,iBAAiB,CAAC,KAAK;EACvB,qBAAqB,CAAC,KAAK;EAC3B,4BAA4B,CAAC,uBAAuB;EACpD,sBAAsB,CAAC,KAAK;EAC5B,4BAA4B,CAAC,KAAK;EAClC,iBAAiB,CAAC,UAAU;EAC5B,iBAAiB,CAAC,OAAO;EACzB,iBAAiB,CAAC,OAAO;EACzB,mBAAmB,CAAC,qBAAqB;EACzC,mBAAmB,CAAC,qBAAqB;EACzC,qBAAqB,CAAC,QAAQ;;AAKhC,uBAAwB;EACtB,qBAAqB,CAAC,QAAQ;EAE9B,wCAAiB;IACf,gBAAgB,CAAC,oBAAoB;IACrC,gBAAgB,CAAC,oBAAoB;IACrC,gBAAgB,CAAC,oBAAoB;IACrC,2BAA2B,CAAC,oBAAoB;IAChD,uBAAuB,CAAC,oBAAoB;IAC5C,2BAA2B,CAAC,IAAI;IAChC,sBAAsB,CAAC,2BAA2B;IAClD,6BAA6B,CAAC,EAAE;EAGlC,kDAA2B;IACzB,2BAA2B,CAAC,oBAAoB;IAChD,sBAAsB,CAAC,kCAAkC;EAG3D,+CAAwB;IACtB,2BAA2B,CAAC,0BAA0B;;AAI1D,SAAU;EACR,OAAO,EAAE,eAAe;;AAG1B,CAAE;EACA,KAAK,EAAE,OAAO;EACd,eAAe,EAAE,OAAO;;AAG1B,MAAO;EACL,WAAW,EAAE,MAAM;;AAIrB,cAAe;EACb,KAAK,EAAE,KAAK;;AAGd,OAAQ;EACN,UAAU,EAAE,IAAI;;AAGlB,iBAAkB;EAChB,UAAU,EAAE,IAAI;EAChB,gBAAgB,EAAE,WAAW;EAC7B,kBAAkB,EAAE,WAAW;EAC/B,mBAAmB,EAAE,WAAW;EAChC,iBAAiB,EAAE,WAAW;;AAGhC,4BAA6B;EAC3B,gBAAgB,EAAE,oBAAoB;EACtC,KAAK,EAAE,yCAAyC;;AAGlD,iCAAkC;EAChC,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,8BAA8B;;AAGxC,eAAgB;EACd,MAAM,EAAE,kBAAkB;;AAG5B,2BAA4B;EAC1B,WAAW,EAAE,iBAAiB;;AAGhC,gBAAiB;EACf,MAAM,EAAE,kBAAkB;;AAG5B,QAAS;EACL,UAAU,EAAE,eAAc;;AAG9B,cAAe;EACX,YAAY,EAAE,+BAA+B;;AAGjD,mCAAoC;EAClC,aAAa,EAAE,CAAC;EAChB,SAAS,EAAE,uBAAuB;;AAGpC,mDAAoD;EAClD,aAAa,EAAE,CAAC;;AAGlB,MAAO;EACH,UAAU,EAAE,eAAe;;AAG/B,YAAa;EACX,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,yCAAwC;;AAGlD,iBAAkB;EAChB,WAAW,EAAE,CAAC;EACd,KAAK,EAAE,2BAA2B;EAClC,sBAAsB,EAAE,0BAA0B;EAClD,yBAAyB,EAAE,0BAA0B;EACrD,UAAU,EAAE,qCAAqC;EACjD,OAAO,EAAE,EAAE;;AAGb,mBAAoB;EAClB,OAAO,EAAE,IAAI;;AAGf,mBAAoB;EAClB,cAAc,EAAE,kBAAkB;EAClC,cAAc,EAAE,WAAW;;AAG7B,eAAe;EACX,UAAU,EAAE,qBAAqB;;AAGrC,sBAAuB;EACnB,cAAc,EAAE,IAAI;;AAGxB,mCAAoC;EAChC,cAAc,EAAE,IAAI;;AAGxB,iBAAkB;EAChB,QAAQ,EAAE,KAAK;EACf,UAAU,EAAE,qBAAqB;EACjC,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,IAAI;;AAGf,8BAA+B;EAC7B,OAAO,EAAE,GAAG;EACZ,gBAAgB,EAAE,KAAK;EACvB,mBAAmB,EAAE,OAAO;;AAG9B,6BAA8B;EAC5B,QAAQ,EAAE,KAAK;EACf,GAAG,EAAE,GAAG;EACR,WAAW,EAAE,EAAE;EACf,SAAS,EAAE,sCAAsC;;AAGnD,uCAAwC;EACtC,UAAU,EAAE,gCAAgC;;AAG9C,SAAU;EACR,UAAU,EAAE,iBAAiB;EAC7B,SAAS,EAAE,eAAe;EAC1B,aAAa,EAAE,YAAY;EAC3B,KAAK,EAAE,iBAAiB;EACxB,WAAW,EAAE,0BAA0B;EACvC,WAAW,EAAE,IAAI;;AAGnB,UAAW;EACP,YAAY,EAAE,MAAM;EACpB,aAAa,EAAE,MAAM;;AAGzB,gDAyCC;EAxCC,sBAAuB;IACrB,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,eAAe;IAC3B,MAAM,EAAE,sBAAsB;IAC9B,SAAS,EAAE,GAAG;IACd,YAAY,EAAE,eAAe;;EAG/B,sBAAuB;IACrB,OAAO,EAAE,YAAY;IACrB,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,GAAG;IAChB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,iCACjB;;EAEA,kCAAmC;IACjC,UAAU,EAAE,iCAAiC;;EAG/C,iCAAkC;IAChC,gBAAgB,EAAE,oBAAoB;;EAGxC,uCAAwC;IACtC,gBAAgB,EAAE,+BAA8B;;EAGlD,yBAA0B;IACxB,OAAO,EAAE,IAAI;;EAGf,mBAAoB;IAClB,OAAO,EAAE,YAAY;;EAGvB,WAAY;IACV,MAAM,EAAE,sBAAqB;AAIjC,oCAAqC;EACnC,WAAY;IACV,SAAS,EAAE,IAAI;AAInB,oCAAqC;EACnC,iBAAkB;IAChB,SAAS,EAAE,CAAC;IACZ,WAAW,EAAE,CAAC;IACd,KAAK,EAAE,IAAI;IACX,sBAAsB,EAAE,CAAC;IACzB,yBAAyB,EAAE,CAAC;;EAG9B,wBAAyB;IACvB,KAAK,EAAE,IAAI;;EAGb,WAAY;IACV,KAAK,EAAE,eAAc;IACrB,UAAU,EAAE,MAAM;AAItB,aAAc;EACZ,SAAS,EAAE,iCAAiC;EAC5C,SAAS,EAAE,iCAAiC;EAC5C,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,IAAI;;AAGlB,qCAAsC;EACpC,aAAc;IACZ,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,wBAAwB;IACpC,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,oCAAoC;AAIpD,kBAAmB;EACf,gBAAgB,EAAE,0BAA0B;;AAGhD,iCAAiC;AACjC;gCACiC;EAC/B,kBAAkB,EAAE,IAAI;EACxB,MAAM,EAAE,CAAC;;AAGX,aAAa;AACb,kBAAmB;EACjB,eAAe,EAAE,SAAS;;AAG5B,uEAAwE;EACtE,OAAO,EAAE,IAAI;;AAGf,6EAA8E;EAC5E,OAAO,EAAE,eAAc;;AAGzB,kEAAmE;EACjE,OAAO,EAAE,IAAI;;AAGf,wEAAyE;EACvE,OAAO,EAAE,eAAc;;AAGzB,YAAa;EACX,YAAY,EAAE,GAAG;EACjB,WAAW,EAAE,iCAAiC;EAC9C,UAAU,EAAE,IAAI;EAChB,YAAY,EAAE,IAAI;EAClB,aAAa,EAAE,IAAI;EACnB,aAAa,EAAE,CAAC;EAChB,aAAa,EAAE,GAAG;;AAGpB,mDAAoD;EAClD,YAAY,EAAE,CAAC;EACf,WAAW,EAAE,eAAc;;AAG7B,iBAAkB;EAChB,YAAY,EAAE,MAAM;EACpB,aAAa,EAAE,MAAM;EACrB,WAAW,EAAE,MAAM",
|
|
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:
|
|
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
|
-
|
|
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.
|
|
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
|
>
|
|
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-
|
|
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-
|
|
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-
|
|
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' }}
|
|
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
|
|
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
|
|
16
|
+
{% for row_object in page.object_list %}
|
|
17
17
|
{% partialdef tr inline=True %}
|
|
18
|
-
<tr id="tr-{{
|
|
19
|
-
{% if
|
|
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="{{
|
|
22
|
-
hx-replace-url="{% querystring detail=
|
|
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>{{
|
|
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: {{
|
|
30
|
+
<td style="text-align: {{ row_object|table_alignment:field }}">
|
|
31
31
|
<span>
|
|
32
|
-
<span class="responsive-heading has-text-weight-
|
|
33
|
-
{{
|
|
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
|
|
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
|
-
|
|
23
|
-
|
|
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;
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
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.
|
|
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
|
|
63
|
-
if
|
|
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.
|
|
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.
|
|
41
|
+
self.tenant_id = tenant.pk
|
|
42
42
|
super().save(
|
|
43
43
|
force_insert=force_insert,
|
|
44
44
|
force_update=force_update,
|
|
@@ -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=
|
|
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=
|
|
11
|
-
accrete/middleware.py,sha256=
|
|
12
|
-
accrete/models.py,sha256=
|
|
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=
|
|
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=
|
|
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
|
|
182
|
-
accrete/contrib/ui/static/css/accrete.css.map,sha256=
|
|
183
|
-
accrete/contrib/ui/static/css/accrete.scss,sha256=
|
|
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=
|
|
218
|
-
accrete/contrib/ui/templates/ui/list.html,sha256=
|
|
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=
|
|
222
|
-
accrete/contrib/ui/templates/ui/oob.html,sha256=
|
|
223
|
-
accrete/contrib/ui/templates/ui/table.html,sha256=
|
|
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=
|
|
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=
|
|
234
|
-
accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
302
|
-
accrete-0.0.
|
|
303
|
-
accrete-0.0.
|
|
304
|
-
accrete-0.0.
|
|
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,,
|
|
File without changes
|
|
File without changes
|