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

Save documents #1892

Merged
merged 49 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
2d5fbb5
merged with master
Sandravaphilips Jul 5, 2024
44c5651
save document to collection
Sandravaphilips Jul 17, 2024
34c194d
add new collection
Sandravaphilips Jul 18, 2024
8a7ecf1
merge with master
Sandravaphilips Jul 23, 2024
5f5a1fa
unsave document
Sandravaphilips Jul 23, 2024
7531f99
updates login templates; checks for authenticated user before saving …
actlikewill Jul 24, 2024
1d8fc1f
used one modal to save document
Sandravaphilips Jul 24, 2024
2c8eea7
adds google login button; template changes
actlikewill Jul 25, 2024
803762b
adds messages template
actlikewill Jul 25, 2024
b8f2452
adds missing translation
actlikewill Jul 25, 2024
7d98ccb
fixes social login button
actlikewill Jul 25, 2024
d2c365d
Merge branch 'sandrava-1690' into auth-updates
actlikewill Jul 25, 2024
aafac5a
fixes create new folder
actlikewill Jul 25, 2024
26232db
Merge pull request #1932 from laws-africa/auth-updates
actlikewill Jul 25, 2024
4bb2dd4
adds recaptcha; allows management of savedoc feature
actlikewill Jul 30, 2024
bb47800
adds migration
actlikewill Jul 30, 2024
f1160f2
removes save document modal
actlikewill Jul 31, 2024
b56bd53
adds recaptcha to dependencies
actlikewill Jul 31, 2024
4e35b40
view saved documents
Sandravaphilips Aug 2, 2024
10dcc83
merge with master
Sandravaphilips Aug 2, 2024
9cb6a12
Merge branch 'sandrava-1690' of https://github.com/laws-africa/peachj…
Sandravaphilips Aug 2, 2024
6499f5b
merge with master
Sandravaphilips Aug 13, 2024
803f958
added csrf token
Sandravaphilips Aug 13, 2024
d4d4d7d
Merge branch 'main' into sandrava-1690
actlikewill Aug 13, 2024
23af6ad
changes user_profile to user model
actlikewill Aug 14, 2024
ce7da57
splits saved document views
actlikewill Aug 15, 2024
1f417af
tweaks saved doc message
actlikewill Aug 15, 2024
384ea67
uses generic views for saving documents
actlikewill Aug 15, 2024
185cc27
fixes saved document generic views
actlikewill Aug 15, 2024
7c2bb6a
loads save button dynamically to preserve caching
actlikewill Aug 16, 2024
5ef6fc3
adds all users group
actlikewill Aug 16, 2024
e210472
updates saved document views
actlikewill Aug 18, 2024
7c3d3ea
fixes saved document urls names
actlikewill Aug 18, 2024
1d4d3df
renames folder list template
actlikewill Aug 18, 2024
4332319
renames new to create
actlikewill Aug 18, 2024
0fffd74
updates saved document form view
actlikewill Aug 18, 2024
5ce4d0e
fixes saved document button for unauthenticated user
actlikewill Aug 18, 2024
96f831a
sets initial value for document in create view
actlikewill Aug 18, 2024
87a41c8
adds allowed saving documents mixin; sets user in create view instance
actlikewill Aug 19, 2024
dc937ff
fetches csrf token asynchronously
actlikewill Aug 19, 2024
8c1c568
adds saved documents to never cache
actlikewill Aug 19, 2024
ee6c299
fixes folder form inheritance
actlikewill Aug 27, 2024
786060d
updates saved document template
actlikewill Aug 30, 2024
07e2944
removes migration files
actlikewill Aug 30, 2024
1a2d2fd
Merge branch 'main' into sandrava-1690
actlikewill Aug 30, 2024
8ed67a5
adds migration files
actlikewill Aug 30, 2024
34444bd
renames basefolderview to basefoldermixin
actlikewill Aug 30, 2024
712f7d3
removes csrf token from header
actlikewill Aug 30, 2024
d436b90
removes csrf token from folder
actlikewill Aug 30, 2024
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
4 changes: 4 additions & 0 deletions peachjam/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
DocumentTopic,
EntityProfile,
ExternalDocument,
Folder,
Gazette,
GenericDocument,
Image,
Expand All @@ -71,6 +72,7 @@
PeachJamSettings,
Predicate,
Relationship,
SavedDocument,
SourceFile,
Taxonomy,
UserProfile,
Expand Down Expand Up @@ -1231,6 +1233,8 @@ class AttorneyAdmin(ImportExportMixin, admin.ModelAdmin):
CourtClass,
AttachedFileNature,
CitationProcessing,
Folder,
SavedDocument,
]
)
admin.site.register(PeachJamSettings, PeachJamSettingsAdmin)
Expand Down
50 changes: 48 additions & 2 deletions peachjam/forms.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import copy

from allauth.account.forms import LoginForm, SignupForm
from django import forms
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.core.files import File
from django.core.mail import send_mail
from django.http import QueryDict
from django.template.loader import render_to_string
from django.utils.translation import gettext as _

from peachjam.models import AttachedFiles, CoreDocument, SourceFile, pj_settings
from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV2Invisible

from peachjam.models import (
AttachedFiles,
CoreDocument,
Folder,
SavedDocument,
SourceFile,
pj_settings,
)
from peachjam.plugins import plugins
from peachjam.storage import clean_filename

User = get_user_model()


def work_choices():
return [("", "---")] + [
Expand Down Expand Up @@ -301,3 +314,36 @@ def send_email(self):
html_message=html,
fail_silently=False,
)


class SaveDocumentForm(forms.ModelForm):
new_folder = forms.CharField(max_length=255, required=False)

class Meta:
model = SavedDocument
fields = ["document", "folder", "new_folder"]
widgets = {"document": forms.HiddenInput()}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["folder"].queryset = self.instance.user.folders.all()
self.fields["document"].required = False

def clean(self):
cleaned_data = super().clean()
cleaned_data["document"] = self.instance.document
if cleaned_data.get("new_folder"):
folder, _ = Folder.objects.get_or_create(
name=cleaned_data["new_folder"],
user=self.instance.user,
)
cleaned_data["folder"] = folder
return cleaned_data


class PeachjamSignupForm(SignupForm):
captcha = ReCaptchaField(widget=ReCaptchaV2Invisible)


class PeachjamLoginForm(LoginForm):
captcha = ReCaptchaField(widget=ReCaptchaV2Invisible)
22 changes: 20 additions & 2 deletions peachjam/js/peachjam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import '@lawsafrica/law-widgets/dist/components/la-decorate-internal-refs';
import '@lawsafrica/law-widgets/dist/components/la-decorate-terms';
// @ts-ignore
import htmx from 'htmx.org';
import { csrfToken } from './api';

export interface PeachJamConfig {
appName: string;
Expand Down Expand Up @@ -65,8 +66,9 @@ class PeachJam {
window.htmx = htmx;
// htmx:load is fired both when the page loads (weird) and when new content is loaded. We only care about the latter
// case. See https://github.com/bigskysoftware/htmx/issues/1500
const htmxHelper = { firstLoad: true};
document.body.addEventListener('htmx:load', (e) => {
const htmxHelper = { firstLoad: true };
let token: string = '';
document.body.addEventListener('htmx:load', async (e) => {
if (htmxHelper.firstLoad) {
htmxHelper.firstLoad = false;
return;
Expand All @@ -75,6 +77,22 @@ class PeachJam {
this.createComponents(e.target as HTMLElement);
this.createVueComponents(e.target as HTMLElement);
});

htmx.on('htmx:confirm', (e:any) => {
if (e.detail.verb === 'post') {
e.preventDefault();
csrfToken().then((t) => {
token = t;
e.detail.issueRequest();
});
}
});

htmx.on('htmx:configRequest', (e: any) => {
if (e.detail.verb === 'post') {
e.detail.headers['X-CSRFToken'] = token;
}
});
}

createComponents (root: HTMLElement) {
Expand Down
1 change: 1 addition & 0 deletions peachjam/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class GeneralUpdateCacheMiddleware(UpdateCacheMiddleware):
"/admin/",
"/accounts/",
"/api/",
"/saved-documents/",
"/_",
]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Generated by Django 4.2.15 on 2024-08-30 04:10

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("peachjam", "0150_peachjamsettings_survey_link_and_more"),
]

operations = [
migrations.CreateModel(
name="Folder",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=100, verbose_name="name")),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="folders",
to=settings.AUTH_USER_MODEL,
verbose_name="user",
),
),
],
options={
"verbose_name": "folder",
"verbose_name_plural": "folders",
"ordering": ("name",),
},
),
migrations.AddField(
model_name="peachjamsettings",
name="allow_save_documents",
field=models.BooleanField(
default=False,
help_text="Allow documents to be saved.",
verbose_name="allow save documents",
),
),
migrations.CreateModel(
name="SavedDocument",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"document",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="peachjam.coredocument",
),
),
(
"folder",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="saved_documents",
to="peachjam.folder",
verbose_name="folder",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="saved_documents",
to=settings.AUTH_USER_MODEL,
verbose_name="user",
),
),
],
options={
"verbose_name": "saved document",
"verbose_name_plural": "saved documents",
"ordering": ("document__title",),
"unique_together": {("document", "folder")},
},
),
]
1 change: 1 addition & 0 deletions peachjam/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
from .judgment import *
from .profile import *
from .relationships import *
from .save_document import *
from .settings import *
from .taxonomies import *
49 changes: 49 additions & 0 deletions peachjam/models/save_document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from django.contrib.auth import get_user_model
from django.db import models
from django.utils.translation import gettext_lazy as _

from .core_document_model import CoreDocument

User = get_user_model()


class Folder(models.Model):
name = models.CharField(_("name"), max_length=100)
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
verbose_name=_("user"),
related_name="folders",
)

class Meta:
ordering = ("name",)
verbose_name = _("folder")
verbose_name_plural = _("folders")

def __str__(self):
return f"{self.name}"


class SavedDocument(models.Model):
document = models.ForeignKey(CoreDocument, on_delete=models.CASCADE)
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
verbose_name=_("user"),
related_name="saved_documents",
)
folder = models.ForeignKey(
Folder,
on_delete=models.CASCADE,
verbose_name=_("folder"),
null=True,
blank=True,
related_name="saved_documents",
)

class Meta:
ordering = ("document__title",)
verbose_name = _("saved document")
verbose_name_plural = _("saved documents")
unique_together = ("document", "folder")
5 changes: 5 additions & 0 deletions peachjam/models/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ class PeachJamSettings(SingletonModel):
null=True,
blank=True,
)
allow_save_documents = models.BooleanField(
verbose_name=_("allow save documents"),
default=False,
help_text=_("Allow documents to be saved."),
)

class Meta:
verbose_name = verbose_name_plural = _("site settings")
Expand Down
23 changes: 20 additions & 3 deletions peachjam/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import dj_database_url
import sentry_sdk
from django.contrib.messages import constants as messages
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from sentry_sdk.integrations.django import DjangoIntegration
Expand Down Expand Up @@ -80,6 +81,7 @@
"martor",
"corsheaders",
"django_htmx",
"django_recaptcha",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -151,16 +153,20 @@
]
# admins must create accounts
ACCOUNT_SIGNUP_ENABLED = False
# sign in with email addresses
ACCOUNT_AUTHENTICATION_METHOD = "email"
# email addresses are required for new accounts
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_PRESERVE_USERNAME_CASING = False
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_EMAIL_SUBJECT_PREFIX = EMAIL_SUBJECT_PREFIX
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "http" if DEBUG else "https"
LOGIN_URL = "account_login"
LOGIN_REDIRECT_URL = "home_page"
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
longhotsummer marked this conversation as resolved.
Show resolved Hide resolved
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_FORMS = {
"signup": "peachjam.forms.PeachjamSignupForm",
"login": "peachjam.forms.PeachjamLoginForm",
}

# social logins
SOCIALACCOUNT_PROVIDERS = {
Expand All @@ -177,6 +183,13 @@

SOCIALACCOUNT_ADAPTER = "peachjam.auth.SocialAccountAdapter"

# Recaptcha
RECAPTCHA_PUBLIC_KEY = os.environ.get("RECAPTCHA_PUBLIC_KEY", "")
RECAPTCHA_PRIVATE_KEY = os.environ.get("RECAPTCHA_PRIVATE_KEY", "")
if DEBUG:
SILENCED_SYSTEM_CHECKS = ["django_recaptcha.recaptcha_test_key_error"]


if DEBUG:
INSTALLED_APPS.append("debug_toolbar")
INSTALLED_APPS.append("django_extensions")
Expand Down Expand Up @@ -626,3 +639,7 @@ def before_send(event, hint):
# CORS
# disable regex matches, we do matching using signals
CORS_URLS_REGEX = r"^$"

MESSAGE_TAGS = {
messages.ERROR: "danger",
}
Loading
Loading