diff --git a/orchestra/admin/menu.py b/orchestra/admin/menu.py
index 3fb6bffc..c3e7b4f1 100644
--- a/orchestra/admin/menu.py
+++ b/orchestra/admin/menu.py
@@ -38,49 +38,71 @@ def get_services():
return sorted(result, key=lambda i: i.title)
-def get_accounts():
- accounts = [
+def get_account_items():
+ childrens = [
items.MenuItem(_("Accounts"), reverse('admin:accounts_account_changelist'))
]
if isinstalled('orchestra.apps.contacts'):
url = reverse('admin:contacts_contact_changelist')
- accounts.append(items.MenuItem(_("Contacts"), url))
+ childrens.append(items.MenuItem(_("Contacts"), url))
if isinstalled('orchestra.apps.users'):
url = reverse('admin:users_user_changelist')
users = [items.MenuItem(_("Users"), url)]
if isinstalled('rest_framework.authtoken'):
tokens = reverse('admin:authtoken_token_changelist')
users.append(items.MenuItem(_("Tokens"), tokens))
- accounts.append(items.MenuItem(_("Users"), url, children=users))
+ childrens.append(items.MenuItem(_("Users"), url, children=users))
if isinstalled('orchestra.apps.prices'):
url = reverse('admin:prices_pack_changelist')
- accounts.append(items.MenuItem(_("Packs"), url))
+ childrens.append(items.MenuItem(_("Packs"), url))
if isinstalled('orchestra.apps.orders'):
url = reverse('admin:orders_order_changelist')
- accounts.append(items.MenuItem(_("Orders"), url))
- return accounts
-
-
-def get_administration():
- administration = []
- return administration
-
-
-def get_administration_models():
- administration_models = []
- if isinstalled('orchestra.apps.orchestration'):
- administration_models.append('orchestra.apps.orchestration.*')
- if isinstalled('djcelery'):
- administration_models.append('djcelery.*')
+ childrens.append(items.MenuItem(_("Orders"), url))
if isinstalled('orchestra.apps.issues'):
- administration_models.append('orchestra.apps.issues.*')
- if isinstalled('orchestra.apps.resources'):
- administration_models.append('orchestra.apps.resources.*')
- if isinstalled('orchestra.apps.miscellaneous'):
- administration_models.append('orchestra.apps.miscellaneous.models.MiscService')
+ url = reverse('admin:issues_ticket_changelist')
+ childrens.append(items.MenuItem(_("Tickets"), url))
+ return childrens
+
+
+def get_administration_items():
+ childrens = []
if isinstalled('orchestra.apps.orders'):
- administration_models.append('orchestra.apps.orders.models.Service')
- return administration_models
+ url = reverse('admin:orders_service_changelist')
+ childrens.append(items.MenuItem(_("Services"), url))
+ if isinstalled('orchestra.apps.orchestration'):
+ route = reverse('admin:orchestration_route_changelist')
+ backendlog = reverse('admin:orchestration_backendlog_changelist')
+ server = reverse('admin:orchestration_server_changelist')
+ childrens.append(items.MenuItem(_("Orchestration"), route, children=[
+ items.MenuItem(_("Routes"), route),
+ items.MenuItem(_("Backend logs"), backendlog),
+ items.MenuItem(_("Servers"), server),
+ ]))
+ if isinstalled('orchestra.apps.resources'):
+ resource = reverse('admin:resources_resource_changelist')
+ data = reverse('admin:resources_resourcedata_changelist')
+ monitor = reverse('admin:resources_monitordata_changelist')
+ childrens.append(items.MenuItem(_("Resources"), resource, children=[
+ items.MenuItem(_("Resources"), resource),
+ items.MenuItem(_("Data"), data),
+ items.MenuItem(_("Monitoring"), monitor),
+ ]))
+ if isinstalled('orchestra.apps.miscellaneous'):
+ url = reverse('admin:miscellaneous_miscservice_changelist')
+ childrens.append(items.MenuItem(_("Miscellaneous"), url))
+ if isinstalled('orchestra.apps.issues'):
+ url = reverse('admin:issues_queue_changelist')
+ childrens.append(items.MenuItem(_("Issue queues"), url))
+ if isinstalled('djcelery'):
+ task = reverse('admin:djcelery_taskstate_changelist')
+ periodic = reverse('admin:djcelery_periodictask_changelist')
+ worker = reverse('admin:djcelery_workerstate_changelist')
+ childrens.append(items.MenuItem(_("Celery"), task, children=[
+ items.MenuItem(_("Tasks"), task),
+ items.MenuItem(_("Periodic tasks"), periodic),
+ items.MenuItem(_("Workers"), worker),
+ ]))
+ return childrens
class OrchestraMenu(Menu):
@@ -99,12 +121,11 @@ class OrchestraMenu(Menu):
items.MenuItem(
_("Accounts"),
reverse('admin:accounts_account_changelist'),
- children=get_accounts()
+ children=get_account_items()
),
- items.AppList(
+ items.MenuItem(
_("Administration"),
- models=get_administration_models(),
- children=get_administration()
+ children=get_administration_items()
),
items.MenuItem("API", api_link(context))
]
diff --git a/orchestra/admin/utils.py b/orchestra/admin/utils.py
index 9340e8ed..70a0c77d 100644
--- a/orchestra/admin/utils.py
+++ b/orchestra/admin/utils.py
@@ -76,7 +76,8 @@ def admin_link(*args, **kwargs):
order = kwargs.pop('order', field)
popup = kwargs.pop('popup', False)
- def display_link(self, instance):
+ def display_link(*args):
+ instance = args[-1]
obj = getattr(instance, field, instance)
if not getattr(obj, 'pk', None):
return '---'
@@ -95,7 +96,7 @@ def admin_link(*args, **kwargs):
def colored(field_name, colours, description='', verbose=False, bold=True):
""" returns a method that will render obj with colored html """
- def colored_field(modeladmin, obj, field=field_name, colors=colours, verbose=verbose):
+ def colored_field(obj, field=field_name, colors=colours, verbose=verbose):
value = escape(get_field_value(obj, field))
color = colors.get(value, "black")
if verbose:
@@ -133,11 +134,12 @@ def admin_date(field, **kwargs):
default = kwargs.pop('default', '')
order = kwargs.pop('order', field)
- def display_date(self, instance):
+ def display_date(*args):
+ instance = args[-1]
value = get_field_value(instance, field)
if not value:
return default
- return '
{1}
'.format(
+ return '{1}'.format(
escape(str(value)), escape(naturaldate(value)),
)
display_date.short_description = _(field.replace('_', ' '))
diff --git a/orchestra/apps/accounts/admin.py b/orchestra/apps/accounts/admin.py
index 2f8f7024..fd046721 100644
--- a/orchestra/apps/accounts/admin.py
+++ b/orchestra/apps/accounts/admin.py
@@ -60,8 +60,9 @@ class AccountAdmin(ExtendedModelAdmin):
if not account.is_active:
messages.warning(request, 'This account is disabled.')
context = {
+ # TODO not services but everythin (payments, bills, etc)
'services': sorted(
- [ model._meta for model in services.get() ],
+ [ model._meta for model in services.get() if model is not Account ],
key=lambda i: i.verbose_name_plural.lower()
)
}
diff --git a/orchestra/apps/issues/admin.py b/orchestra/apps/issues/admin.py
index 4f37dc7c..d0c43ea8 100644
--- a/orchestra/apps/issues/admin.py
+++ b/orchestra/apps/issues/admin.py
@@ -55,8 +55,8 @@ class MessageReadOnlyInline(admin.TabularInline):
def content_html(self, msg):
context = {
'number': msg.number,
- 'time': display_timesince(msg.created_on),
- 'author': link('author')(self, msg) if msg.author else msg.author_name,
+ 'time': admin_date('created_on')(msg),
+ 'author': admin_link('author')(msg) if msg.author else msg.author_name,
}
summary = _("#%(number)i Updated by %(author)s about %(time)s") % context
header = '%s
' % summary
@@ -113,7 +113,7 @@ class TicketInline(admin.TabularInline):
last_modified = admin_link('last_modified_on')
def ticket_id(self, instance):
- return '%s' % link()(self, instance)
+ return '%s' % admin_link()(instance)
ticket_id.short_description = '#'
ticket_id.allow_tags = True
@@ -197,17 +197,18 @@ class TicketAdmin(ChangeListDefaultFilter, ExtendedModelAdmin): #TODO ChangeView
display_creator = admin_link('creator')
display_queue = admin_link('queue')
display_owner = admin_link('owner')
+ last_modified = admin_date('last_modified_on')
def display_summary(self, ticket):
context = {
- 'creator': link('creator')(self, ticket) if ticket.creator else ticket.creator_name,
- 'created': display_timesince(ticket.created_on),
+ 'creator': admin_link('creator')(self, ticket) if ticket.creator else ticket.creator_name,
+ 'created': admin_date('created_on')(ticket),
'updated': '',
}
msg = ticket.messages.last()
if msg:
context.update({
- 'updated': display_timesince(msg.created_on),
+ 'updated': admin_date('created_on')(msg),
'updater': admin_link('author')(self, msg) if msg.author else msg.author_name,
})
context['updated'] = '. Updated by %(updater)s about %(updated)s' % context
@@ -245,10 +246,6 @@ class TicketAdmin(ChangeListDefaultFilter, ExtendedModelAdmin): #TODO ChangeView
bold_subject.short_description = _("Subject")
bold_subject.admin_order_field = 'subject'
- def last_modified(self, instance):
- return display_timesince(instance.last_modified_on)
- last_modified.admin_order_field = 'last_modified_on'
-
def formfield_for_dbfield(self, db_field, **kwargs):
""" Make value input widget bigger """
if db_field.name == 'subject':
diff --git a/orchestra/apps/issues/models.py b/orchestra/apps/issues/models.py
index 7922b2de..e0a8b142 100644
--- a/orchestra/apps/issues/models.py
+++ b/orchestra/apps/issues/models.py
@@ -85,7 +85,7 @@ class Ticket(models.Model):
if self.owner:
emails.append(self.owner.email)
for contact in self.creator.account.contacts.all():
- if self.queue and set(contact.email_usage).union(set(self.queue.nofify)):
+ if self.queue and set(contact.email_usage).union(set(self.queue.notify)):
emails.append(contact.email)
for message in self.messages.distinct('author'):
emails.append(message.author.email)
diff --git a/orchestra/apps/resources/models.py b/orchestra/apps/resources/models.py
index 51a0c664..dde199c3 100644
--- a/orchestra/apps/resources/models.py
+++ b/orchestra/apps/resources/models.py
@@ -173,7 +173,6 @@ def create_resource_relation():
resource = Resource.objects.get(content_type__model=model,
name=attr, is_active=True)
data = ResourceData(content_object=self.obj, resource=resource)
- print data.resource_id, data.content_type_id, data.object_id
setattr(self, attr, data)
return data
diff --git a/orchestra/conf/base_settings.py b/orchestra/conf/base_settings.py
index 2672a067..213deac4 100644
--- a/orchestra/conf/base_settings.py
+++ b/orchestra/conf/base_settings.py
@@ -145,6 +145,7 @@ FLUENT_DASHBOARD_APP_GROUPS = (
'orchestra.apps.prices.models.Pack',
'orchestra.apps.bills.models.Bill',
'orchestra.apps.payments.models.Transaction',
+ 'orchestra.apps.issues.models.Ticket',
),
'collapsible': True,
}),
@@ -154,7 +155,6 @@ FLUENT_DASHBOARD_APP_GROUPS = (
'orchestra.apps.orchestration.models.Route',
'orchestra.apps.orchestration.models.BackendLog',
'orchestra.apps.orchestration.models.Server',
- 'orchestra.apps.issues.models.Ticket',
'orchestra.apps.resources.models.Resource',
'orchestra.apps.resources.models.Monitor',
'orchestra.apps.orders.models.Service',
@@ -185,13 +185,13 @@ FLUENT_DASHBOARD_APP_ICONS = {
'prices/pack': 'Pack.png',
'bills/bill': 'invoice.png',
'payments/transaction': 'transaction.png',
+ 'issues/ticket': 'Ticket_star.png',
# Administration
'users/user': 'Mr-potato.png',
'djcelery/taskstate': 'taskstate.png',
'orchestration/server': 'vps.png',
'orchestration/route': 'hal.png',
'orchestration/backendlog': 'scriptlog.png',
- 'issues/ticket': 'Ticket_star.png',
'resources/resource': "gauge.png",
'resources/monitor': "Utilities-system-monitor.png",
}
diff --git a/orchestra/static/orchestra/icons/Pack.png b/orchestra/static/orchestra/icons/Pack.png
new file mode 100644
index 00000000..24d48ced
Binary files /dev/null and b/orchestra/static/orchestra/icons/Pack.png differ
diff --git a/orchestra/static/orchestra/icons/Pack.svg b/orchestra/static/orchestra/icons/Pack.svg
new file mode 100644
index 00000000..7afdb383
--- /dev/null
+++ b/orchestra/static/orchestra/icons/Pack.svg
@@ -0,0 +1,4350 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/orchestra/static/orchestra/icons/Taskstate.svg b/orchestra/static/orchestra/icons/Taskstate.svg
new file mode 100644
index 00000000..0471b135
--- /dev/null
+++ b/orchestra/static/orchestra/icons/Taskstate.svg
@@ -0,0 +1,512 @@
+
+
+
+
diff --git a/orchestra/static/orchestra/icons/applications-other.png b/orchestra/static/orchestra/icons/applications-other.png
new file mode 100644
index 00000000..8e909384
Binary files /dev/null and b/orchestra/static/orchestra/icons/applications-other.png differ
diff --git a/orchestra/static/orchestra/icons/applications-other.svg b/orchestra/static/orchestra/icons/applications-other.svg
new file mode 100644
index 00000000..3a141484
--- /dev/null
+++ b/orchestra/static/orchestra/icons/applications-other.svg
@@ -0,0 +1,807 @@
+
+
+
+
diff --git a/orchestra/static/orchestra/icons/invoice.png b/orchestra/static/orchestra/icons/invoice.png
new file mode 100644
index 00000000..6a5daa2c
Binary files /dev/null and b/orchestra/static/orchestra/icons/invoice.png differ
diff --git a/orchestra/static/orchestra/icons/invoice.svg b/orchestra/static/orchestra/icons/invoice.svg
new file mode 100644
index 00000000..6bc4a4e9
--- /dev/null
+++ b/orchestra/static/orchestra/icons/invoice.svg
@@ -0,0 +1,679 @@
+
+
+
+
diff --git a/orchestra/static/orchestra/icons/taskstate.png b/orchestra/static/orchestra/icons/taskstate.png
index 777c5898..9280cb7f 100755
Binary files a/orchestra/static/orchestra/icons/taskstate.png and b/orchestra/static/orchestra/icons/taskstate.png differ