backoffice: view to list elements outside applications (#85886)
gitea/wcs/pipeline/head This commit looks good Details

This commit is contained in:
Lauréline Guérin 2024-01-19 15:13:57 +01:00 committed by Lauréline Guérin
parent be22912d7c
commit 6d41ed8c74
14 changed files with 266 additions and 71 deletions

View File

@ -130,8 +130,10 @@ def test_formdefs(pub, application_with_icon, application_without_icon, icon):
)
else:
assert len(resp.pyquery('h3:contains("Applications") + .button-paragraph img')) == 0
assert 'Forms outside applications' in resp
# check application view
resp = app.get('/backoffice/forms/')
resp = resp.click(href='application/%s/' % application.slug)
assert resp.pyquery('h2').text() == application.name
if icon:
@ -145,6 +147,13 @@ def test_formdefs(pub, application_with_icon, application_without_icon, icon):
assert resp.pyquery('.section ul.objects-list li:nth-child(2)').text() == 'form3'
assert len(resp.pyquery('.section ul.objects-list img')) == 0
# check elements outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Forms outside applications'
assert len(resp.pyquery('.section')) == 1
assert len(resp.pyquery('.section ul.objects-list li')) == 1
assert resp.pyquery('.section ul.objects-list li:nth-child(1)').text() == 'form1'
# with category
cat = Category()
cat.name = 'cat'
@ -192,13 +201,21 @@ def test_formdefs(pub, application_with_icon, application_without_icon, icon):
cat2 = Category()
cat2.name = 'cat2'
cat2.store()
cat3 = Category()
cat3.name = 'cat3'
cat3.store()
resp = app.get('/backoffice/forms/categories/')
assert resp.pyquery('h3:contains("Applications") + .button-paragraph').text() == application.name
assert len(resp.pyquery('ul.biglist li')) == 2
assert len(resp.pyquery('ul.biglist li')) == 3
resp = resp.click(href='application/%s/' % application.slug)
assert resp.pyquery('h2').text() == application.name
assert len(resp.pyquery('ul.objects-list li')) == 1
# check categories outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Categories outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 2
# check detail page
resp = app.get('/backoffice/forms/%s/' % formdef1.id)
assert len(resp.pyquery('h3:contains("Applications")')) == 0
@ -296,6 +313,7 @@ def test_carddefs(pub, application_with_icon, application_without_icon, icon):
)
else:
assert len(resp.pyquery('h3:contains("Applications") + .button-paragraph img')) == 0
assert 'Card models outside applications' in resp
# check application view
resp = resp.click(href='application/%s/' % application.slug)
@ -311,6 +329,13 @@ def test_carddefs(pub, application_with_icon, application_without_icon, icon):
assert resp.pyquery('.section ul.objects-list li:nth-child(2)').text() == 'card3'
assert len(resp.pyquery('.section ul.objects-list img')) == 0
# check elements outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Card models outside applications'
assert len(resp.pyquery('.section')) == 1
assert len(resp.pyquery('.section ul.objects-list li')) == 1
assert resp.pyquery('.section ul.objects-list li:nth-child(1)').text() == 'card1'
# with category
cat = CardDefCategory()
cat.name = 'cat'
@ -380,13 +405,21 @@ def test_carddefs(pub, application_with_icon, application_without_icon, icon):
cat2 = CardDefCategory()
cat2.name = 'cat2'
cat2.store()
cat3 = CardDefCategory()
cat3.name = 'cat3'
cat3.store()
resp = app.get('/backoffice/cards/categories/')
assert resp.pyquery('h3:contains("Applications") + .button-paragraph').text() == application.name
assert len(resp.pyquery('ul.biglist li')) == 2
assert len(resp.pyquery('ul.biglist li')) == 3
resp = resp.click(href='application/%s/' % application.slug)
assert resp.pyquery('h2').text() == application.name
assert len(resp.pyquery('ul.objects-list li')) == 1
# check categories outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Categories outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 2
# check visible flag
application = Application.get(application.id)
application.visible = False
@ -496,6 +529,7 @@ def test_workflows(pub, application_with_icon, application_without_icon, icon):
)
else:
assert len(resp.pyquery('h3:contains("Applications") + .button-paragraph img')) == 0
assert 'Workflows outside applications' in resp
# check application view
resp = resp.click(href='application/%s/' % application.slug)
@ -510,6 +544,13 @@ def test_workflows(pub, application_with_icon, application_without_icon, icon):
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'workflow2 Forms and card models'
assert resp.pyquery('ul.objects-list li:nth-child(2)').text() == 'workflow3 Unused'
# check elements outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Workflows outside applications'
assert len(resp.pyquery('.section')) == 1
assert len(resp.pyquery('.section ul.objects-list li')) == 1
assert resp.pyquery('.section ul.objects-list li:nth-child(1)').text() == 'workflow1 Unused'
# with category
cat = WorkflowCategory()
cat.name = 'cat'
@ -604,13 +645,21 @@ def test_workflows(pub, application_with_icon, application_without_icon, icon):
cat2 = WorkflowCategory()
cat2.name = 'cat2'
cat2.store()
cat3 = WorkflowCategory()
cat3.name = 'cat3'
cat3.store()
resp = app.get('/backoffice/workflows/categories/')
assert resp.pyquery('h3:contains("Applications") + .button-paragraph').text() == application.name
assert len(resp.pyquery('ul.biglist li')) == 2
assert len(resp.pyquery('ul.biglist li')) == 3
resp = resp.click(href='application/%s/' % application.slug)
assert resp.pyquery('h2').text() == application.name
assert len(resp.pyquery('ul.objects-list li')) == 1
# check categories outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Categories outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 2
# check visible flag
application = Application.get(application.id)
application.visible = False
@ -685,6 +734,7 @@ def test_blockdefs(pub, application_with_icon, application_without_icon, icon):
)
else:
assert len(resp.pyquery('h3:contains("Applications") + .button-paragraph img')) == 0
assert 'Field blocks outside applications' in resp
# check application view
resp = resp.click(href='application/%s/' % application.slug)
@ -699,6 +749,12 @@ def test_blockdefs(pub, application_with_icon, application_without_icon, icon):
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'block2'
assert resp.pyquery('ul.objects-list li:nth-child(2)').text() == 'block3'
# check elements outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Field blocks outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 1
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'block1'
# with category
cat = BlockCategory()
cat.name = 'cat'
@ -768,13 +824,21 @@ def test_blockdefs(pub, application_with_icon, application_without_icon, icon):
cat2 = BlockCategory()
cat2.name = 'cat2'
cat2.store()
cat3 = BlockCategory()
cat3.name = 'cat3'
cat3.store()
resp = app.get('/backoffice/forms/blocks/categories/')
assert resp.pyquery('h3:contains("Applications") + .button-paragraph').text() == application.name
assert len(resp.pyquery('ul.biglist li')) == 2
assert len(resp.pyquery('ul.biglist li')) == 3
resp = resp.click(href='application/%s/' % application.slug)
assert resp.pyquery('h2').text() == application.name
assert len(resp.pyquery('ul.objects-list li')) == 1
# check categories outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Categories outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 2
# check visible flag
application = Application.get(application.id)
application.visible = False
@ -849,6 +913,7 @@ def test_mailtemplates(pub, application_with_icon, application_without_icon, ico
)
else:
assert len(resp.pyquery('h3:contains("Applications") + .button-paragraph img')) == 0
assert 'Mail templates outside applications' in resp
# check application view
resp = resp.click(href='application/%s/' % application.slug)
@ -863,6 +928,12 @@ def test_mailtemplates(pub, application_with_icon, application_without_icon, ico
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'mailtemplate2'
assert resp.pyquery('ul.objects-list li:nth-child(2)').text() == 'mailtemplate3'
# check elements outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Mail templates outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 1
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'mailtemplate1'
# with category
cat = MailTemplateCategory()
cat.name = 'cat'
@ -942,13 +1013,21 @@ def test_mailtemplates(pub, application_with_icon, application_without_icon, ico
cat2 = MailTemplateCategory()
cat2.name = 'cat2'
cat2.store()
cat3 = MailTemplateCategory()
cat3.name = 'cat3'
cat3.store()
resp = app.get('/backoffice/workflows/mail-templates/categories/')
assert resp.pyquery('h3:contains("Applications") + .button-paragraph').text() == application.name
assert len(resp.pyquery('ul.biglist li')) == 2
assert len(resp.pyquery('ul.biglist li')) == 3
resp = resp.click(href='application/%s/' % application.slug)
assert resp.pyquery('h2').text() == application.name
assert len(resp.pyquery('ul.objects-list li')) == 1
# check categories outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Categories outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 2
# check visible flag
application = Application.get(application.id)
application.visible = False
@ -1023,6 +1102,7 @@ def test_commenttemplates(pub, application_with_icon, application_without_icon,
)
else:
assert len(resp.pyquery('h3:contains("Applications") + .button-paragraph img')) == 0
assert 'Comment templates outside applications' in resp
# check application view
resp = resp.click(href='application/%s/' % application.slug)
@ -1037,6 +1117,12 @@ def test_commenttemplates(pub, application_with_icon, application_without_icon,
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'commenttemplate2'
assert resp.pyquery('ul.objects-list li:nth-child(2)').text() == 'commenttemplate3'
# check elements outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Comment templates outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 1
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'commenttemplate1'
# with category
cat = CommentTemplateCategory()
cat.name = 'cat'
@ -1121,13 +1207,21 @@ def test_commenttemplates(pub, application_with_icon, application_without_icon,
cat2 = CommentTemplateCategory()
cat2.name = 'cat2'
cat2.store()
cat3 = CommentTemplateCategory()
cat3.name = 'cat3'
cat3.store()
resp = app.get('/backoffice/workflows/comment-templates/categories/')
assert resp.pyquery('h3:contains("Applications") + .button-paragraph').text() == application.name
assert len(resp.pyquery('ul.biglist li')) == 2
assert len(resp.pyquery('ul.biglist li')) == 3
resp = resp.click(href='application/%s/' % application.slug)
assert resp.pyquery('h2').text() == application.name
assert len(resp.pyquery('ul.objects-list li')) == 1
# check categories outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Categories outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 2
# check visible flag
application = Application.get(application.id)
application.visible = False
@ -1273,6 +1367,7 @@ def test_datasources(pub, application_with_icon, application_without_icon, icon)
)
else:
assert len(resp.pyquery('h3:contains("Applications") + .button-paragraph img')) == 0
assert 'Data sources outside applications' in resp
# check application view
resp = resp.click(href='application/%s/' % application.slug)
@ -1306,6 +1401,29 @@ def test_datasources(pub, application_with_icon, application_without_icon, icon)
assert len(PyQuery(resp.pyquery('.section')[2]).find('ul.objects-list li')) == 1
assert PyQuery(resp.pyquery('.section')[2]).find('ul.objects-list li:nth-child(1)').text() == 'card2'
# check elements outside applications
resp = resp.click(href='application/')
assert resp.pyquery('#appbar h2').text() == 'Data sources outside applications'
assert len(resp.pyquery('.section')) == 3
assert PyQuery(resp.pyquery('.section')[0]).find('h2').text() == 'Users Data Sources'
assert len(PyQuery(resp.pyquery('.section')[0]).find('ul.objects-list li')) == 1
assert (
PyQuery(resp.pyquery('.section')[0]).find('ul.objects-list li:nth-child(1)').text()
== 'user datasource1 (user_datasource1)'
)
assert PyQuery(resp.pyquery('.section')[1]).find('h2').text() == 'Manually Configured Data Sources'
assert len(PyQuery(resp.pyquery('.section')[1]).find('ul.objects-list li')) == 1
assert (
PyQuery(resp.pyquery('.section')[1]).find('ul.objects-list li:nth-child(1)').text()
== 'datasource1 (datasource1)'
)
assert (
PyQuery(resp.pyquery('.section')[2]).find('h2').text()
== 'Data Sources from Card Models - automatically configured'
)
assert len(PyQuery(resp.pyquery('.section')[2]).find('ul.objects-list li')) == 1
assert PyQuery(resp.pyquery('.section')[2]).find('ul.objects-list li:nth-child(1)').text() == 'card1'
# with category
cat = DataSourceCategory()
cat.name = 'cat'
@ -1414,13 +1532,21 @@ def test_datasources(pub, application_with_icon, application_without_icon, icon)
cat2 = DataSourceCategory()
cat2.name = 'cat2'
cat2.store()
cat3 = DataSourceCategory()
cat3.name = 'cat3'
cat3.store()
resp = app.get('/backoffice/forms/data-sources/categories/')
assert resp.pyquery('h3:contains("Applications") + .button-paragraph').text() == application.name
assert len(resp.pyquery('ul.biglist li')) == 2
assert len(resp.pyquery('ul.biglist li')) == 3
resp = resp.click(href='application/%s/' % application.slug)
assert resp.pyquery('h2').text() == application.name
assert len(resp.pyquery('ul.objects-list li')) == 1
# check categories outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Categories outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 2
# check visible flag
application = Application.get(application.id)
application.visible = False
@ -1492,6 +1618,7 @@ def test_wscalls(pub, application_with_icon, application_without_icon, icon):
)
else:
assert len(resp.pyquery('h3:contains("Applications") + .button-paragraph img')) == 0
assert 'Webservice calls outside applications' in resp
# check application view
resp = resp.click(href='application/%s/' % application.slug)
@ -1505,6 +1632,12 @@ def test_wscalls(pub, application_with_icon, application_without_icon, icon):
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'wscall2 (wscall2)'
assert resp.pyquery('ul.objects-list li:nth-child(2)').text() == 'wscall3 (wscall3)'
# check elements outside applications
resp = resp.click(href='application/')
assert resp.pyquery('h2').text() == 'Webservice calls outside applications'
assert len(resp.pyquery('ul.objects-list li')) == 1
assert resp.pyquery('ul.objects-list li:nth-child(1)').text() == 'wscall1 (wscall1)'
# check detail page
resp = app.get('/backoffice/settings/wscalls/%s/' % wscall1.id)
assert len(resp.pyquery('h3:contains("Applications")')) == 0

View File

@ -307,7 +307,7 @@ class BlocksDirectory(Directory):
def __init__(self):
super().__init__()
self.applications_dir = ApplicationsDirectory(BlockDef.xml_root_node)
self.applications_dir = ApplicationsDirectory(BlockDef)
def _q_traverse(self, path):
if not get_publisher().get_backoffice_root().is_global_accessible('forms'):
@ -330,6 +330,7 @@ class BlocksDirectory(Directory):
context = {
'view': self,
'applications': Application.select_for_object_type(BlockDef.xml_root_node),
'elements_label': BlockDef.verbose_name_plural,
'has_sidebar': True,
}
blocks = BlockDef.select(order_by='name')

View File

@ -384,7 +384,7 @@ class CategoriesDirectory(Directory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.applications_dir = ApplicationsDirectory(self.category_class.xml_root_node)
self.applications_dir = ApplicationsDirectory(self.category_class)
def _q_index(self):
from wcs.applications import Application
@ -400,6 +400,7 @@ class CategoriesDirectory(Directory):
'view': self,
'categories': categories,
'applications': Application.select_for_object_type(self.category_class.xml_root_node),
'elements_label': self.category_class.verbose_name_plural,
'has_sidebar': True,
},
is_django_native=True,

View File

@ -46,7 +46,7 @@ class CommentTemplatesDirectory(Directory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.applications_dir = ApplicationsDirectory(CommentTemplate.xml_root_node)
self.applications_dir = ApplicationsDirectory(CommentTemplate)
def _q_traverse(self, path):
if not get_publisher().get_backoffice_root().is_global_accessible('workflows'):
@ -67,6 +67,7 @@ class CommentTemplatesDirectory(Directory):
context = {
'view': self,
'applications': Application.select_for_object_type(CommentTemplate.xml_root_node),
'elements_label': CommentTemplate.verbose_name_plural,
'has_sidebar': True,
}
context.update(self.get_list_context(comment_templates))

View File

@ -521,7 +521,7 @@ class NamedDataSourcesDirectory(Directory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.applications_dir = ApplicationsDirectory(NamedDataSource.xml_root_node)
self.applications_dir = ApplicationsDirectory(NamedDataSource)
def _q_traverse(self, path):
if (
@ -543,6 +543,7 @@ class NamedDataSourcesDirectory(Directory):
'has_chrono': has_chrono(get_publisher()),
'has_users': True,
'applications': Application.select_for_object_type(NamedDataSource.xml_root_node),
'elements_label': NamedDataSource.verbose_name_plural,
'has_sidebar': True,
}
data_sources = NamedDataSource.select(order_by='name')
@ -554,7 +555,7 @@ class NamedDataSourcesDirectory(Directory):
is_django_native=True,
)
def get_list_context(self, objects, application=None):
def get_list_context(self, objects, application=Ellipsis):
from wcs.applications import Application
data_sources = []
@ -575,8 +576,11 @@ class NamedDataSourcesDirectory(Directory):
category.data_sources = [x for x in data_sources if x.category_id == category.id]
generated_data_sources = list(CardDef.get_carddefs_as_data_source())
generated_data_sources.sort(key=lambda x: misc.simplify(x[1]))
if application:
carddefs = application.get_objects_for_object_type(CardDef.xml_root_node, lightweight=True)
if application is None:
carddefs = Application.get_orphan_objects_for_object_type(CardDef.xml_root_node)
generated_data_sources = [g for g in generated_data_sources if g[0] in carddefs]
elif application is not Ellipsis:
carddefs = application.get_objects_for_object_type(CardDef.xml_root_node)
generated_data_sources = [g for g in generated_data_sources if g[0] in carddefs]
else:
Application.populate_objects([g[0] for g in generated_data_sources])

View File

@ -1817,7 +1817,7 @@ class FormsDirectory(AccessControlled, Directory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.applications_dir = ApplicationsDirectory(self.formdef_class.xml_root_node)
self.applications_dir = ApplicationsDirectory(self.formdef_class)
def _q_traverse(self, path):
get_response().breadcrumb.append(('%s/' % self.section, self.top_title))
@ -1847,6 +1847,7 @@ class FormsDirectory(AccessControlled, Directory):
'view': self,
'has_roles': bool(get_publisher().role_class.count()),
'applications': Application.select_for_object_type(self.formdef_class.xml_root_node),
'elements_label': self.formdef_class.verbose_name_plural,
'has_sidebar': True,
}
formdefs = self.formdef_class.select(order_by='name', ignore_errors=True, lightweight=True)

View File

@ -46,7 +46,7 @@ class MailTemplatesDirectory(Directory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.applications_dir = ApplicationsDirectory(MailTemplate.xml_root_node)
self.applications_dir = ApplicationsDirectory(MailTemplate)
def _q_traverse(self, path):
if not get_publisher().get_backoffice_root().is_global_accessible('workflows'):
@ -67,6 +67,7 @@ class MailTemplatesDirectory(Directory):
context = {
'view': self,
'applications': Application.select_for_object_type(MailTemplate.xml_root_node),
'elements_label': MailTemplate.verbose_name_plural,
'has_sidebar': True,
}
context.update(self.get_list_context(mail_templates))

View File

@ -1985,7 +1985,7 @@ class WorkflowsDirectory(Directory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.applications_dir = ApplicationsDirectory(Workflow.xml_root_node)
self.applications_dir = ApplicationsDirectory(Workflow)
def _q_traverse(self, path):
get_response().breadcrumb.append(('workflows/', _('Workflows')))
@ -2015,6 +2015,7 @@ class WorkflowsDirectory(Directory):
'view': self,
'is_global_accessible': is_global_accessible(),
'applications': Application.select_for_object_type(Workflow.xml_root_node),
'elements_label': Workflow.verbose_name_plural,
'has_sidebar': True,
}
workflows = Workflow.select(order_by='name')

View File

@ -228,7 +228,7 @@ class NamedWsCallsDirectory(Directory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.applications_dir = ApplicationsDirectory(NamedWsCall.xml_root_node)
self.applications_dir = ApplicationsDirectory(NamedWsCall)
def _q_traverse(self, path):
get_response().breadcrumb.append(('wscalls/', _('Webservice Calls')))
@ -247,6 +247,7 @@ class NamedWsCallsDirectory(Directory):
'view': self,
'wscalls': wscalls,
'applications': Application.select_for_object_type(NamedWsCall.xml_root_node),
'elements_label': NamedWsCall.verbose_name_plural,
'has_sidebar': True,
},
is_django_native=True,

View File

@ -20,6 +20,7 @@ import mimetypes
from quixote import get_publisher
from wcs import sql
from wcs.qommon.storage import Contains, Not
from wcs.qommon.upload_storage import PicklableUpload
@ -113,7 +114,7 @@ class Application(sql.Application):
)
object_ids = [e.object_id for e in elements]
select_kwargs = {}
if object_type == 'formdef':
if object_type in ['formdef', 'carddef']:
select_kwargs['lightweight'] = lightweight
return (
get_publisher()
@ -121,6 +122,23 @@ class Application(sql.Application):
.get_ids(object_ids, ignore_errors=True, order_by='name', **select_kwargs)
)
@classmethod
def get_orphan_objects_for_object_type(cls, object_type, lightweight=True):
elements = ApplicationElement.select([sql.Equal('object_type', object_type)])
application_ids = [e.application_id for e in elements]
applications_by_ids = {a.id: a for a in cls.get_ids(application_ids, ignore_errors=True) if a.visible}
object_ids = [e.object_id for e in elements if applications_by_ids.get(e.application_id)]
select_kwargs = {}
if object_type in ['formdef', 'carddef']:
select_kwargs['lightweight'] = lightweight
return (
get_publisher()
.get_object_class(object_type)
.select(
clause=[Not(Contains('id', object_ids))], ignore_errors=True, order_by='name', **select_kwargs
)
)
class ApplicationElement(sql.ApplicationElement):
id = None

View File

@ -14,33 +14,13 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
from quixote import get_response, redirect
from quixote import get_response
from quixote.directory import Directory
from wcs.qommon import errors, misc, template
from wcs.qommon import _, errors, misc, template
class ApplicationsDirectory(Directory):
_q_exports = ['']
def __init__(self, object_type):
self.object_type = object_type
def _q_index(self):
return redirect('..')
def _q_lookup(self, component):
from wcs.applications import Application
application = Application.get_by_slug(component, ignore_errors=True)
if not application or not application.visible:
raise errors.TraversalError()
return ApplicationDirectory(self.object_type, application)
class ApplicationDirectory(Directory):
_q_exports = ['', 'icon', 'logo']
class ApplicationMixin:
formdef_objects_template = 'wcs/backoffice/application_formdefs.html'
carddef_objects_template = 'wcs/backoffice/application_carddefs.html'
workflow_objects_template = 'wcs/backoffice/application_workflows.html'
@ -50,36 +30,11 @@ class ApplicationDirectory(Directory):
datasource_objects_template = 'wcs/backoffice/application_datasources.html'
wscall_objects_template = 'wcs/backoffice/application_wscalls.html'
def __init__(self, object_type, application):
self.object_type = object_type
self.application = application
def _q_traverse(self, path):
get_response().breadcrumb.append(('application/%s/' % self.application.slug, self.application.name))
return super()._q_traverse(path)
def _q_index(self):
get_response().set_title(self.application.name)
return template.QommonTemplateResponse(templates=[self.get_template()], context=self.get_context())
def get_template(self):
if hasattr(self, '%s_objects_template' % self.object_type.replace('-', '')):
return getattr(self, '%s_objects_template' % self.object_type.replace('-', ''))
return 'wcs/backoffice/application_objects.html'
def get_context(self):
context = {
'application': self.application,
}
objects = self.application.get_objects_for_object_type(self.object_type)
if hasattr(self, 'get_%s_objects_context' % self.object_type.replace('-', '')):
context.update(
getattr(self, 'get_%s_objects_context' % self.object_type.replace('-', ''))(objects)
)
else:
context['objects'] = objects
return context
def get_formdef_objects_context(self, objects):
from wcs.admin.forms import FormsDirectory
@ -113,7 +68,73 @@ class ApplicationDirectory(Directory):
def get_datasource_objects_context(self, objects):
from wcs.admin.data_sources import NamedDataSourcesDirectory
return NamedDataSourcesDirectory().get_list_context(objects, self.application)
return NamedDataSourcesDirectory().get_list_context(objects, getattr(self, 'application', None))
class ApplicationsDirectory(ApplicationMixin, Directory):
_q_exports = ['']
def __init__(self, object_class):
self.object_class = object_class
self.object_type = object_class.xml_root_node
self.object_label = object_class.verbose_name_plural
def _q_traverse(self, path):
get_response().breadcrumb.append(('application/', _('Applications')))
return super()._q_traverse(path)
def _q_index(self):
get_response().set_title(_('Applications'))
return template.QommonTemplateResponse(templates=[self.get_template()], context=self.get_context())
def _q_lookup(self, component):
from wcs.applications import Application
application = Application.get_by_slug(component, ignore_errors=True)
if not application or not application.visible:
raise errors.TraversalError()
return ApplicationDirectory(self.object_class, application)
def get_context(self):
from wcs.applications import Application
context = {
'elements_label': self.object_label,
}
objects = Application.get_orphan_objects_for_object_type(self.object_type)
if hasattr(self, 'get_%s_objects_context' % self.object_type.replace('-', '')):
context.update(
getattr(self, 'get_%s_objects_context' % self.object_type.replace('-', ''))(objects)
)
else:
context['objects'] = objects
return context
class ApplicationDirectory(ApplicationMixin, Directory):
_q_exports = ['', 'icon', 'logo']
def __init__(self, object_class, application):
self.object_type = object_class.xml_root_node
self.object_label = object_class.verbose_name_plural
self.application = application
def _q_index(self):
get_response().set_title(self.application.name)
return template.QommonTemplateResponse(templates=[self.get_template()], context=self.get_context())
def get_context(self):
context = {
'application': self.application,
}
objects = self.application.get_objects_for_object_type(self.object_type)
if hasattr(self, 'get_%s_objects_context' % self.object_type.replace('-', '')):
context.update(
getattr(self, 'get_%s_objects_context' % self.object_type.replace('-', ''))(objects)
)
else:
context['objects'] = objects
return context
def icon(self):
return self._icon(size=(16, 16))

View File

@ -31,6 +31,7 @@ class Category(XmlStorableObject):
xml_root_node = 'category'
backoffice_class = 'wcs.admin.categories.CategoryPage'
backoffice_base_url = 'forms/categories/'
verbose_name_plural = _('Categories')
name = None
url_name = None
@ -219,6 +220,7 @@ class CardDefCategory(Category):
xml_root_node = 'carddef_category'
backoffice_class = 'wcs.admin.categories.CardDefCategoryPage'
backoffice_base_url = 'cards/categories/'
verbose_name_plural = _('Categories')
# declarations for serialization
XML_NODES = [
@ -264,6 +266,7 @@ class BlockCategory(Category):
xml_root_node = 'block_category'
backoffice_class = 'wcs.admin.categories.BlockCategoryPage'
backoffice_base_url = 'forms/blocks/categories/'
verbose_name_plural = _('Categories')
# declarations for serialization
XML_NODES = [
@ -306,6 +309,7 @@ class CommentTemplateCategory(Category):
xml_root_node = 'comment_template_category'
backoffice_class = 'wcs.admin.categories.CommentTemplateCategoryPage'
backoffice_base_url = 'workflows/comment-templates/categories/'
verbose_name_plural = _('Categories')
# declarations for serialization
XML_NODES = [
@ -327,6 +331,7 @@ class DataSourceCategory(Category):
xml_root_node = 'data_source_category'
backoffice_class = 'wcs.admin.categories.DataSourceCategoryPage'
backoffice_base_url = 'forms/data-sources/categories/'
verbose_name_plural = _('Categories')
# declarations for serialization
XML_NODES = [

View File

@ -2,10 +2,14 @@
{% load i18n %}
{% block appbar-title %}
{% if application.icon %}
<img src="logo" alt="" class="application-logo" />
{% if application %}
{% if application.icon %}
<img src="logo" alt="" class="application-logo" />
{% endif %}
{{ application.name }}
{% else %}
{% blocktrans %}{{ elements_label }} outside applications{% endblocktrans %}
{% endif %}
{{ application.name }}
{% endblock %}
{% block content %}

View File

@ -10,4 +10,7 @@
{{ application.name }}
</a>
{% endfor %}
<a class="button button-paragraph" href="{{ prefix }}application/">
{% blocktrans %}{{ elements_label }} outside applications{% endblocktrans %}
</a>
{% endif %}