Application Icon upload (#341)

* core: add initial implementation for File Upload

* root: add volumes to docker-compose for file upload

* helm: add pvc for uploads

* core: allow meta_icon to be overwritten with static files
This commit is contained in:
Jens L
2020-11-23 20:50:19 +01:00
committed by GitHub
parent 91e9f176a5
commit 665839133f
18 changed files with 139 additions and 21 deletions

View File

@ -22,7 +22,7 @@ class ApplicationSerializer(ModelSerializer):
"slug",
"provider",
"meta_launch_url",
"meta_icon_url",
"meta_icon",
"meta_description",
"meta_publisher",
"policies",

View File

@ -23,14 +23,13 @@ class ApplicationForm(forms.ModelForm):
"slug",
"provider",
"meta_launch_url",
"meta_icon_url",
"meta_icon",
"meta_description",
"meta_publisher",
]
widgets = {
"name": forms.TextInput(),
"meta_launch_url": forms.TextInput(),
"meta_icon_url": forms.TextInput(),
"meta_publisher": forms.TextInput(),
}
help_texts = {
@ -44,7 +43,7 @@ class ApplicationForm(forms.ModelForm):
field_classes = {"provider": GroupedModelChoiceField}
labels = {
"meta_launch_url": _("Launch URL"),
"meta_icon_url": _("Icon URL"),
"meta_icon": _("Icon"),
"meta_description": _("Description"),
"meta_publisher": _("Publisher"),
}

View File

@ -0,0 +1,24 @@
# Generated by Django 3.1.3 on 2020-11-23 17:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("passbook_core", "0014_auto_20201018_1158"),
]
operations = [
migrations.RemoveField(
model_name="application",
name="meta_icon_url",
),
migrations.AddField(
model_name="application",
name="meta_icon",
field=models.FileField(
blank=True, default="", upload_to="application-icons/"
),
),
]

View File

@ -171,7 +171,8 @@ class Application(PolicyBindingModel):
)
meta_launch_url = models.URLField(default="", blank=True)
meta_icon_url = models.TextField(default="", blank=True)
# For template applications, this can be set to /static/passbook/applications/*
meta_icon = models.FileField(upload_to="application-icons/", default="", blank=True)
meta_description = models.TextField(default="", blank=True)
meta_publisher = models.TextField(default="", blank=True)

View File

@ -13,12 +13,12 @@
{% if applications %}
<div class="pf-l-gallery pf-m-gutter">
{% for app in applications %}
<a href="{{ app.get_launch_url }}" class="pf-c-card pf-m-hoverable pf-m-compact">
<a href="{{ app.get_launch_url }}" class="pf-c-card pf-m-hoverable pf-m-compact pb-root-link">
<div class="pf-c-card__header">
{% if not app.meta_icon_url %}
<i class="pf-icon pf-icon-arrow"></i>
{% if app.meta_icon %}
<img class="app-icon pf-c-avatar" src="{{ app.meta_icon.url }}" alt="{% trans 'Application Icon' %}">
{% else %}
<img class="app-icon pf-c-avatar" src="{{ app.meta_icon_url }}" alt="{% trans 'Application Icon' %}">
<i class="pf-icon pf-icon-arrow"></i>
{% endif %}
</div>
<div class="pf-c-card__title">

View File

@ -57,6 +57,26 @@
{% endif %}
</div>
</div>
{% elif field.field.widget|fieldtype == "ClearableFileInput" %}
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
</div>
<div class="pf-c-form__group-control">
<div class="c-form__horizontal-group">
<div class="pf-c-file-upload">
<div class="pf-c-file-upload__file-select">
<div class="pf-c-input-group">
{{ field|css_class:"pf-c-form-control" }}
</div>
</div>
</div>
</div>
</div>
{% else %}
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">

View File

@ -1,9 +1,10 @@
"""passbook URL Configuration"""
from django.urls import path
from passbook.core.views import impersonate, overview, shell, user
from passbook.core.views import impersonate, library, shell, user
urlpatterns = [
path("", shell.ShellView.as_view(), name="shell"),
# User views
path("-/user/", user.UserSettingsView.as_view(), name="user-settings"),
path("-/user/tokens/", user.TokenListView.as_view(), name="user-tokens"),
@ -22,9 +23,8 @@ urlpatterns = [
user.TokenDeleteView.as_view(),
name="user-tokens-delete",
),
# Overview
path("", shell.ShellView.as_view(), name="shell"),
path("-/overview/", overview.OverviewView.as_view(), name="overview"),
# Libray
path("-/overview/", library.LibraryView.as_view(), name="overview"),
# Impersonation
path(
"-/impersonation/<int:user_id>/",

View File

@ -1,4 +1,4 @@
"""passbook overview views"""
"""passbook library view"""
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView
@ -7,11 +7,11 @@ from passbook.core.models import Application
from passbook.policies.engine import PolicyEngine
class OverviewView(LoginRequiredMixin, TemplateView):
class LibraryView(LoginRequiredMixin, TemplateView):
"""Overview for logged in user, incase user opens passbook directly
and is not being forwarded"""
template_name = "overview/index.html"
template_name = "library.html"
def get_context_data(self, **kwargs):
kwargs["applications"] = []