lino 24.9.4__py3-none-any.whl → 24.10.0__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.
- lino/__init__.py +1 -5
- lino/api/doctest.py +18 -1
- lino/core/actions.py +15 -8
- lino/core/actors.py +82 -8
- lino/core/constants.py +20 -4
- lino/core/dashboard.py +1 -3
- lino/core/dbtables.py +33 -50
- lino/core/elems.py +26 -33
- lino/core/fields.py +13 -7
- lino/core/kernel.py +3 -3
- lino/core/model.py +1 -0
- lino/core/renderer.py +33 -20
- lino/core/requests.py +18 -18
- lino/core/store.py +11 -11
- lino/core/tablerequest.py +5 -5
- lino/core/tables.py +39 -25
- lino/mixins/dupable.py +1 -1
- lino/modlib/checkdata/models.py +1 -1
- lino/modlib/comments/mixins.py +2 -2
- lino/modlib/comments/ui.py +83 -77
- lino/modlib/dupable/models.py +1 -1
- lino/modlib/export_excel/models.py +0 -3
- lino/modlib/extjs/ext_renderer.py +8 -8
- lino/modlib/extjs/views.py +6 -16
- lino/modlib/help/management/commands/makehelp.py +1 -1
- lino/modlib/notify/models.py +1 -1
- lino/modlib/printing/actions.py +0 -5
- lino/modlib/publisher/ui.py +3 -3
- lino/modlib/publisher/views.py +10 -10
- lino/modlib/search/models.py +2 -2
- lino/modlib/system/mixins.py +0 -10
- lino/modlib/uploads/mixins.py +6 -3
- lino/modlib/uploads/ui.py +2 -2
- lino/modlib/users/mixins.py +5 -5
- lino/sphinxcontrib/actordoc.py +1 -1
- lino/sphinxcontrib/logo/static/linodocs.css +1 -8
- lino/utils/choosers.py +1 -1
- lino/utils/report.py +1 -1
- {lino-24.9.4.dist-info → lino-24.10.0.dist-info}/METADATA +1 -1
- {lino-24.9.4.dist-info → lino-24.10.0.dist-info}/RECORD +43 -43
- {lino-24.9.4.dist-info → lino-24.10.0.dist-info}/WHEEL +0 -0
- {lino-24.9.4.dist-info → lino-24.10.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {lino-24.9.4.dist-info → lino-24.10.0.dist-info}/licenses/COPYING +0 -0
lino/modlib/comments/ui.py
CHANGED
@@ -78,9 +78,16 @@ class CommentDetail(dd.DetailLayout):
|
|
78
78
|
class Comments(dd.Table):
|
79
79
|
required_roles = dd.login_required(CommentsUser)
|
80
80
|
model = "comments.Comment"
|
81
|
-
|
81
|
+
default_display_modes = {None: constants.DISPLAY_MODE_LIST}
|
82
|
+
# The idea is maybe good, but story mode has no insert button:
|
83
|
+
# default_display_modes = {
|
84
|
+
# 70: constants.DISPLAY_MODE_LIST,
|
85
|
+
# None: constants.DISPLAY_MODE_STORY}
|
86
|
+
extra_display_modes = {constants.DISPLAY_MODE_STORY}
|
87
|
+
# display mode "html" is not needed for comments
|
82
88
|
|
83
89
|
params_layout = "start_date end_date observed_event user reply_to"
|
90
|
+
column_names = "id modified body_short_preview owner *"
|
84
91
|
|
85
92
|
insert_layout = dd.InsertLayout(
|
86
93
|
"""
|
@@ -95,63 +102,63 @@ class Comments(dd.Table):
|
|
95
102
|
|
96
103
|
detail_layout = "comments.CommentDetail"
|
97
104
|
|
98
|
-
card_layout = dd.Panel(
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
)
|
105
|
+
# card_layout = dd.Panel(
|
106
|
+
# """
|
107
|
+
# # reply_to owner owner_type owner_id
|
108
|
+
# # comment_type
|
109
|
+
# body_short_preview
|
110
|
+
# # private
|
111
|
+
# """,
|
112
|
+
# label=_("Cards"),
|
113
|
+
# )
|
107
114
|
|
108
115
|
@classmethod
|
109
116
|
def get_simple_parameters(cls):
|
110
|
-
for p in super(
|
117
|
+
for p in super().get_simple_parameters():
|
111
118
|
yield p
|
112
119
|
yield "reply_to"
|
113
120
|
|
114
|
-
@classmethod
|
115
|
-
def get_card_title(cls, ar, obj):
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
@classmethod
|
125
|
-
def get_comment_header(cls, comment, ar):
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
121
|
+
# @classmethod
|
122
|
+
# def get_card_title(cls, ar, obj):
|
123
|
+
# """Overrides the default behaviour"""
|
124
|
+
# return cls.get_comment_header(obj, ar)
|
125
|
+
# # title = _("Created {created} by {user}").format(
|
126
|
+
# # created=naturaltime(obj.created), user=str(obj.user))
|
127
|
+
# # if cls.get_view_permission(ar.get_user().user_type):
|
128
|
+
# # title = tostring(ar.obj2html(obj, title))
|
129
|
+
# # return title
|
130
|
+
|
131
|
+
# @classmethod
|
132
|
+
# def get_comment_header(cls, comment, ar):
|
133
|
+
# if (comment.modified - comment.created).total_seconds() < 1:
|
134
|
+
# t = _("Created " + comment.created.strftime("%Y-%m-%d %H:%M"))
|
135
|
+
# else:
|
136
|
+
# t = _("Modified " + comment.modified.strftime("%Y-%m-%d %H:%M"))
|
137
|
+
# ch = ar.obj2htmls(comment, naturaltime(comment.created), title=t)
|
138
|
+
# ch += " " + _("by") + " "
|
139
|
+
# if comment.user is None:
|
140
|
+
# ch += _("system")
|
141
|
+
# else:
|
142
|
+
# ch += ar.obj2htmls(comment.user)
|
143
|
+
#
|
144
|
+
# if cls.insert_action is not None:
|
145
|
+
# sar = cls.insert_action.request_from(ar)
|
146
|
+
# # print(20170217, sar)
|
147
|
+
# sar.known_values = dict(
|
148
|
+
# reply_to=comment, **gfk2lookup(comment.__class__.owner, comment.owner)
|
149
|
+
# )
|
150
|
+
# # if ar.get_user().is_authenticated:
|
151
|
+
# if sar.get_permission():
|
152
|
+
# btn = sar.ar2button(None, _(" Reply "), icon_name=None)
|
153
|
+
# # btn.set("style", "padding-left:10px")
|
154
|
+
# ch += " [" + tostring(btn) + "]"
|
155
|
+
#
|
156
|
+
# # ch.append(' ')
|
157
|
+
# # ch.append(
|
158
|
+
# # E.a(u"⁜", onclick="toggle_visibility('comment-{}');".format(
|
159
|
+
# # comment.id), title=str(_("Hide")), href="#")
|
160
|
+
# # )
|
161
|
+
# return ch
|
155
162
|
|
156
163
|
|
157
164
|
class MyComments(My, Comments):
|
@@ -174,14 +181,14 @@ class CommentsByX(Comments):
|
|
174
181
|
class RecentComments(CommentsByX):
|
175
182
|
# required_roles = dd.login_required(CommentsReader)
|
176
183
|
# required_roles = set([CommentsReader])
|
184
|
+
# order_by = ["-modified"]
|
185
|
+
label = _("Recent comments")
|
177
186
|
allow_create = False
|
178
187
|
column_names = "body_short_preview modified user owner *"
|
179
188
|
stay_in_grid = True
|
180
189
|
live_panel_update = True
|
181
|
-
# order_by = ["-modified"]
|
182
|
-
label = _("Recent comments")
|
183
190
|
preview_limit = 10
|
184
|
-
#
|
191
|
+
# default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
|
185
192
|
|
186
193
|
|
187
194
|
class CommentsByType(CommentsByX):
|
@@ -217,26 +224,26 @@ class CommentsByRFC(CommentsByX):
|
|
217
224
|
kw["reply_to"] = constants.CHOICES_BLANK_FILTER_VALUE
|
218
225
|
return kw
|
219
226
|
|
220
|
-
@classmethod
|
221
|
-
def get_main_card(self, ar):
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
227
|
+
# @classmethod
|
228
|
+
# def get_main_card(self, ar):
|
229
|
+
# ticket_obj = ar.master_instance
|
230
|
+
# if ticket_obj is None:
|
231
|
+
# return None
|
232
|
+
# sar = self.request(parent=ar, master_instance=ticket_obj)
|
233
|
+
# html = ticket_obj.get_rfc_description(ar)
|
234
|
+
# sar = self.insert_action.request_from(sar)
|
235
|
+
# if sar.get_permission():
|
236
|
+
# btn = sar.ar2button(None, _("Write comment"), icon_name=None)
|
237
|
+
# html += "<p>" + tostring(btn) + "</p>"
|
238
|
+
#
|
239
|
+
# if html:
|
240
|
+
# return dict(
|
241
|
+
# card_title="Description",
|
242
|
+
# main_card_body=html, # main_card_body is special keyword
|
243
|
+
# id="[main_card]", # needed for map key in react...
|
244
|
+
# )
|
245
|
+
# else:
|
246
|
+
# return None
|
240
247
|
|
241
248
|
|
242
249
|
class CommentsByMentioned(CommentsByX):
|
@@ -274,7 +281,6 @@ class RepliesByComment(CommentsByX):
|
|
274
281
|
live_panel_update = True
|
275
282
|
label = _("Replies")
|
276
283
|
simple_slavegrid_header = True
|
277
|
-
|
278
284
|
paginator_template = "PrevPageLink NextPageLink"
|
279
285
|
hide_if_empty = True
|
280
286
|
|
@@ -292,7 +298,7 @@ class Reactions(dd.Table):
|
|
292
298
|
|
293
299
|
class ReactionsByComment(Reactions):
|
294
300
|
master_key = "comment"
|
295
|
-
|
301
|
+
default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
|
296
302
|
|
297
303
|
|
298
304
|
from lino.modlib.publisher.choicelists import PageFillers
|
lino/modlib/dupable/models.py
CHANGED
@@ -116,7 +116,7 @@ class SimilarObjects(dd.VirtualTable):
|
|
116
116
|
"""Shows the other objects that are similar to this one."""
|
117
117
|
|
118
118
|
label = _("Similar objects")
|
119
|
-
|
119
|
+
default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
|
120
120
|
master = Dupable
|
121
121
|
|
122
122
|
@classmethod
|
@@ -128,9 +128,6 @@ class ExportExcelAction(actions.Action):
|
|
128
128
|
callable_from = "t"
|
129
129
|
required_roles = dd.login_required(DataExporter)
|
130
130
|
|
131
|
-
# def is_callable_from(self, caller):
|
132
|
-
# return isinstance(caller, actions.ShowTable)
|
133
|
-
|
134
131
|
def run_from_ui(self, ar, **kw):
|
135
132
|
# Prepare tmp file
|
136
133
|
mf = TmpMediaFile(ar, "xlsx")
|
@@ -1207,7 +1207,7 @@ class ExtRenderer(JsCacheRenderer):
|
|
1207
1207
|
if not hasattr(rh, "store"):
|
1208
1208
|
raise AttributeError("20200128 {} has no store".format(rh))
|
1209
1209
|
kw.update(
|
1210
|
-
ls_store_fields=[js_code(f.as_js(f.name)) for f in rh.store.
|
1210
|
+
ls_store_fields=[js_code(f.as_js(f.name)) for f in rh.store.grid_fields]
|
1211
1211
|
)
|
1212
1212
|
if rh.store.pk is not None:
|
1213
1213
|
kw.update(ls_id_property=rh.store.pk.name)
|
@@ -1280,17 +1280,17 @@ class ExtRenderer(JsCacheRenderer):
|
|
1280
1280
|
yield " this.ls_insert_handler = Lino.%s;" % a.full_name()
|
1281
1281
|
|
1282
1282
|
yield " var ww = this.containing_window;"
|
1283
|
-
if not hasattr(rh, "
|
1284
|
-
raise AttributeError("20200128 {} has no
|
1285
|
-
for ln in jsgen.declare_vars(rh.
|
1283
|
+
if not hasattr(rh, "grid_layout"):
|
1284
|
+
raise AttributeError("20200128 {} has no grid_layout".format(rh))
|
1285
|
+
for ln in jsgen.declare_vars(rh.grid_layout.main.columns):
|
1286
1286
|
yield " " + ln
|
1287
1287
|
|
1288
1288
|
yield " this.before_row_edit = function(record) {"
|
1289
|
-
for ln in self.before_row_edit(rh.
|
1289
|
+
for ln in self.before_row_edit(rh.grid_layout.main):
|
1290
1290
|
yield " " + ln
|
1291
1291
|
yield " };"
|
1292
1292
|
|
1293
|
-
on_render = self.build_on_render(rh.
|
1293
|
+
on_render = self.build_on_render(rh.grid_layout.main)
|
1294
1294
|
if on_render:
|
1295
1295
|
yield " this.onRender = function(ct, position) {"
|
1296
1296
|
for ln in on_render:
|
@@ -1303,8 +1303,8 @@ class ExtRenderer(JsCacheRenderer):
|
|
1303
1303
|
|
1304
1304
|
yield " this.ls_columns = %s;" % py2js(
|
1305
1305
|
[
|
1306
|
-
ext_elems.GridColumn(rh.
|
1307
|
-
for i, e in enumerate(rh.
|
1306
|
+
ext_elems.GridColumn(rh.grid_layout, i, e)
|
1307
|
+
for i, e in enumerate(rh.grid_layout.main.columns)
|
1308
1308
|
]
|
1309
1309
|
)
|
1310
1310
|
|
lino/modlib/extjs/views.py
CHANGED
@@ -20,9 +20,6 @@ Summary from <http://en.wikipedia.org/wiki/Restful>:
|
|
20
20
|
The ID created is included as part of the data returned by this operation.
|
21
21
|
- DELETE : Delete the entire collection.
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
23
|
"""
|
27
24
|
import json
|
28
25
|
import os
|
@@ -50,24 +47,17 @@ from lino.core.utils import obj2unicode
|
|
50
47
|
from lino.utils.html import E, tostring
|
51
48
|
from etgen.html import Document
|
52
49
|
|
53
|
-
# E = xghtml.E
|
54
|
-
|
55
50
|
from lino.utils import ucsv
|
56
51
|
from lino.utils import dblogger
|
57
|
-
|
58
52
|
from lino.core import constants
|
59
53
|
from lino.core import actions
|
60
54
|
from lino.core import fields
|
61
55
|
from lino.core.fields import choices_for_field
|
62
|
-
|
63
56
|
from lino.core.views import requested_actor, action_request
|
64
57
|
from lino.core.views import json_response, json_response_kw
|
65
58
|
from lino.core.views import choices_response
|
66
|
-
|
67
59
|
from lino.core.requests import BaseRequest, PhantomRow
|
68
60
|
|
69
|
-
# from lino.core import callbacks
|
70
|
-
|
71
61
|
MAX_ROW_COUNT = 300
|
72
62
|
|
73
63
|
|
@@ -279,9 +269,9 @@ class Restful(View):
|
|
279
269
|
data = json.loads(data)
|
280
270
|
ar.form2obj_and_save(data, instance, True)
|
281
271
|
|
282
|
-
# Ext.ensible needs
|
272
|
+
# Ext.ensible needs grid_fields, not detail_fields
|
283
273
|
ar.set_response(
|
284
|
-
rows=[ar.ah.store.row2dict(ar, instance, ar.ah.store.
|
274
|
+
rows=[ar.ah.store.row2dict(ar, instance, ar.ah.store.grid_fields)]
|
285
275
|
)
|
286
276
|
return json_response(ar.response)
|
287
277
|
|
@@ -298,7 +288,7 @@ class Restful(View):
|
|
298
288
|
ar = rpt.request(request=request)
|
299
289
|
rh = ar.ah
|
300
290
|
rows = [
|
301
|
-
rh.store.row2dict(ar, row, rh.store.
|
291
|
+
rh.store.row2dict(ar, row, rh.store.grid_fields)
|
302
292
|
for row in ar.sliced_data_iterator
|
303
293
|
]
|
304
294
|
kw = dict(count=ar.get_total_count(), rows=rows)
|
@@ -320,8 +310,8 @@ class Restful(View):
|
|
320
310
|
ar = rpt.request(request=request, action=a)
|
321
311
|
ar.renderer = settings.SITE.kernel.extjs_renderer
|
322
312
|
ar.form2obj_and_save(data, elem, False)
|
323
|
-
# Ext.ensible needs
|
324
|
-
ar.set_response(rows=[rh.store.row2dict(ar, elem, rh.store.
|
313
|
+
# Ext.ensible needs grid_fields, not detail_fields
|
314
|
+
ar.set_response(rows=[rh.store.row2dict(ar, elem, rh.store.grid_fields)])
|
325
315
|
return json_response(ar.response)
|
326
316
|
|
327
317
|
|
@@ -340,7 +330,7 @@ class ApiElement(View):
|
|
340
330
|
# if not rpt.get_view_permission(request.user.user_type):
|
341
331
|
# raise PermissionDenied("{} has permission to view {}".format(
|
342
332
|
# request.user.user_type, rpt))
|
343
|
-
#
|
333
|
+
# raise Exception(f"20241001 {rpt} {request.user.user_type}")
|
344
334
|
|
345
335
|
action_name = request.GET.get(constants.URL_PARAM_ACTION_NAME, None)
|
346
336
|
if action_name:
|
@@ -481,7 +481,7 @@ class Command(GeneratingCommand):
|
|
481
481
|
# s += show(_("Columns"), rpt.get_handle().get_columns())
|
482
482
|
s += show(_("Columns"), visible)
|
483
483
|
# s += rubric(_("Columns"))
|
484
|
-
# s += rstgen.ul([elem2par(e) for e in rpt.
|
484
|
+
# s += rstgen.ul([elem2par(e) for e in rpt.grid_layout.walk()])
|
485
485
|
# s += rstgen.ul([elem2par(f) for f in rpt.wildcard_data_elems()])
|
486
486
|
|
487
487
|
# s += show(_("Other fields"),
|
lino/modlib/notify/models.py
CHANGED
@@ -383,7 +383,7 @@ class MyMessages(My, Messages):
|
|
383
383
|
created_order = "-created"
|
384
384
|
order_by = [created_order]
|
385
385
|
# hide_headers = True
|
386
|
-
|
386
|
+
default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
|
387
387
|
|
388
388
|
@classmethod
|
389
389
|
def unused_get_table_summary(cls, mi, ar):
|
lino/modlib/printing/actions.py
CHANGED
@@ -52,11 +52,6 @@ class BasePrintAction(Action):
|
|
52
52
|
# logger.info("20140401 attach_to_actor() %r", self)
|
53
53
|
return super(BasePrintAction, self).attach_to_actor(actor, name)
|
54
54
|
|
55
|
-
# def is_callable_from(self, caller):
|
56
|
-
# # including ShowEmptyTable which is subclass of
|
57
|
-
# # ShowDetail. But not callable from ShowInsert.
|
58
|
-
# return isinstance(caller, (ShowTable, ShowDetail))
|
59
|
-
|
60
55
|
def get_print_templates(self, bm, elem):
|
61
56
|
# print("20190506 BasePrintAction.get_print_templates", elem)
|
62
57
|
return elem.get_print_templates(bm, self)
|
lino/modlib/publisher/ui.py
CHANGED
@@ -147,7 +147,7 @@ class Pages(dd.Table):
|
|
147
147
|
ref
|
148
148
|
#page_type filler
|
149
149
|
"""
|
150
|
-
|
150
|
+
default_display_modes = {None: constants.DISPLAY_MODE_STORY}
|
151
151
|
|
152
152
|
|
153
153
|
class PagesByParent(Pages):
|
@@ -156,7 +156,7 @@ class PagesByParent(Pages):
|
|
156
156
|
# ~ column_names = "title user *"
|
157
157
|
order_by = ["seqno"]
|
158
158
|
column_names = "seqno title *"
|
159
|
-
|
159
|
+
default_display_modes = {None: constants.DISPLAY_MODE_LIST}
|
160
160
|
|
161
161
|
|
162
162
|
# PublisherViews.add_item_lazy("p", Pages)
|
@@ -169,7 +169,7 @@ class TranslationsByPage(Pages):
|
|
169
169
|
master_key = "translated_from"
|
170
170
|
label = _("Translations")
|
171
171
|
column_names = "ref title language id *"
|
172
|
-
|
172
|
+
default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
|
173
173
|
|
174
174
|
@classmethod
|
175
175
|
def row_as_summary(cls, ar, obj, **kwargs):
|
lino/modlib/publisher/views.py
CHANGED
@@ -9,6 +9,7 @@ from django.views.generic import View
|
|
9
9
|
from lino.api import dd
|
10
10
|
from lino.core import auth
|
11
11
|
from lino.core.requests import BaseRequest, ActionRequest
|
12
|
+
from django.core.exceptions import ObjectDoesNotExist
|
12
13
|
|
13
14
|
from django.shortcuts import redirect
|
14
15
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
@@ -21,8 +22,8 @@ class Element(View):
|
|
21
22
|
|
22
23
|
def get(self, request, pk=None):
|
23
24
|
# print("20220927 a get()")
|
24
|
-
if pk is None:
|
25
|
-
|
25
|
+
# if pk is None:
|
26
|
+
# return http.HttpResponseNotFound()
|
26
27
|
# rnd = settings.SITE.kernel.default_renderer
|
27
28
|
rnd = settings.SITE.plugins.publisher.renderer
|
28
29
|
|
@@ -33,15 +34,14 @@ class Element(View):
|
|
33
34
|
# if rnd.front_end.media_name == 'react':
|
34
35
|
# kw.update(hash_router=True)
|
35
36
|
|
36
|
-
|
37
|
+
kw.update(selected_pks=[pk])
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
ar.selected_rows = [obj]
|
39
|
+
try:
|
40
|
+
ar = self.table_class.request(request=request, **kw)
|
41
|
+
except ObjectDoesNotExist as e:
|
42
|
+
# print("20240911", e)
|
43
|
+
return http.HttpResponseNotFound(f"No row #{pk} in {self.table_class}")
|
44
|
+
obj = ar.selected_rows[0]
|
45
45
|
return obj.get_publisher_response(ar)
|
46
46
|
|
47
47
|
|
lino/modlib/search/models.py
CHANGED
@@ -25,7 +25,7 @@ class SiteSearchBase(dd.VirtualTable):
|
|
25
25
|
column_names = "description matches"
|
26
26
|
private_apps = frozenset(["sessions", "contenttypes", "users"])
|
27
27
|
|
28
|
-
|
28
|
+
default_display_modes = {None: constants.DISPLAY_MODE_STORY}
|
29
29
|
|
30
30
|
card_layout = """description"""
|
31
31
|
list_layout = """
|
@@ -136,7 +136,7 @@ class SiteSearchBase(dd.VirtualTable):
|
|
136
136
|
|
137
137
|
|
138
138
|
class SiteSearch(SiteSearchBase):
|
139
|
-
|
139
|
+
default_display_modes = {None: constants.DISPLAY_MODE_LIST}
|
140
140
|
|
141
141
|
@classmethod
|
142
142
|
def get_data_rows(cls, ar):
|
lino/modlib/system/mixins.py
CHANGED
@@ -107,11 +107,6 @@ class Lockable(EditSafe):
|
|
107
107
|
resolve_fields_list(cls, "lockable_fields")
|
108
108
|
cls.lockable_fields = set([f.name for f in cls.lockable_fields])
|
109
109
|
|
110
|
-
# @dd.action(_("Edit"), sort_index=100, callable_from='d')
|
111
|
-
# def acquire_lock(self, ar):
|
112
|
-
# self.lock_row(ar)
|
113
|
-
# ar.success(refresh=True)
|
114
|
-
|
115
110
|
def before_ui_edit(self, ar, **kwargs):
|
116
111
|
self.lock_row(ar)
|
117
112
|
ar.success(refresh=True)
|
@@ -131,11 +126,6 @@ class Lockable(EditSafe):
|
|
131
126
|
)
|
132
127
|
self._disabled_fields = None # clear cache
|
133
128
|
|
134
|
-
# @dd.action(_("Abort"), sort_index=100, auto_save=None, callable_from='d')
|
135
|
-
# def release_lock(self, ar):
|
136
|
-
# self.unlock_row(ar)
|
137
|
-
# ar.success(refresh=True)
|
138
|
-
|
139
129
|
def on_ui_abort(self, ar, **kwargs):
|
140
130
|
self.unlock_row(ar)
|
141
131
|
ar.success(refresh=True)
|
lino/modlib/uploads/mixins.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- coding: UTF-8 -*-
|
2
|
-
# Copyright 2008-
|
2
|
+
# Copyright 2008-2024 Rumma & Ko Ltd
|
3
3
|
# License: GNU Affero General Public License v3 (see file COPYING for details)
|
4
4
|
|
5
5
|
import os
|
@@ -13,11 +13,12 @@ from django.core.files.storage import default_storage
|
|
13
13
|
from django.core.exceptions import ValidationError, FieldError
|
14
14
|
from django.template.defaultfilters import filesizeformat
|
15
15
|
|
16
|
-
from
|
16
|
+
from rstgen.sphinxconf.sigal_image import parse_image_spec
|
17
|
+
from lino.core import constants
|
17
18
|
from lino.utils import DATE_TO_DIR_TPL
|
18
19
|
from lino.utils.html import E
|
19
|
-
from rstgen.sphinxconf.sigal_image import parse_image_spec
|
20
20
|
from lino.api import dd, rt, _
|
21
|
+
from lino.modlib.uploads import UPLOADS_ROOT
|
21
22
|
from lino.modlib.memo.mixins import MemoReferrable
|
22
23
|
|
23
24
|
# from lino.mixins.sequenced import Sequenced
|
@@ -133,6 +134,8 @@ class UploadBase(MemoReferrable, GalleryViewable):
|
|
133
134
|
class Meta(object):
|
134
135
|
abstract = True
|
135
136
|
|
137
|
+
extra_display_modes = {constants.DISPLAY_MODE_GALLERY}
|
138
|
+
|
136
139
|
file = models.FileField(_("File"), blank=True, upload_to=upload_to_tpl)
|
137
140
|
mimetype = models.CharField(
|
138
141
|
_("MIME type"), blank=True, max_length=255, editable=False)
|
lino/modlib/uploads/ui.py
CHANGED
@@ -33,7 +33,7 @@ class Volumes(dd.Table):
|
|
33
33
|
ref root_dir
|
34
34
|
description
|
35
35
|
"""
|
36
|
-
|
36
|
+
|
37
37
|
detail_layout = """
|
38
38
|
ref root_dir
|
39
39
|
description
|
@@ -146,7 +146,7 @@ class AreaUploads(Uploads):
|
|
146
146
|
# required_roles = dd.login_required((OfficeUser, OfficeOperator))
|
147
147
|
required_roles = dd.login_required(UploadsReader)
|
148
148
|
stay_in_grid = True
|
149
|
-
|
149
|
+
default_display_modes = {None: constants.DISPLAY_MODE_SUMMARY}
|
150
150
|
|
151
151
|
# 20180119
|
152
152
|
# @classmethod
|
lino/modlib/users/mixins.py
CHANGED
@@ -65,11 +65,11 @@ class Authored(Printable):
|
|
65
65
|
return ba.action.readonly
|
66
66
|
return True
|
67
67
|
|
68
|
-
@classmethod
|
69
|
-
def on_analyze(cls, site):
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
# @classmethod
|
69
|
+
# def on_analyze(cls, site):
|
70
|
+
# if hasattr(cls, "manager_level_field"):
|
71
|
+
# raise ChangedAPI("{0} has a manager_level_field".format(cls))
|
72
|
+
# super().on_analyze(site)
|
73
73
|
|
74
74
|
# no longer needed after 20170826
|
75
75
|
# @classmethod
|
lino/sphinxcontrib/actordoc.py
CHANGED
@@ -199,7 +199,7 @@ def get_actor_description(self):
|
|
199
199
|
if self.help_text:
|
200
200
|
body += unindent(force_str(self.help_text).strip()) + "\n\n"
|
201
201
|
|
202
|
-
# ~ ll = self.get_handle().
|
202
|
+
# ~ ll = self.get_handle().grid_layout
|
203
203
|
# ~ if ll is not None:
|
204
204
|
# ~ body += fields_table([ e.field for e in ll.main.columns] )
|
205
205
|
|
@@ -41,7 +41,7 @@ table.scrollwide td {
|
|
41
41
|
}
|
42
42
|
|
43
43
|
/* centered image captions would be nice. doesn't work.
|
44
|
-
e.g.
|
44
|
+
e.g. https://lino-framework.org/tutorials/layouts.html
|
45
45
|
*/
|
46
46
|
p.caption {
|
47
47
|
width: 100%;
|
@@ -61,10 +61,3 @@ div.body {
|
|
61
61
|
color: #3E4349;
|
62
62
|
padding: 30px 30px;
|
63
63
|
}
|
64
|
-
|
65
|
-
img.pi-button {
|
66
|
-
width: 1.1em;
|
67
|
-
height: 1.1em;
|
68
|
-
background-color: LightSkyBlue;
|
69
|
-
border: 3px solid LightSkyBlue;
|
70
|
-
}
|
lino/utils/choosers.py
CHANGED
@@ -436,7 +436,7 @@ def uses_simple_values(holder, fld):
|
|
436
436
|
# if isinstance(fld, models.OneToOneRel):
|
437
437
|
# return False
|
438
438
|
if not hasattr(fld, "name"):
|
439
|
-
raise Exception("
|
439
|
+
raise Exception("20240925")
|
440
440
|
if holder is not None and fld.name is not None:
|
441
441
|
ch = holder.get_chooser_for_field(fld.name)
|
442
442
|
if ch is not None:
|
lino/utils/report.py
CHANGED
@@ -121,7 +121,7 @@ class EmptyTable(Frame):
|
|
121
121
|
hide_navigator = True
|
122
122
|
# 20240404 default_list_action_name = 'show'
|
123
123
|
# default_elem_action_name = 'show'
|
124
|
-
|
124
|
+
default_display_modes = None # for Actor
|
125
125
|
build_method = None
|
126
126
|
|
127
127
|
@classmethod
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: lino
|
3
|
-
Version: 24.
|
3
|
+
Version: 24.10.0
|
4
4
|
Summary: A framework for writing desktop-like web applications using Django and ExtJS or React
|
5
5
|
Project-URL: Homepage, https://www.lino-framework.org
|
6
6
|
Project-URL: Repository, https://gitlab.com/lino-framework/lino
|