Skip to content

Commit

Permalink
feat: Update design for asset cards
Browse files Browse the repository at this point in the history
  • Loading branch information
petesfrench committed Oct 23, 2024
1 parent 55a5b8e commit ee2edf0
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 223 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"postcss": "8.4.21",
"postcss-cli": "10.1.0",
"sass-lint": "1.13.1",
"vanilla-framework": "3.13.0",
"vanilla-framework": "4.16.0",
"watch-cli": "0.2.3"
},
"devDependencies": {
Expand Down
17 changes: 6 additions & 11 deletions static/sass/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,13 @@
}
}

.asset-thumbnail {
.p-asset-card--thumbnail {
max-height: 100px;
min-height: 100px;
}

.asset-additional-edit-row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
& > * {
margin: 0 !important;
}
}
.p-asset-card {
padding:0.75rem;
background:#f7f7f7;
margin-top:2rem;
}
51 changes: 51 additions & 0 deletions templates/_asset-card-image.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<div class="p-asset-card p-equal-height-row__col" style="padding:0.75rem;background:#f7f7f7;margin-top:2rem;">
<div class="p-equal-height-row__item">
{% if asset.data.image %}
<a href="/v1/{{ asset.file_path }}" target="_blank">
<img
class="p-asset-card--thumbnail"
src="/v1/{{ asset.file_path }}"
/>
</a>
{% endif %}
</div>
<div class="p-equal-height-row__item">
{% if asset.name %}
<p class="u-no-margin--bottom"><strong>{{ asset.name }}</strong></p>
{% else %}
<p class="u-no-margin--bottom"><strong>{{ asset.file_path.split('.')[0] }}</strong></p>
{% endif %}
<p>File type: <strong>.{{ asset.file_path.split('.', 1)[1] }}</strong></p>
<p class="u-no-margin--bottom">Image size: <strong>{% if asset.data.width and asset.data.height %}{{asset.data.width}} x {{asset.data.height}}{% endif %}</strong></p>
<p>
Tags:
{% for tag in asset.tags %}
<strong>{{ tag.name }}{% if not loop.last %},{% endif %}</strong>
{% endfor %}
</p>
<p>
<span>Date created: {{ asset.created.strftime('%d %B %Y') }}</span>
</p>
</div>
<div class="p-equal-height-row__item">
<p class="p-text--small">
<a href="/manager/details?file-path={{ asset.file_path }}">Full asset details&nbsp;&rsaquo;</a>
</p>
</div>
<div class="p-equal-height-row__item">
<p class="u-align--right u-no-margin--bottom" style="height:100%">
<button
class="p-button--positive copy-link is-dense"
data-url="/v1/{{ asset.file_path }}"
>
Asset link
</button>
<a
class="p-button is-dense"
href="/manager/update?file-path={{ asset.file_path }}"
>
Edit asset
</a>
</p>
</div>
</div>
48 changes: 48 additions & 0 deletions templates/_asset-card.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<div class="p-asset-card p-equal-height-row__col" style="">
<div class="p-equal-height-row__item" style="max-height:6rem;">
{% if asset.asset_type == "whitepaper" %}
<img class="p-asset-card--thumbnail" src="https://assets.ubuntu.com/v1/b061c401-White+paper.svg" alt="">
{% else %}
<img class="p-asset-card--thumbnail" src="https://assets.ubuntu.com/v1/fd84bbdc-Document-open.svg" alt="">
{% endif %}
</div>
<div class="p-equal-height-row__item">
{% if asset.name %}
<p><strong>{{ asset.name }}</strong></p>
{% else %}
<p><strong>{{ asset.file_path.split('.')[0] }}</strong></p>
{% endif %}
<p class="u-no-margin--bottom">File type: <strong>.{{ asset.file_path.split('.', 1)[1] }}</strong></p>
<p>Asset type: <strong>{{ asset.asset_type }}</strong></p>
<p>
Tags:
{% for tag in asset.tags %}
<strong>{{ tag.name }}{% if not loop.last %},{% endif %}</strong>
{% endfor %}
</p>
<p>
<span>Date created: {{ asset.created.strftime('%d %B %Y') }}</span>
</p>
</div>
<div class="p-equal-height-row__item">
<p class="p-text--small">
<a href="/manager/details?file-path={{ asset.file_path }}">Full asset details&nbsp;&rsaquo;</a>
</p>
</div>
<div class="p-equal-height-row__item">
<p class="u-align--right u-no-margin--bottom" style="height:100%">
<button
class="p-button--positive copy-link is-dense"
data-url="/v1/{{ asset.file_path }}"
>
Asset link
</button>
<a
class="p-button is-dense"
href="/manager/update?file-path={{ asset.file_path }}"
>
Edit asset
</a>
</p>
</div>
</div>
6 changes: 5 additions & 1 deletion templates/_asset-list.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
{% for asset in assets %}
{% include "_asset.html" %}
{% if asset.data.image %}
{% include "_asset-card-image.html" %}
{% else %}
{% include "_asset-card.html" %}
{% endif %}
{% endfor %}
57 changes: 0 additions & 57 deletions templates/_asset.html

This file was deleted.

4 changes: 2 additions & 2 deletions templates/created.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ <h2>Failed to upload {{failed|length}} assets</h2>
</div>
{% endif %}
{% if assets %}
<div class="row">
<div class="p-equal-height-row">
<h2>{{assets|length}} assets created</h2>
{% include "_asset-list.html" %}
</div>
{% endif %}

{% if existing %}
<div class="row">
<div class="p-equal-height-row">
{% set assets = existing %}
<h2>{{existing|length}} existing assets</h2>
{% include "_asset-list.html" %}
Expand Down
58 changes: 58 additions & 0 deletions templates/details.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{% extends "_layout.html" %}

{% block title %}Asset details{% endblock %}

{% block content %}
<div class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h2>Asset details</h2>
{% if asset.data.image %}
<a href="/v1/{{ asset.file_path }}" target="_blank">
<img
src="/v1/{{ asset.file_path }}"
/>
</a>
{% endif %}
<p>File path:<strong>{{ file_path }}</strong></p>
<p>Name: <strong>{{ asset.name }}</strong></p>
<p>File type: <strong>.{{ asset.file_path.split('.', 1)[1] }}</strong></p>
<p>Asset type: {{ asset.asset_type }}</p>
<p>Image size: <strong>{% if asset.data.width and asset.data.height %}{{asset.data.width}} x {{asset.data.height}}{% else %}Unknown{% endif %}</strong></p>
<p>
Products:
{% for product in asset.products %}
<strong>{{ product.name }}{% if not loop.last %},{% endif %}</strong>
{% endfor %}
</p>
<p>
Tags:
{% for tag in asset.tags %}
<strong>{{ tag.name }}{% if not loop.last %},{% endif %}</strong>
{% endfor %}
</p>
<p>Created: {{ asset.created.strftime('%d %B %Y') }}</p>
<p>Updated: {{ asset.updated.strftime('%d %B %Y') }}</p>
<p>Google drive link: {{ asset.google_drive_link }}</p>
<p>Author email: {{ asset.author_email }}</p>
<p>Language: {{ asset.language }}</p>
<p>Salesforce campaign ID: {{ asset.salesforce_campaign_id }}</p>
<p>Deprecated: {{ asset.deprecated }}</p>
<p style="height:100%">
<button
class="p-button--positive copy-link is-dense"
data-url="/v1/{{ asset.file_path }}"
>
Asset link
</button>
<button
class="p-button is-dense"
data-url="/manager/update?file-path={{ asset.file_path }}"
>
Edit asset
</button>
</p>
</div>
</div>
</div>
{% endblock %}
2 changes: 1 addition & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
</div>
</div>
<div class="p-strip is-shallow">
<div class="row u-clearfix">
<div class="p-equal-height-row">
{% if assets %}
{% include "_asset-list.html" %}
{% elif request.values.get("q", None) %}
Expand Down
2 changes: 1 addition & 1 deletion templates/update.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ <h2>{{ asset.file_path or request.args.get("file-path")}}</h2>
{% if asset.data.image %}
<div class="u-fixed-width">
<a href="/v1/{{ asset.file_path }}" target="_blank">
<img class="p-image--bordered asset-thumbnail" src="/v1/{{ asset.file_path }}">
<img class="p-image--bordered p-asset-card--thumbnail" src="/v1/{{ asset.file_path }}">
</a>
</div>
{% endif %}
Expand Down
12 changes: 11 additions & 1 deletion webapp/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def home():
)


@ui_blueprint.route("/create", methods=["POST"])
@ui_blueprint.route("/create", methods=["GET", "POST"])
@login_required
def create():
created_assets = []
Expand Down Expand Up @@ -195,6 +195,16 @@ def update():

return flask.render_template("update.html", asset=asset)

@ui_blueprint.route("/details", methods=["GET"])
@login_required
def details():
file_path = request.args.get("file-path")

asset = asset_service.find_asset(file_path)
if not asset:
flask.flash("Asset not found", "negative")

return flask.render_template("details.html", asset=asset)

# API Routes
# ===
Expand Down
35 changes: 22 additions & 13 deletions webapp/services.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# System
import imghdr
from base64 import b64decode
from base64 import b64decode, b64encode
from datetime import datetime, timezone
from io import BytesIO

# Packages
from wand.image import Image
from typing import List
from PIL import Image as PillowImage

# Local
from webapp.database import db_session
Expand Down Expand Up @@ -98,7 +100,11 @@ def create_asset(
friendly_name = clean_unicode(friendly_name)
url_path = clean_unicode(url_path)

encoded_file_content = (b64decode(file_content),)
# First we ensure it is b64 encoded
encoded_file_content = b64encode(file_content)
# Then we can decode it
decoded_file_content = (b64decode(encoded_file_content))

if imghdr.what(None, h=file_content) is not None or is_svg(
file_content
):
Expand All @@ -107,30 +113,33 @@ def create_asset(
# As it's not an image, there is no need for optimization
data["optimized"] = False

if data.get("image"):
try:
# Use Pillow to open the image and get dimensions
with PillowImage.open(BytesIO(decoded_file_content)) as img:
data["width"] = img.width
data["height"] = img.height
except Exception as e:
print(f"Error opening image with Pillow: {e}")
data["width"] = None
data["height"] = None

# Try to optimize the asset if it's an image
if data.get("image") and optimize:
try:
image = ImageProcessor(encoded_file_content)
image = ImageProcessor(decoded_file_content)
image.optimize(allow_svg_errors=True)
encoded_file_content = image.data
decoded_file_content = image.data
data["optimized"] = True
except Exception:
# If optimisation failed, just don't bother optimising
data["optimized"] = False

if not url_path:
url_path = file_manager.generate_asset_path(
file_content, friendly_name
)

if data.get("image"):
try:
with Image(blob=encoded_file_content) as image_info:
data["width"] = image_info.width
data["height"] = image_info.height
except Exception:
# Just don't worry if image reading fails
pass

asset = (
db_session.query(Asset)
.filter(Asset.file_path == url_path)
Expand Down
Loading

0 comments on commit ee2edf0

Please sign in to comment.