musician webapp visualization and firsts edits
This commit is contained in:
parent
bb4fc5e267
commit
3c3e15d1c5
|
@ -9,6 +9,7 @@ from orchestra.contrib.domains.models import Domain, Record
|
||||||
from orchestra.contrib.mailboxes.models import Address, Mailbox
|
from orchestra.contrib.mailboxes.models import Address, Mailbox
|
||||||
from orchestra.contrib.systemusers.models import WebappUsers, SystemUser
|
from orchestra.contrib.systemusers.models import WebappUsers, SystemUser
|
||||||
from orchestra.contrib.musician.validators import ValidateZoneMixin
|
from orchestra.contrib.musician.validators import ValidateZoneMixin
|
||||||
|
from orchestra.contrib.webapps.models import WebApp, WebAppOption
|
||||||
|
|
||||||
from . import api
|
from . import api
|
||||||
|
|
||||||
|
@ -201,3 +202,20 @@ class SystemUsersChangePasswordForm(ChangePasswordForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
fields = ("password",)
|
fields = ("password",)
|
||||||
model = SystemUser
|
model = SystemUser
|
||||||
|
|
||||||
|
class WebappOptionCreateForm(forms.ModelForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = WebAppOption
|
||||||
|
fields = ("name", "value")
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.webapp = kwargs.pop('webapp')
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
instance = super().save(commit=False)
|
||||||
|
instance.webapp = self.webapp
|
||||||
|
if commit:
|
||||||
|
super().save(commit=True)
|
||||||
|
return instance
|
|
@ -0,0 +1,42 @@
|
||||||
|
{% extends "musician/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<a class="btn-arrow-left" href="{% url 'musician:webapp-list' %}">{% trans "Go back" %}</a>
|
||||||
|
|
||||||
|
<h1 class="service-name">
|
||||||
|
{% trans "PHP settings for" %} <span class="font-weight-light">{{ object.name }}</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="service-description">{% trans "PHP settings page description." %}</p>
|
||||||
|
|
||||||
|
<table class="table service-list">
|
||||||
|
<colgroup>
|
||||||
|
<col span="1" style="width: 12%;">
|
||||||
|
<col span="1" style="width: 10%;">
|
||||||
|
<col span="1" style="width: 78%;">
|
||||||
|
</colgroup>
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">{% trans "Type" %}</th>
|
||||||
|
<th scope="col">{% trans "Value" %}</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for option in object.options.all %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ option.name }}</td>
|
||||||
|
<td>{{ option.value }}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<a href="{% url 'musician:webapp-delete-option' object.pk option.pk %}">
|
||||||
|
<i class="ml-3 text-danger fas fa-trash"></i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<a class="btn btn-primary mt-4 mb-4" href="{% url 'musician:webapp-add-option' object.pk %}">{% trans "Add new option" %}</a></td>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{% extends "musician/base.html" %}
|
||||||
|
{% load bootstrap4 i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1 class="service-name">{{ service.verbose_name }}</h1>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
{% buttons %}
|
||||||
|
<a class="btn btn-light mr-2" href="{% url 'musician:address-list' %}">{% trans "Cancel" %}</a>
|
||||||
|
<button type="submit" class="btn btn-secondary">{% trans "Save" %}</button>
|
||||||
|
{% if form.instance.pk %}
|
||||||
|
<div class="float-right">
|
||||||
|
<a class="btn btn-danger" href="{% url 'musician:address-delete' view.kwargs.pk %}">{% trans "Delete" %}</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,57 @@
|
||||||
|
{% extends "musician/base.html" %}
|
||||||
|
{% load bootstrap4 i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Una Webapp es el diectorio donde se almacena su web,
|
||||||
|
mediante SFTP podras acceder a este directorio y subir/editar/eliminar los archivos
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Cada Webapp tiene su propio usuario SFTP, este se creara automaticamente al crear la Webapp
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table class="table service-list">
|
||||||
|
<colgroup>
|
||||||
|
<col span="1" style="width: 19%;">
|
||||||
|
<col span="1" style="width: 19%;">
|
||||||
|
<col span="1" style="width: 19%;">
|
||||||
|
<col span="1" style="width: 19%;">
|
||||||
|
<col span="1" style="width: 19%;">
|
||||||
|
<col span="1" style="width: 5%;">
|
||||||
|
</colgroup>
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">{% trans "Name" %}</th>
|
||||||
|
<th scope="col">{% trans "Type" %}</th>
|
||||||
|
<th scope="col">{% trans "Version" %}</th>
|
||||||
|
<th scope="col">{% trans "SFTP User" %}</th>
|
||||||
|
<th scope="col">{% trans "Server" %}</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for webapp in object_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ webapp.name }}</td>
|
||||||
|
<td>{{ webapp.type }}</td>
|
||||||
|
<td>{{ webapp.type_instance.get_detail }}</td>
|
||||||
|
<td>
|
||||||
|
{% if webapp.sftpuser %}
|
||||||
|
<a href="{% url 'musician:webappuser-list'%}">{{ webapp.sftpuser }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'musician:systemuser-list'%}">{{ webapp.account.main_systemuser }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ webapp.target_server }}</td>
|
||||||
|
<td>
|
||||||
|
<a class="btn btn-outline-warning" href="{% url 'musician:webapp-detail' webapp.id %}">
|
||||||
|
<i class="fas fa-tools"></i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
{% include "musician/components/table_paginator.html" %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{% extends "musician/base.html" %}
|
||||||
|
{% load bootstrap4 i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<a class="btn-arrow-left" href="{% url 'musician:webapp-detail' view.kwargs.pk %}">{% trans "Go back" %}</a>
|
||||||
|
|
||||||
|
<h1 class="service-name">
|
||||||
|
{% if form.instance.pk %}{% trans "Update record of" %}{% else %}{% trans "Add record to" %}{% endif %}
|
||||||
|
<span class="font-weight-light">{{ form.webapp.name }}</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
{% buttons %}
|
||||||
|
<a class="btn btn-light mr-2" href="{% url 'musician:webapp-detail' view.kwargs.pk %}">{% trans "Cancel" %}</a>
|
||||||
|
<button type="submit" class="btn btn-secondary">{% trans "Save" %}</button>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,13 @@
|
||||||
|
{% extends "musician/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<p>{% blocktrans %}Are you sure that you want remove the following option"?{% endblocktrans %}</p>
|
||||||
|
<pre>{{ object.name}} {{ object.value}}</pre>
|
||||||
|
<p class="alert alert-warning"><strong>{% trans 'WARNING: This action cannot be undone.' %}</strong></p>
|
||||||
|
<input class="btn btn-danger" type="submit" value="{% trans 'Delete' %}">
|
||||||
|
<a class="btn btn-secondary" href="{% url 'musician:webapp-detail' view.kwargs.pk %}">{% trans 'Cancel' %}</a>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,103 @@
|
||||||
|
{% extends "musician/base.html" %}
|
||||||
|
{% load bootstrap4 i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<table class="table service-list table-hover">
|
||||||
|
<colgroup>
|
||||||
|
<col span="1" style="width: 15%;">
|
||||||
|
<col span="1" style="width: 25%;">
|
||||||
|
<col span="1" style="width: 40%;">
|
||||||
|
<col span="1" style="width: 10%;">
|
||||||
|
<col span="1" style="width: 10%;">
|
||||||
|
</colgroup>
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">{% trans "Name" %}</th>
|
||||||
|
<th scope="col">{% trans "Url" %}</th>
|
||||||
|
<th scope="col">{% trans "Server" %}</th>
|
||||||
|
<th scope="col">{% trans "Is active?" %}</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for website in object_list %}
|
||||||
|
<tr class="fila-principal" data-toggle="collapse" data-target=".detalles{{ website.id }}">
|
||||||
|
<td>{{ website.name }}</td>
|
||||||
|
<td>
|
||||||
|
{% for domain in website.domains.all %}
|
||||||
|
<a href="{{ website.get_protocol }}://{{ domain }}">{{ website.get_protocol }}://{{ domain }}</a><br>
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td>{{ website.target_server }}</td>
|
||||||
|
<td class="text-{{website.is_active|yesno:'success,danger'}}">
|
||||||
|
<i class="fa fa-{{ website.is_active|yesno:'check,times' }}"></i>
|
||||||
|
<span class="sr-only">{{ website.is_active|yesno }}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="btn btn-outline-warning" href="#">
|
||||||
|
<i class="fas fa-tools"></i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- Fila oculta de webapp -->
|
||||||
|
<tr class="collapse detalles{{ website.id }}">
|
||||||
|
<td colspan="12"class="p-5">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
{% for content in website.content_set.all %}
|
||||||
|
<tr class="table-active">
|
||||||
|
<td>Webapp Dir</td>
|
||||||
|
<td>/home/{{ content.webapp.account }}/webapps/{{ content.webapp }}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<a class="btn btn-outline-secondary" href="#">
|
||||||
|
<i class="fas fa-tools"></i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Url</td>
|
||||||
|
{% if website.domains.first %}
|
||||||
|
<td><a href="{{ website.get_protocol }}://{{ website.domains.first }}{{ content.path }}">
|
||||||
|
{{ website.get_protocol }}://{{ website.domains.first }}{{ content.path }}</a>
|
||||||
|
</td>
|
||||||
|
{% else %}
|
||||||
|
<td></td>
|
||||||
|
{% endif %}
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Type</td>
|
||||||
|
{% if content.webapp.type == "php" %}
|
||||||
|
<td>PHP {{ content.webapp.type_instance.get_detail }}</td>
|
||||||
|
{% else %}
|
||||||
|
<td>{{ content.webapp.type }}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
{% if content.webapp.sftpuser %}
|
||||||
|
<td>SFTP user</td>
|
||||||
|
<td>{{ content.webapp.sftpuser }}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<a class="btn btn-outline-warning" href="{% url 'musician:webappuser-password' content.webapp.sftpuser.id %}">
|
||||||
|
<i class="fas fa-key"></i> {% trans "Update password" %}</a>
|
||||||
|
</td>
|
||||||
|
{% else %}
|
||||||
|
<td>FTP user</td>
|
||||||
|
<td>{{ content.webapp.account.main_systemuser }}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<a class="btn btn-outline-warning" href="{% url 'musician:systemuser-password' content.webapp.account.main_systemuser.id %}">
|
||||||
|
<i class="fas fa-key"></i> {% trans "Update password" %}</a>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
{% include "musician/components/table_paginator.html" %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -45,4 +45,9 @@ urlpatterns = [
|
||||||
path('systemusers/', views.SystemUserListView.as_view(), name='systemuser-list'),
|
path('systemusers/', views.SystemUserListView.as_view(), name='systemuser-list'),
|
||||||
path('systemuser/<int:pk>/change-password/', views.SystemUserChangePasswordView.as_view(), name='systemuser-password'),
|
path('systemuser/<int:pk>/change-password/', views.SystemUserChangePasswordView.as_view(), name='systemuser-password'),
|
||||||
path('websites/', views.WebsiteListView.as_view(), name='website-list'),
|
path('websites/', views.WebsiteListView.as_view(), name='website-list'),
|
||||||
|
|
||||||
|
path('webapps/', views.WebappListView.as_view(), name='webapp-list'),
|
||||||
|
path('webapps/<int:pk>/', views.WebappDetailView.as_view(), name='webapp-detail'),
|
||||||
|
path('webapps/<int:pk>/add-option/', views.WebappAddOptionView.as_view(), name='webapp-add-option'),
|
||||||
|
path('webapps/<int:pk>/option/<int:option_pk>/delete/', views.WebappDeleteOptionView.as_view(), name='webapp-delete-option'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -34,13 +34,14 @@ from orchestra.contrib.resources.models import Resource, ResourceData
|
||||||
from orchestra.contrib.saas.models import SaaS
|
from orchestra.contrib.saas.models import SaaS
|
||||||
from orchestra.contrib.systemusers.models import WebappUsers, SystemUser
|
from orchestra.contrib.systemusers.models import WebappUsers, SystemUser
|
||||||
from orchestra.contrib.websites.models import Website
|
from orchestra.contrib.websites.models import Website
|
||||||
|
from orchestra.contrib.webapps.models import WebApp, WebAppOption
|
||||||
from orchestra.utils.html import html_to_pdf
|
from orchestra.utils.html import html_to_pdf
|
||||||
|
|
||||||
from .auth import logout as auth_logout
|
from .auth import logout as auth_logout
|
||||||
from .forms import (LoginForm, MailboxChangePasswordForm, MailboxCreateForm,
|
from .forms import (LoginForm, MailboxChangePasswordForm, MailboxCreateForm,
|
||||||
MailboxSearchForm, MailboxUpdateForm, MailForm,
|
MailboxSearchForm, MailboxUpdateForm, MailForm,
|
||||||
RecordCreateForm, RecordUpdateForm, WebappUsersChangePasswordForm,
|
RecordCreateForm, RecordUpdateForm, WebappUsersChangePasswordForm,
|
||||||
SystemUsersChangePasswordForm)
|
SystemUsersChangePasswordForm, WebappOptionCreateForm)
|
||||||
from .mixins import (CustomContextMixin, ExtendedPaginationMixin,
|
from .mixins import (CustomContextMixin, ExtendedPaginationMixin,
|
||||||
UserTokenRequiredMixin)
|
UserTokenRequiredMixin)
|
||||||
from .models import Address as AddressService
|
from .models import Address as AddressService
|
||||||
|
@ -659,3 +660,48 @@ class WebsiteListView(ServiceListView):
|
||||||
# Translators: This message appears on the page title
|
# Translators: This message appears on the page title
|
||||||
'title': _('Websites'),
|
'title': _('Websites'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WebappListView(ServiceListView):
|
||||||
|
model = WebApp
|
||||||
|
template_name = "musician/webapp_list.html"
|
||||||
|
extra_context = {
|
||||||
|
# Translators: This message appears on the page title
|
||||||
|
'title': _('Webapps'),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class WebappDetailView(CustomContextMixin, UserTokenRequiredMixin, DetailView):
|
||||||
|
template_name = "musician/webapp_detail.html"
|
||||||
|
extra_context = {
|
||||||
|
# Translators: This message appears on the page title
|
||||||
|
'title': _('webapp details'),
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return WebApp.objects.filter(account=self.request.user)
|
||||||
|
|
||||||
|
class WebappAddOptionView(CustomContextMixin, UserTokenRequiredMixin, CreateView):
|
||||||
|
model = WebAppOption
|
||||||
|
form_class = WebappOptionCreateForm
|
||||||
|
template_name = "musician/webapp_option_form.html"
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
webapp = get_object_or_404(WebApp, account=self.request.user, pk=self.kwargs["pk"])
|
||||||
|
kwargs['webapp'] = webapp
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse_lazy("musician:webapp-detail", kwargs={"pk": self.kwargs["pk"]})
|
||||||
|
|
||||||
|
class WebappDeleteOptionView(CustomContextMixin, UserTokenRequiredMixin, DeleteView):
|
||||||
|
model = WebAppOption
|
||||||
|
template_name = "musician/webappoption_check_delete.html"
|
||||||
|
pk_url_kwarg = "option_pk"
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
qs = WebAppOption.objects.filter(webapp__account=self.request.user, webapp=self.kwargs["pk"])
|
||||||
|
return qs
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse_lazy("musician:webapp-detail", kwargs={"pk": self.kwargs["pk"]})
|
Loading…
Reference in New Issue