1
0
Fork 0

Merge pull request #1490 from hughrun/bookwyrm-groups

Bookwyrm groups
This commit is contained in:
Mouse Reeve 2021-10-17 07:54:59 -07:00 committed by GitHub
commit a27a55b40a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 2475 additions and 32 deletions

View file

@ -0,0 +1,12 @@
{% extends 'components/inline_form.html' %}
{% load i18n %}
{% block header %}
{% trans "Create Group" %}
{% endblock %}
{% block form %}
<form name="create-group" method="post" action="{% url 'user-groups' request.user.username %}">
{% include 'groups/form.html' with group_form=group_form %}
</form>
{% endblock %}

View file

@ -0,0 +1,6 @@
{% load i18n %}
{% spaceless %}
{% blocktrans with username=group.user.display_name path=group.user.local_path %}Managed by <a href="{{ path }}">{{ username }}</a>{% endblocktrans %}
{% endspaceless %}

View file

@ -0,0 +1,21 @@
{% extends 'components/modal.html' %}
{% load i18n %}
{% block modal-title %}{% trans "Delete this group?" %}{% endblock %}
{% block modal-body %}
{% trans "This action cannot be un-done" %}
{% endblock %}
{% block modal-footer %}
<form name="delete-group-{{ group.id }}" action="{% url 'delete-group' group.id %}" method="POST">
{% csrf_token %}
<input type="hidden" name="id" value="{{ group.id }}">
<button class="button is-danger" type="submit">
{% trans "Delete" %}
</button>
{% trans "Cancel" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="delete_group" controls_uid=group.id %}
</form>
{% endblock %}

View file

@ -0,0 +1,13 @@
{% extends 'components/inline_form.html' %}
{% load i18n %}
{% block header %}
{% trans "Edit Group" %}
{% endblock %}
{% block form %}
<form name="edit-group" method="post" action="{% url 'group' group.id %}">
{% include 'groups/form.html' %}
</form>
{% include "groups/delete_group_modal.html" with controls_text="delete_group" controls_uid=group.id %}
{% endblock %}

View file

@ -0,0 +1,9 @@
{% extends 'groups/group.html' %}
{% load i18n %}
{% block searchresults %}
<h2 class="title is-5">
{% trans "Add new members!" %}
</h2>
{% include 'groups/suggested_users.html' with suggested_users=suggested_users %}
{% endblock %}

View file

@ -0,0 +1,35 @@
{% load i18n %}
{% csrf_token %}
<div class="columns">
<div class="column is-two-thirds">
<input type="hidden" name="user" value="{{ request.user.id }}" />
<input type="hidden" name="privacy" value="public" />
<div class="field">
<label class="label" for="id_name">{% trans "Group Name:" %}</label>
{{ group_form.name }}
</div>
<div class="field">
<label class="label" for="id_description">{% trans "Group Description:" %}</label>
{{ group_form.description }}
</div>
</div>
</div>
<div class="columns is-mobile">
<div class="column">
<div class="field has-addons">
<div class="control">
{% include 'snippets/privacy_select.html' with current=group.privacy %}
</div>
<div class="control">
<button type="submit" class="button is-primary">{% trans "Save" %}</button>
</div>
</div>
</div>
{% if group.id %}
<div class="column is-narrow">
{% trans "Delete group" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with class="is-danger" text=button_text icon_with_text="x" controls_text="delete_group" controls_uid=group.id focus="modal_title_delete_group" %}
</div>
{% endif %}
</div>

View file

@ -0,0 +1,82 @@
{% extends 'groups/layout.html' %}
{% load i18n %}
{% load bookwyrm_tags %}
{% load markdown %}
{% block panel %}
<div class="columns mt-3">
<section class="column is-three-quarters">
{% if group.user == request.user %}
<div class="block">
<form class="field has-addons" method="get" action="{% url 'group-find-users' group.id %}">
<div class="control">
<input type="text" name="user_query" value="{{ request.GET.user_query }}" class="input" placeholder="{% trans 'Search to add a user' %}" aria-label="{% trans 'Search to add a user' %}">
</div>
<div class="control">
<button class="button" type="submit">
<span class="icon icon-search" title="{% trans 'Search' %}">
<span class="is-sr-only">{% trans "Search" %}</span>
</span>
</button>
</div>
</form>
</div>
{% endif %}
{% block searchresults %}
{% endblock %}
<div class="mb-2">
{% include "groups/members.html" with group=group %}
</div>
<h2 class="title is-5">Lists</h2>
{% if not lists %}
<p>{% trans "This group has no lists" %}</p>
{% else %}
<div class="columns is-multiline">
{% for list in lists %}
<div class="column is-one-third">
<div class="card is-stretchable">
<header class="card-header">
<h4 class="card-header-title">
<a href="{{ list.local_path }}">{{ list.name }}</a> <span class="subtitle">{% include 'snippets/privacy-icons.html' with item=list %}</span>
</h4>
</header>
{% with list_books=list.listitem_set.all|slice:5 %}
{% if list_books %}
<div class="card-image columns is-mobile is-gapless is-clipped">
{% for book in list_books %}
<a class="column is-cover" href="{{ book.book.local_path }}">
{% include 'snippets/book_cover.html' with book=book.book cover_class='is-h-s' size='small' aria='show' %}
</a>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<div class="card-content is-flex-grow-0">
<div class="is-clipped" {% if list.description %}title="{{ list.description }}"{% endif %}>
{% if list.description %}
{{ list.description|to_markdown|safe|truncatechars_html:30 }}
{% else %}
&nbsp;
{% endif %}
</div>
<p class="subtitle help">
{% include 'lists/created_text.html' with list=list %}
</p>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
{% include "snippets/pagination.html" with page=items %}
</section>
</div>
{% endblock %}

View file

@ -0,0 +1,32 @@
{% extends 'layout.html' %}
{% load i18n %}
{% block title %}{{ group.name }}{% endblock %}
{% block content %}
<header class="columns content is-mobile">
<div class="column">
<h1 class="title">{{ group.name }} <span class="subtitle">{% include 'snippets/privacy-icons.html' with item=group %}</span></h1>
<p class="subtitle help">
{% include 'groups/created_text.html' with group=group %}
</p>
</div>
<div class="column is-narrow is-flex">
{% if request.user == group.user %}
{% trans "Edit group" as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit_group" focus="edit_group_header" %}
{% endif %}
</div>
</header>
<div class="block content">
{% include 'snippets/trimmed_text.html' with full=group.description %}
</div>
<div class="block">
{% include 'groups/edit_form.html' with controls_text="edit_group" %}
</div>
{% block panel %}{% endblock %}
{% endblock %}

View file

@ -0,0 +1,47 @@
{% load i18n %}
{% load utilities %}
{% load humanize %}
{% load bookwyrm_tags %}
{% load bookwyrm_group_tags %}
<h2 class="title is-5">Group Members</h2>
<p class="subtitle is-6">{% trans "Members can add and remove books on a group's book lists" %}</p>
{% if group.user != request.user and group|is_member:request.user %}
<form action="{% url 'remove-group-member' %}" method="POST" class="my-4">
{% csrf_token %}
<input type="hidden" name="group" value="{{ group.id }}">
<input type="hidden" name="user" value="{{ user.username }}">
<button id="remove_self_button" class="button is-small is-danger is-light is-hidden" type="submit">
{% trans "Confirm" %}
</button>
<button id="hide_remove_self_button" data-controls="remove_self_button" class="button is-small" type="button" aria-pressed="false">
{% trans "Leave group" %}
</button>
</form>
{% endif %}
<div class="is-multiline is-flex is-flex-grow-0 is-flex-wrap-wrap">
{% for membership in group.memberships.all %}
{% with member=membership.user %}
<div class="box has-text-centered is-shadowless has-background-white-bis my-2 mx-2 member_{{ member.id }}">
<a href="{{ member.local_path }}" class="has-text-black">
{% include 'snippets/avatar.html' with user=member large=True %}
<span title="{{ member.display_name }}" class="is-block is-6 has-text-weight-bold">{{ member.display_name|truncatechars:10 }}</span>
<span title="@{{ member|username }}" class="is-block pb-3">@{{ member|username|truncatechars:8 }}</span>
</a>
{% if group.user == member %}
<span class="icon icon-star-full" title="Manager">
<span class="is-sr-only">Manager</span>
</span>
{% endif %}
{% include 'snippets/remove_from_group_button.html' with user=member group=group %}
{% if request.user in member.following.all %}
<p class="help">
{% trans "Follows you" %}
</p>
{% endif %}
</div>
{% endwith %}
{% endfor %}
</div>

View file

@ -0,0 +1,42 @@
{% load i18n %}
{% load utilities %}
{% load humanize %}
{% if suggested_users %}
<div class="column is-flex is-flex-grow-0">
{% for user in suggested_users %}
<div class="box has-text-centered is-shadowless has-background-white-bis m-2">
<a href="{{ user.local_path }}" class="has-text-black">
{% include 'snippets/avatar.html' with user=user large=True %}
<span title="{{ user.display_name }}" class="is-block is-6 has-text-weight-bold">{{ user.display_name|truncatechars:10 }}</span>
<span title="@{{ user|username }}" class="is-block pb-3">@{{ user|username|truncatechars:8 }}</span>
</a>
{% include 'snippets/add_to_group_button.html' with user=user group=group %}
{% if user.mutuals %}
<p class="help">
{% blocktrans trimmed with mutuals=user.mutuals|intcomma count counter=user.mutuals %}
{{ mutuals }} follower you follow
{% plural %}
{{ mutuals }} followers you follow{% endblocktrans %}
</p>
{% elif user.shared_books %}
<p class="help">
{% blocktrans trimmed with shared_books=user.shared_books|intcomma count counter=user.shared_books %}
{{ shared_books }} book on your shelves
{% plural %}
{{ shared_books }} books on your shelves
{% endblocktrans %}
</p>
{% elif request.user in user.following.all %}
<p class="help">
{% trans "Follows you" %}
</p>
{% endif %}
</div>
{% endfor %}
</div>
{% else %}
<p>No potential members found for "{{ user_query }}"</p>
<br/>
{% endif %}

View file

@ -0,0 +1,35 @@
{% load i18n %}
{% load markdown %}
{% load interaction %}
<div class="columns is-multiline">
{% for group in groups %}
<div class="column is-one-quarter">
<div class="card is-stretchable">
<header class="card-header">
<h4 class="card-header-title">
<a href="{{ group.local_path }}">{{ group.name }}</a> <span class="subtitle">{% include 'snippets/privacy-icons.html' with item=group %}</span>
</h4>
{% if group.user == user %}
<div class="card-header-icon">
{% trans "Manager" as text %}
<span class="icon icon-star-full has-text-grey" title="{{ text }}">
<span class="is-sr-only">{{ text }}</span>
</span>
</div>
{% endif %}
</header>
<div class="card-content is-flex-grow-0">
<div class="is-clipped" {% if group.description %}title="{{ group.description }}"{% endif %}>
{% if group.description %}
{{ group.description|to_markdown|safe|truncatechars_html:30 }}
{% else %}
&nbsp;
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>

View file

@ -6,7 +6,7 @@
{% endblock %}
{% block form %}
<form name="create-list" method="post" action="{% url 'lists' %}">
<form name="create-list" method="post" action="{% url 'lists' %}">
{% include 'lists/form.html' %}
</form>
{% endblock %}

View file

@ -1,7 +1,9 @@
{% load i18n %}
{% spaceless %}
{% if list.curation != 'open' %}
{% if list.curation == 'group' %}
{% blocktrans with username=list.user.display_name userpath=list.user.local_path groupname=list.group.name grouppath=list.group.local_path %}Created by <a href="{{ userpath }}">{{ username }}</a> and managed by <a href="{{ grouppath }}">{{ groupname }}</a>{% endblocktrans %}
{% elif list.curation != 'open' %}
{% blocktrans with username=list.user.display_name path=list.user.local_path %}Created and curated by <a href="{{ path }}">{{ username }}</a>{% endblocktrans %}
{% else %}
{% blocktrans with username=list.user.display_name path=list.user.local_path %}Created by <a href="{{ path }}">{{ username }}</a>{% endblocktrans %}

View file

@ -1,5 +1,6 @@
{% load i18n %}
{% csrf_token %}
{% load utilities %}
<input type="hidden" name="user" value="{{ request.user.id }}">
<div class="columns">
@ -17,20 +18,50 @@
<fieldset class="field">
<legend class="label">{% trans "List curation:" %}</legend>
<label class="field">
<label class="field" data-hides="list_group_selector">
<input type="radio" name="curation" value="closed"{% if not list or list.curation == 'closed' %} checked{% endif %}> {% trans "Closed" %}
<p class="help mb-2">{% trans "Only you can add and remove books to this list" %}</p>
</label>
<label class="field">
<label class="field" data-hides="list_group_selector">
<input type="radio" name="curation" value="curated"{% if list.curation == 'curated' %} checked{% endif %}> {% trans "Curated" %}
<p class="help mb-2">{% trans "Anyone can suggest books, subject to your approval" %}</p>
</label>
<label class="field">
<label class="field" data-hides="list_group_selector">
<input type="radio" name="curation" value="open"{% if list.curation == 'open' %} checked{% endif %}> {% trans "Open" context "curation type" %}
<p class="help mb-2">{% trans "Anyone can add books to this list" %}</p>
</label>
<label class="field hidden-form">
<input type="radio" name="curation" value="group"{% if list.curation == 'group' %} checked{% endif %} > {% trans "Group" %}
<p class="help mb-2">{% trans "Group members can add to and remove from this list" %}</p>
<fieldset class="{% if list.curation != 'group' %}is-hidden{% endif %}" id="list_group_selector">
{% if user.memberships.exists %}
<label class="label" for="id_group" id="group">{% trans "Select Group" %}</label>
<div class="field has-addons">
<div class="select control">
<select name="group" id="id_group">
<option value="" disabled {% if not list.group %} selected{% endif %}>{% trans "Select a group" %}</option>
{% for membership in user.memberships.all %}
<option value="{{ membership.group.id }}" {% if list.group.id == membership.group.id %} selected{% endif %}>{{ membership.group.name }}</option>
{% endfor %}
</select>
</div>
</div>
{% else %}
{% with user|username as username %}
{% url 'user-groups' user|username as url %}
<div>
<p>{% trans "You don't have any Groups yet!" %}</p>
<p>
<a class="help has-text-weight-normal" href="{{ url }}">{% trans "Create a Group" %}</a>
</p>
</div>
{% endwith %}
{% endif %}
</fieldset>
</label>
</fieldset>
</div>
</div>

View file

@ -25,7 +25,9 @@
</div>
<div class="block">
{% include 'lists/edit_form.html' with controls_text="edit_list" %}
{% if request.user == list.user %}
{% include 'lists/edit_form.html' with controls_text="edit_list" user_groups=user_groups %}
{% endif %}
</div>
{% block panel %}{% endblock %}

View file

@ -1,6 +1,7 @@
{% extends 'lists/layout.html' %}
{% load i18n %}
{% load bookwyrm_tags %}
{% load bookwyrm_group_tags %}
{% load markdown %}
{% block panel %}
@ -16,7 +17,7 @@
<section class="column is-three-quarters">
{% if request.GET.updated %}
<div class="notification is-primary">
{% if list.curation != "open" and request.user != list.user %}
{% if list.curation != "open" and request.user != list.user and not list.group|is_member:request.user %}
{% trans "You successfully suggested a book for this list!" %}
{% else %}
{% trans "You successfully added a book to this list!" %}
@ -66,7 +67,7 @@
<p>{% blocktrans with username=item.user.display_name user_path=item.user.local_path %}Added by <a href="{{ user_path }}">{{ username }}</a>{% endblocktrans %}</p>
</div>
</div>
{% if list.user == request.user %}
{% if list.user == request.user or list.group|is_member:request.user %}
<div class="card-footer-item">
<form name="set-position" method="post" action="{% url 'list-set-book-position' item.id %}">
{% csrf_token %}
@ -84,7 +85,7 @@
</form>
</div>
{% endif %}
{% if list.user == request.user or list.curation == 'open' and item.user == request.user %}
{% if list.user == request.user or list.curation == 'open' and item.user == request.user or list.group|is_member:request.user %}
<form name="remove-book" method="post" action="{% url 'list-remove-book' list.id %}" class="card-footer-item">
{% csrf_token %}
<input type="hidden" name="item" value="{{ item.id }}">
@ -125,7 +126,7 @@
</form>
{% if request.user.is_authenticated and not list.curation == 'closed' or request.user == list.user %}
<h2 class="title is-5 mt-6">
{% if list.curation == 'open' or request.user == list.user %}
{% if list.curation == 'open' or request.user == list.user or list.group|is_member:request.user %}
{% trans "Add Books" %}
{% else %}
{% trans "Suggest Books" %}
@ -178,7 +179,7 @@
{% csrf_token %}
<input type="hidden" name="book" value="{{ book.id }}">
<input type="hidden" name="list" value="{{ list.id }}">
<button type="submit" class="button is-small is-link">{% if list.curation == 'open' or request.user == list.user %}{% trans "Add" %}{% else %}{% trans "Suggest" %}{% endif %}</button>
<button type="submit" class="button is-small is-link">{% if list.curation == 'open' or request.user == list.user or list.group|is_member:request.user %}{% trans "Add" %}{% else %}{% trans "Suggest" %}{% endif %}</button>
</form>
</div>
</div>

View file

@ -22,10 +22,11 @@
</div>
{% endif %}
</header>
{% if request.user.is_authenticated %}
<div class="block">
{% include 'lists/create_form.html' with controls_text="create_list" %}
</div>
{% endif %}
{% if request.user.is_authenticated %}
<nav class="tabs">

View file

@ -17,4 +17,14 @@
{% include 'notifications/items/add.html' %}
{% elif notification.notification_type == 'REPORT' %}
{% include 'notifications/items/report.html' %}
{% elif notification.notification_type == 'INVITE' %}
{% include 'notifications/items/invite.html' %}
{% elif notification.notification_type == 'ACCEPT' %}
{% include 'notifications/items/accept.html' %}
{% elif notification.notification_type == 'JOIN' %}
{% include 'notifications/items/join.html' %}
{% elif notification.notification_type == 'LEAVE' %}
{% include 'notifications/items/leave.html' %}
{% elif notification.notification_type == 'REMOVE' %}
{% include 'notifications/items/remove.html' %}
{% endif %}

View file

@ -0,0 +1,20 @@
{% extends 'notifications/items/item_layout.html' %}
{% load i18n %}
{% load utilities %}
{% block primary_link %}{% spaceless %}
{{ notification.related_group.local_path }}
{% endspaceless %}{% endblock %}
{% block icon %}
<span class="icon icon-local"></span>
{% endblock %}
{% block description %}
{% blocktrans with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
accepted your invitation to join group "<a href="{{ group_path }}">{{ group_name }}</a>"
{% endblocktrans %}
{% endblock %}

View file

@ -0,0 +1,22 @@
{% extends 'notifications/items/item_layout.html' %}
{% load i18n %}
{% load utilities %}
{% block primary_link %}{% spaceless %}
{{ notification.related_group.local_path }}
{% endspaceless %}{% endblock %}
{% block icon %}
<span class="icon icon-local"></span>
{% endblock %}
{% block description %}
{% blocktrans trimmed with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
invited you to join the group <a href="{{ group_path }}">{{ group_name }}</a>
{% endblocktrans %}
<div class="row shrink">
{% include 'snippets/join_invitation_buttons.html' with group=notification.related_group %}
</div>
{% endblock %}

View file

@ -0,0 +1,23 @@
{% extends 'notifications/items/item_layout.html' %}
{% load i18n %}
{% load utilities %}
{% block primary_link %}{% spaceless %}
{{ notification.related_group.local_path }}
{% endspaceless %}{% endblock %}
{% block icon %}
<span class="icon icon-local"></span>
{% endblock %}
{% block description %}
{% blocktrans with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
has joined your group "<a href="{{ group_path }}">{{ group_name }}</a>"
{% endblocktrans %}
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends 'notifications/items/item_layout.html' %}
{% load i18n %}
{% load utilities %}
{% block primary_link %}{% spaceless %}
{{ notification.related_group.local_path }}
{% endspaceless %}{% endblock %}
{% block icon %}
<span class="icon icon-local"></span>
{% endblock %}
{% block description %}
{% blocktrans with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
has left your group "<a href="{{ group_path }}">{{ group_name }}</a>"
{% endblocktrans %}
{% endblock %}

View file

@ -0,0 +1,29 @@
{% extends 'notifications/items/item_layout.html' %}
{% load i18n %}
{% load utilities %}
{% block primary_link %}{% spaceless %}
{{ notification.related_group.local_path }}
{% endspaceless %}{% endblock %}
{% block icon %}
<span class="icon icon-local"></span>
{% endblock %}
{% block description %}
{% if notification.related_user %}
{% blocktrans with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
has been removed from your group "<a href="{{ group_path }}">{{ group_name }}</a>"
{% endblocktrans %}
{% else %}
{% blocktrans with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
You have been removed from the "<a href="{{ group_path }}">{{ group_name }}</a> group"
{% endblocktrans %}
{% endif %}
{% endblock %}

View file

@ -0,0 +1,34 @@
{% load i18n %}
{% load bookwyrm_group_tags %}
{% if request.user == user or not request.user == group.user or not request.user.is_authenticated %}
{% elif user in request.user.blocks.all %}
{% include 'snippets/block_button.html' with blocks=True %}
{% else %}
<div class="field mb-0">
<div class="control">
<form action="{% url 'invite-group-member' %}" method="POST" class="interaction add_{{ user.id }} {% if group|is_member:user or group|is_invited:user %}is-hidden{%endif %}" data-id="add_{{ user.id }}">
{% csrf_token %}
<input type="hidden" name="group" value="{{ group.id }}">
<input type="hidden" name="user" value="{{ user.username }}">
<button class="button is-small" type="submit">
{% trans "Invite" %}
</button>
</form>
<form action="{% url 'remove-group-member' %}" method="POST" class="interaction add_{{ user.id }} {% if not group|is_member:user and not group|is_invited:user %}is-hidden{% endif %}" data-id="add_{{ user.id }}">
{% csrf_token %}
<input type="hidden" name="group" value="{{ group.id }}">
<input type="hidden" name="user" value="{{ user.username }}">
{% if not group|is_member:user %}
<button class="button is-small is-danger is-light" type="submit">
{% trans "Uninvite" %}
</button>
{% else %}
<button class="button is-small is-danger is-light" type="submit">
{% blocktrans with username=user.localname %}Remove @{{ username }}{% endblocktrans %}
</button>
{% endif %}
</form>
</div>
</div>
{% endif %}

View file

@ -0,0 +1,16 @@
{% load i18n %}
{% load bookwyrm_group_tags %}
{% if group|is_invited:request.user %}
<div class="field is-grouped">
<form action="/accept-group-invitation/" method="POST">
{% csrf_token %}
<input type="hidden" name="group" value="{{ group.id }}">
<button class="button is-link is-small" type="submit">{% trans "Accept" %}</button>
</form>
<form action="/reject-group-invitation/" method="POST">
{% csrf_token %}
<input type="hidden" name="group" value="{{ group.id }}">
<button class="button is-danger is-light is-small" type="submit" class="warning">{% trans "Delete" %}</button>
</form>
</div>
{% endif %}

View file

@ -0,0 +1,24 @@
{% load i18n %}
{% load bookwyrm_group_tags %}
{% if request.user == user or not request.user == group.user or not request.user.is_authenticated %}
{% else %}
{% if user in request.user.blocks.all %}
{% include 'snippets/block_button.html' with blocks=True %}
<br/>
{% endif %}
<div class="fieldmb-0">
<div class="control">
<form action="{% url 'remove-group-member' %}" method="POST" class="has-text-centered">
{% csrf_token %}
<input type="hidden" name="group" value="{{ group.id }}">
<input type="hidden" name="user" value="{{ user.username }}">
<button id="submit_button" class="button is-small is-danger is-light is-hidden" type="submit" data-id="member_{{ member.id }}">
{% blocktrans with username=user.localname %} Confirm {% endblocktrans %}
</button>
<button id="hide_submit_button" data-controls="submit_button" class="button is-small" type="button" aria-pressed="false">
{% blocktrans with username=user.localname %} Remove {% endblocktrans %}
</button>
</form>
</div>
</div>
{% endif %}

View file

@ -0,0 +1,37 @@
{% extends 'user/layout.html' %}
{% load i18n %}
{% block header %}
<div class="columns is-mobile">
<div class="column">
<h1 class="title">
{% if is_self %}
{% trans "Your Groups" %}
{% else %}
{% blocktrans with username=user.display_name %}Groups: {{ username }}{% endblocktrans %}
{% endif %}
</h1>
</div>
{% if is_self %}
<div class="column is-narrow">
{% trans "Create group" as button_text %}
{% include 'snippets/toggle/open_button.html' with controls_text="create_group" icon_with_text="plus" text=button_text %}
</div>
{% endif %}
</div>
{% endblock %}
{% block panel %}
<section class="block">
<div class="block">
{% include 'groups/create_form.html' with controls_text="create_group" %}
</div>
{% include 'groups/user_groups.html' with memberships=memberships %}
</section>
<div>
{% include 'snippets/pagination.html' with page=user.memberships path=path %}
</div>
{% endblock %}

View file

@ -4,6 +4,7 @@
{% load utilities %}
{% load markdown %}
{% load layout %}
{% load bookwyrm_group_tags %}
{% block title %}{{ user.display_name }}{% endblock %}
@ -69,6 +70,12 @@
<a href="{{ url }}">{% trans "Reading Goal" %}</a>
</li>
{% endif %}
{% if is_self or user|has_groups %}
{% url 'user-groups' user|username as url %}
<li{% if url in request.path %} class="is-active"{% endif %}>
<a href="{{ url }}">{% trans "Groups" %}</a>
</li>
{% endif %}
{% if is_self or user.list_set.exists %}
{% url 'user-lists' user|username as url %}
<li{% if url in request.path %} class="is-active"{% endif %}>