Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💄 [#1309] Make upload widget correspond with design #580

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/open_inwoner/accounts/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ def __init__(self, users, *args, **kwargs):

class CaseUploadForm(forms.Form):
title = forms.CharField(
label=_("Titel"), max_length=255, validators=[validate_charfield_entry]
label=_("Titel bestand"), max_length=255, validators=[validate_charfield_entry]
)
type = forms.ModelChoiceField(
ZaakTypeInformatieObjectTypeConfig.objects.none(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
title="{% firstof title text %}"
aria-label="{% firstof title text %}"
{% as_attributes extra_attributes %}
{% if id %} id="{{ id }}" {% endif %}
>
{% if icon %}{% icon icon=icon outlined=icon_outlined %}{% endif %}
{% if text_icon %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% load i18n form_tags icon_tags %}

<div class="form__control {{ extra_classes|default:"upload" }}">
<div class="inputfile-group">
<label class="label">
<span class="input-file">
{{ field|addclass:"inputfile" }}

<label class="label__label">
{% icon icon="cloud_upload" icon_position="before" outlined=True %}
{{ text }}

</label>{% if field.field.required %}<span class="label__label--required"> * </span>{% endif %}
</span>

{% if field.errors %}
{% errors errors=field.errors %}
{% endif %}
</label>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
hx-select="{{ async_selector }}"
hx-target="{{ async_selector }}"
{% endif %}

{# HTML attribute to bypass browser defaults and show validation #}
novalidate
>
{% if form.non_field_errors %}
{% errors errors=form.non_field_errors %}
Expand Down
15 changes: 15 additions & 0 deletions src/open_inwoner/components/templatetags/form_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,21 @@ def input(field, **kwargs):
return {**kwargs, "field": field}


@register.inclusion_tag("components/Form/FileInput.html")
def file_input(file, text, **kwargs):
"""
Displaying a file upload interface.

Usage:
{% file_input form.field text="Bestanden uploaden" %}

Variables:
+ field: Field | The field that needs to be rendered.
- extra_classes: string| classes which should be added to the top-level container
"""
return {**kwargs, "field": file, "text": text}


@register.inclusion_tag("components/Form/DateField.html")
def date_field(field, **kwargs):
return {**kwargs, "field": field}
Expand Down
1 change: 1 addition & 0 deletions src/open_inwoner/js/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import './preview'
import './questionnaire'
import './search'
import './toggle'
import './upload-document'
import './session'

const htmx = (window.htmx = require('htmx.org'))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const documentUpload = document.getElementById('form_upload')
const uploadError = document.querySelectorAll('.notifications')
// get info
const getFormInfo = document.querySelectorAll('.form__control--info')

// if errors are present, scroll and trigger opened state
if (uploadError.length > 1) {
documentUpload.scrollIntoView({
block: 'center',
behavior: 'smooth',
})
// documentUpload.classList.add('upload--open')
getFormInfo.forEach((elem) => {
elem.style.display = 'block'
})
}
2 changes: 2 additions & 0 deletions src/open_inwoner/js/components/upload-document/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './show-file-info'
import './file-input-errors'
68 changes: 68 additions & 0 deletions src/open_inwoner/js/components/upload-document/show-file-info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const fileUploadInput = document.getElementById('id_file')
const sizeInfo = document.getElementById('upload_size')
const nameInfo = document.getElementById('upload_name')
const closeButton = document.getElementById('close_upload')
const submit_upload = document.getElementById('submit_upload')
// show info
const formControlInfo = document.querySelectorAll('.form__control--info')

if (fileUploadInput) {
// Convert the file size to a readable format
const formatFileSize = function (bytes) {
const suffixes = ['B', 'kB', 'MB', 'GB', 'TB']
const i = Math.floor(Math.log(bytes) / Math.log(1024))
return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${suffixes[i]}`
}
// initial values
submit_upload.disabled = true
formControlInfo.forEach((elem) => {
elem.style.display = 'none'
})

fileUploadInput.addEventListener('change', function (e) {
const files = e.target.files

if ((files.length === 0) | (files === null) | (files === undefined)) {
submit_upload.disabled = true
// Hide the size element if user doesn't choose any file
formControlInfo.forEach((elem) => {
elem.style.display = 'none'
})
} else {
submit_upload.disabled = false
// Display info
sizeInfo.textContent = formatFileSize(files[0].size)
nameInfo.textContent = `${files[0].name}`
// Display in DOM
formControlInfo.forEach((elem) => {
elem.style.display = 'block'
})
}
})

if (closeButton) {
closeButton.addEventListener('click', (event) => {
submit_upload.disabled = true
formControlInfo.forEach((elem) => {
elem.style.display = 'none'
})
})
}

// if there is only 1 case-type, remove select and its surrounding label
document
.querySelectorAll('.file-type__select')
.forEach(function (selectType) {
if (selectType.querySelector('input[type="hidden"]')) {
selectType.style.display = 'none'
}
})

// Firefox focus bug fix
fileUploadInput.addEventListener('focus', function () {
fileUploadInput.classList.add('has-focus')
})
fileUploadInput.addEventListener('blur', function () {
fileUploadInput.classList.remove('has-focus')
})
}
186 changes: 185 additions & 1 deletion src/open_inwoner/scss/components/Form/DocumentUpload.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,192 @@
#document-upload {
gap: var(--spacing-tiny);

.button[type='submit']:disabled {
background-color: var(--color-gray) !important;
border-color: var(--color-gray) !important;
color: var(--color-gray-light);
color: var(--color-white);
pointer-events: none;
cursor: default;
}

.form__control.upload .form__submit {
*[class*='icon'],
.button {
position: initial;
margin-top: 2em;
}
}

input[type='text'] {
max-width: var(--mobile-xs-width);
}

.inputfile-group {
display: block;

.label,
.close {
display: block;
}
}
}

/// File-input site wide
input[type='file'] {
background-color: var(--color-white);
color: var(--color-primary-lighter);
border: 1px solid var(--color-mute);
border-radius: var(--border-radius);
display: flex;
flex-direction: column;
min-width: var(--mobile-xs-width);
max-width: 500px;
padding: 0;
overflow: hidden;
cursor: pointer;
}

/// File-input button site wide
input[type='file']::file-selector-button {
color: var(--color-white);
background-color: var(--color-primary);
text-transform: uppercase;
border: 1px;
border-radius: var(--border-radius);
font-size: var(--font-size-body);
line-height: var(--font-line-height-body);
height: var(--row-height);
font-weight: normal;
text-align: center;
vertical-align: middle;
cursor: pointer;
white-space: nowrap;
padding: 0 12px 0 12px;
margin: 0 12px 0 0;
width: 200px;
}

.button-row .upload-button--disabled {
background-color: var(--color-gray) !important;
border-color: var(--color-gray) !important;
}

.form__open-upload {
.file-type__select {
max-width: var(--mobile-xs-width);
}
.form__control > .label *[class*='icon'] {
top: 69%;
}

.input-file {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 7px;
position: relative;
//width: 200px;

*[class*='icons'] {
position: absolute;
top: 18px;
left: 12px;
color: orange;
}

/// Hidden file-input for cases
.inputfile {
display: inline-block;
margin-top: var(--spacing-medium);
min-width: 200px;
height: var(--row-height);
opacity: 0;
overflow: hidden;
z-index: 200;
}

.inputfile + label {
display: inline-block;
position: absolute;
top: 5px;
left: 0;
padding: var(--spacing-medium) var(--spacing-large) var(--spacing-medium)
calc(3 * (var(--spacing-extra-large)));
font-size: var(--font-size-body);
color: var(--color-font-primary);
background-color: var(--color-primary);
border: 1px solid var(--color-primary);
border-radius: var(--border-radius);
min-width: 202px;
z-index: -1;
}

.inputfile:focus + label,
.inputfile.has-focus + label,
.inputfile:hover + label,
.inputfile + label:hover {
background-color: var(--color-primary-darker);
top: 4px;
transition: all 0.3s, background-color 0.3s;
}

.inputfile + label *[class*='icons'] {
width: 1.3em;
vertical-align: middle;
color: white;
margin-left: var(--spacing-medium);
}

.inputfile + label {
cursor: pointer; /* "hand" cursor */
}

.inputfile:focus + label {
outline: 2px solid orange;
outline: -webkit-focus-ring-color auto 5px;
}
}

.close .button--transparent {
color: var(--color-red);
}

.info-container {
display: none;
}

.fieldset-container {
display: flex;
box-sizing: border-box;
flex-direction: row;
justify-content: space-around;
border: 1px solid lightgray;
border-radius: 4px;
max-width: var(--mobile-xs-width);
height: 80px;
padding-top: var(--spacing-large);
margin-bottom: 20px;

.fieldset__content {
color: var(--color-mute);
width: 200px;

.upload-info {
display: inline-block;
font-family: var(--font-family-body);
font-size: var(--font-size-body);
color: var(--color-mute);
width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

&__name {
color: var(--font-color-body);
font-weight: bold;
}
}
}
}
}
11 changes: 10 additions & 1 deletion src/open_inwoner/scss/components/Form/Form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@
}
}
}
&__control
.label
.notifications__errors
.notification--warning
*[class*='icon'] {
position: static;
transform: translateY(-5px);
}

&__control > .label .p:last-child {
font-size: var(--font-size-body-small);
Expand Down Expand Up @@ -148,9 +156,10 @@

.caption__content {
display: block;
color: var(--font-color-body);
color: var(--color-mute);
font-family: var(--font-family-body);
font-size: var(--font-size-body);
font-style: italic;
.label__label--required {
vertical-align: sub;
}
Expand Down
2 changes: 1 addition & 1 deletion src/open_inwoner/scss/components/Header/AnchorMenu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
position: fixed;
bottom: var(--spacing-large);
right: var(--spacing-large);
z-index: 401;
z-index: 1005;

@media (min-width: 768px) {
position: static;
Expand Down
Loading