Identity profile metadata input with dynamic form (#280)
This commit is contained in:
parent
b63ad40f54
commit
aa2ace9b68
|
@ -434,6 +434,7 @@ p.authorization-code {
|
|||
font-size: 140%;
|
||||
}
|
||||
|
||||
|
||||
/* Icon menus */
|
||||
|
||||
.icon-menu .option {
|
||||
|
@ -870,6 +871,35 @@ button:hover,
|
|||
.right-column .button {
|
||||
padding: 2px 6px;
|
||||
}
|
||||
form .field.multi-option {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
form .field.multi-option {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
form .option.option-row {
|
||||
margin: 0px 0px 5px 0px;
|
||||
}
|
||||
.option-row .right {
|
||||
float: right;
|
||||
}
|
||||
form .option-row .option-field {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
line-height: normal;
|
||||
width: 40%;
|
||||
min-width: 30px;
|
||||
padding-left: 0px;
|
||||
padding-right: 7px;
|
||||
|
||||
}
|
||||
|
||||
form .option-row .right button {
|
||||
vertical-align: middle;
|
||||
margin-top: 0px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
/* Logged out homepage */
|
||||
|
||||
|
@ -933,6 +963,32 @@ h1.identity small {
|
|||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
.identity-metadata .metadata-pair {
|
||||
display: block;
|
||||
margin: 0px 0 10px 0;
|
||||
background: var(--color-bg-box);
|
||||
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1);
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
padding: 10px 20px;
|
||||
border: 2px solid rgba(255, 255, 255, 0);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.identity-metadata .metadata-pair .metadata-name {
|
||||
display: inline-block;
|
||||
min-width: 80px;
|
||||
margin-right: 15px;
|
||||
text-align: right;
|
||||
color: var(--color-text-dull);
|
||||
}
|
||||
.identity-metadata .metadata-pair .metadata-name::after {
|
||||
padding-left: 3px;
|
||||
|
||||
color: var(--color-text-dull);
|
||||
}
|
||||
|
||||
.system-note {
|
||||
background: var(--color-bg-menu);
|
||||
color: var(--color-text-dull);
|
||||
|
@ -1602,3 +1658,7 @@ form .post {
|
|||
.debug-section .hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.field .hidden {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
{% with name_one=field_name_one|default:"name" name_two=field_name_two|default:"value" %}
|
||||
|
||||
<script type="text/hyperscript">
|
||||
def {{ field.name }}.collect{{ field.name|title }}Fields()
|
||||
set newdata to []
|
||||
for item in <div.{{ field.name }}-row/>
|
||||
get the (value of the first <input.{{ field.name }}-{{ name_one }}/> in item)
|
||||
set n to it
|
||||
get the (value of the last <input.{{ field.name }}-{{ name_two }}/> in item)
|
||||
set val to it
|
||||
if n != '' and val != '' then
|
||||
append {'{{ name_one }}': n, '{{ name_two }}': val} to newdata
|
||||
end
|
||||
set #id_{{ field.name }}@value to newdata as JSON
|
||||
end
|
||||
|
||||
def {{ field.name }}.addEmptyField()
|
||||
get #blank_{{ field.name }}'s outerHTML
|
||||
put it before #new_{{ field.name }}
|
||||
get #new_{{ field.name }}'s previousSibling
|
||||
set foo to it
|
||||
set foo@id to ''
|
||||
remove .hidden from foo
|
||||
add .{{ field.name }}-row to foo
|
||||
return foo
|
||||
end
|
||||
</script>
|
||||
|
||||
{% include "forms/_field.html" %}
|
||||
|
||||
<div class="field multi-option">
|
||||
<section class="icon-menu">
|
||||
<span id="new_{{ field.name }}" stlye="display: none"
|
||||
_="on load
|
||||
get the (value of #id_{{ field.name }}) as Object
|
||||
set items to it
|
||||
for item in items
|
||||
set f to {{ field.name }}.addEmptyField()
|
||||
set one to the first <input.{{ field.name }}-{{ name_one }}/> in f then
|
||||
set one@value to item.{{ name_one }}
|
||||
|
||||
set two to the first <input.{{ field.name }}-{{ name_two }}/> in f then
|
||||
set two@value to item.{{ name_two }}
|
||||
end
|
||||
"></span>
|
||||
|
||||
<div class="option">
|
||||
<span class="option-field">
|
||||
<button class="fa-solid fa-add" _="on click {{ field.name }}.addEmptyField() then halt"></button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div id="blank_{{ field.name }}" class="option option-row hidden">
|
||||
<span class="option-field">
|
||||
<input type=text class="{{ field.name }}-{{ name_one }}" name="{{ field.name }}_{{ name_one }}" value="">
|
||||
</span>
|
||||
<span class="option-field">
|
||||
<input type=text class="{{ field.name }}-{{ name_two }}" name="{{ field.name }}_{{ name_two }}" value="">
|
||||
</span>
|
||||
<div class="right">
|
||||
<button class="fa-solid fa-trash delete"
|
||||
_="on click remove (closest parent .option)
|
||||
then {{ field.name }}.collect{{ field.name|title }}Fields()
|
||||
then halt" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
{% endwith %}
|
|
@ -68,14 +68,14 @@
|
|||
{% endif %}
|
||||
|
||||
{% if identity.metadata %}
|
||||
<table class="metadata">
|
||||
<div class="identity-metadata">
|
||||
{% for entry in identity.safe_metadata %}
|
||||
<tr>
|
||||
<th>{{ entry.name }}</td>
|
||||
<td>{{ entry.value }}</td>
|
||||
</tr>
|
||||
<div class="metadata-pair">
|
||||
<span class="metadata-name">{{ entry.name }}</span>
|
||||
<span class="metadata-value">{{ entry.value }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if identity.local and identity.config_identity.visible_follows %}
|
||||
|
|
|
@ -3,15 +3,19 @@
|
|||
{% block subtitle %}Profile{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="." method="POST" enctype="multipart/form-data" >
|
||||
<form action="." method="POST" enctype="multipart/form-data"
|
||||
_="on submit metadata.collectMetadataFields()">
|
||||
{% csrf_token %}
|
||||
|
||||
<fieldset>
|
||||
<legend>Details</legend>
|
||||
{% include "forms/_field.html" with field=form.name %}
|
||||
{% include "forms/_field.html" with field=form.summary %}
|
||||
{% include "forms/_json_name_value_list.html" with field=form.metadata %}
|
||||
{% include "forms/_field.html" with field=form.discoverable %}
|
||||
{% include "forms/_field.html" with field=form.visible_follows %}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Images</legend>
|
||||
{% include "forms/_field.html" with field=form.icon %}
|
||||
|
|
|
@ -47,6 +47,12 @@ class ProfilePage(FormView):
|
|||
widget=forms.Select(choices=[(True, "Visible"), (False, "Hidden")]),
|
||||
required=False,
|
||||
)
|
||||
metadata = forms.JSONField(
|
||||
label="Profile Metadata Fields",
|
||||
help_text="These values will appear on your profile below your Bio",
|
||||
widget=forms.HiddenInput,
|
||||
required=False,
|
||||
)
|
||||
|
||||
def get_initial(self):
|
||||
identity = self.request.identity
|
||||
|
@ -57,6 +63,7 @@ class ProfilePage(FormView):
|
|||
"image": identity.image and identity.image.url,
|
||||
"discoverable": identity.discoverable,
|
||||
"visible_follows": identity.config_identity.visible_follows,
|
||||
"metadata": identity.metadata,
|
||||
}
|
||||
|
||||
def form_valid(self, form):
|
||||
|
@ -78,6 +85,9 @@ class ProfilePage(FormView):
|
|||
image.name,
|
||||
resize_image(image, size=(1500, 500)),
|
||||
)
|
||||
metadata = form.cleaned_data.get("metadata")
|
||||
if metadata:
|
||||
identity.metadata = metadata
|
||||
identity.save()
|
||||
identity.transition_perform(IdentityStates.edited)
|
||||
|
||||
|
|
Loading…
Reference in New Issue