Skip to content

Commit

Permalink
Merge pull request #237 from iragm/add-wysiwyg-editor
Browse files Browse the repository at this point in the history
Add wysiwyg editor
  • Loading branch information
iragm authored Oct 7, 2024
2 parents 6397c94 + 4c9e6ac commit 5c65557
Show file tree
Hide file tree
Showing 83 changed files with 3,080 additions and 86 deletions.
62 changes: 36 additions & 26 deletions auctions/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from django.utils import timezone
from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV2Invisible
from django_summernote.widgets import SummernoteWidget

from .models import (
Auction,
Expand Down Expand Up @@ -110,7 +111,7 @@ class Meta:
fields = [
"custom_lot_number",
"lot_name",
"description",
"summernote_description",
"species_category",
"i_bred_this_fish",
"quantity",
Expand All @@ -119,7 +120,16 @@ class Meta:
"buy_now_price",
]
widgets = {
"description": forms.Textarea(attrs={"rows": 2}),
"summernote_description": SummernoteWidget(
attrs={
"summernote": {
"width": "100%",
"height": "100px",
"toolbar": [],
}
}
),
# "description": forms.Textarea(attrs={"rows": 2}),
}

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -151,9 +161,11 @@ def __init__(self, *args, **kwargs):
if not self.auction.advanced_lot_adding:
self.fields["quantity"].initial = 1
self.fields["quantity"].widget = HiddenInput()
self.fields["description"].widget = HiddenInput()
# self.fields["description"].widget = HiddenInput()
self.fields["summernote_description"].widget = HiddenInput()
self.fields["custom_lot_number"].widget = HiddenInput()
self.fields["description"].help_text = ""
# self.fields["description"].help_text = ""
self.fields["summernote_description"].help_text = ""
if self.auction.reserve_price == "disable":
self.fields["reserve_price"].widget = HiddenInput()
if self.auction.reserve_price == "required":
Expand Down Expand Up @@ -587,7 +599,8 @@ def __init__(self, user, lot, auction, *args, **kwargs):
),
css_class="row",
),
"description",
# "description",
"summernote_description",
Div(
Div(
"i_bred_this_fish",
Expand Down Expand Up @@ -643,7 +656,8 @@ def __init__(self, user, lot, auction, *args, **kwargs):
else:
self.fields["custom_lot_number"].help_text = "Leave blank to automatically generate"
self.fields["lot_name"].initial = self.lot.lot_name
self.fields["description"].initial = self.lot.description
# self.fields["description"].initial = self.lot.description
self.fields["summernote_description"].initial = self.lot.summernote_description
# self.fields['auctiontos_seller'].initial = self.lot.auctiontos_seller
self.fields["quantity"].initial = self.lot.quantity
self.fields["donation"].initial = self.lot.donation
Expand Down Expand Up @@ -696,7 +710,8 @@ class Meta:
"custom_lot_number",
"auction",
"species_category",
"description",
# "description",
"summernote_description",
# 'auctiontos_seller',
"quantity",
"donation",
Expand All @@ -708,7 +723,8 @@ class Meta:
"winning_price",
]
widgets = {
"description": forms.Textarea(attrs={"rows": 2}),
"summernote_description": SummernoteWidget(attrs={"summernote": {"width": "100%", "height": "300px"}}),
# "description": forms.Textarea(attrs={"rows": 2}),
# 'auctiontos_seller': autocomplete.ModelSelect2(url='auctiontos-autocomplete', forward=['auction'], attrs={'data-html': True, 'data-container-css-class': ''}),
"auctiontos_winner": autocomplete.ModelSelect2(
url="auctiontos-autocomplete",
Expand Down Expand Up @@ -1518,7 +1534,7 @@ class AuctionEditForm(forms.ModelForm):
class Meta:
model = Auction
fields = [
"notes",
"summernote_description",
"lot_entry_fee",
"unsold_lot_fee",
"winning_bid_percent_to_club",
Expand Down Expand Up @@ -1559,15 +1575,15 @@ class Meta:
"lot_submission_end_date": DateTimePickerInput(),
"date_online_bidding_ends": DateTimePickerInput(),
"date_online_bidding_starts": DateTimePickerInput(),
"notes": forms.Textarea(),
"summernote_description": SummernoteWidget(),
}

def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
self.cloned_from = kwargs.pop("cloned_from")
timezone.activate(kwargs.pop("user_timezone"))
super().__init__(*args, **kwargs)
self.fields["notes"].widget.attrs = {"rows": 10}
# self.fields["summernote_description"].widget.attrs = {"rows": 10}
self.fields["winning_bid_percent_to_club"].label = "Club cut"
self.fields["winning_bid_percent_to_club_for_club_members"].label = "Club cut (members)"
self.fields["date_start"].label = "Bidding opens"
Expand Down Expand Up @@ -1609,22 +1625,13 @@ def __init__(self, *args, **kwargs):
self.fields["user_cut"].initial = 100 - self.instance.winning_bid_percent_to_club
self.fields["club_member_cut"].initial = 100 - self.instance.winning_bid_percent_to_club_for_club_members

# if self.instance.pk:
# # editing existing auction
# pass
# else:
# # this is a new auction
# if not self.cloned_from:
# self.fields[
# "notes"
# ].initial = "## General information\n\nYou should remove this line and edit this section to suit your auction. Use the formatting here as an example.\n\n## Prohibited items\n- You cannot sell any fish or plants banned by state law.\n- You cannot sell large hardware items such as tanks.\n\n## Rules\n- All lots must be properly bagged. No leaking bags!\n- You do not need to be a club member to buy or sell lots."
self.helper = FormHelper()
self.helper.form_method = "post"
self.helper.form_id = "auction-form"
self.helper.form_class = "form"
self.helper.form_tag = True
self.helper.layout = Layout(
"notes",
"summernote_description",
HTML("<h4>Dates</h4>"),
Div(
Div(
Expand Down Expand Up @@ -1861,7 +1868,8 @@ class Meta:
"relist_if_not_sold",
"lot_name",
"i_bred_this_fish",
"description",
"summernote_description",
# "description",
"quantity",
"reserve_price",
"species_category",
Expand All @@ -1884,7 +1892,7 @@ class Meta:
)
exclude = ["user", "image", "image_source"]
widgets = {
"description": forms.Textarea(),
"summernote_description": SummernoteWidget(),
# 'species': forms.HiddenInput(),
# 'cloned_from': forms.HiddenInput(),
"shipping_locations": forms.CheckboxSelectMultiple(),
Expand All @@ -1895,7 +1903,7 @@ def __init__(self, *args, **kwargs):
self.cloned_from = kwargs.pop("cloned_from")
self.auction = kwargs.pop("auction")
super().__init__(*args, **kwargs)
self.fields["description"].widget.attrs = {"rows": 3}
# self.fields["description"].widget.attrs = {"rows": 3}
# self.fields['species_category'].required = True
self.fields["auction"].queryset = (
Auction.objects.exclude(is_deleted=True)
Expand Down Expand Up @@ -1940,7 +1948,8 @@ def __init__(self, *args, **kwargs):
"lot_name",
"quantity",
"species_category",
"description",
# "description",
"summernote_description",
"i_bred_this_fish",
"reserve_price",
"buy_now_price",
Expand Down Expand Up @@ -2074,7 +2083,8 @@ def __init__(self, *args, **kwargs):
# Div('image',css_class='col-md-8',),
# Div('image_source',css_class='col-md-4',),
Div(
"description",
# "description",
"summernote_description",
css_class="col-md-12",
),
css_class="row",
Expand Down
17 changes: 17 additions & 0 deletions auctions/migrations/0151_lot_summernote_description.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1 on 2024-10-06 23:16

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("auctions", "0150_auction_invoice_rounding_and_more"),
]

operations = [
migrations.AddField(
model_name="lot",
name="summernote_description",
field=models.CharField(default="", max_length=2000, verbose_name="Description"),
),
]
25 changes: 25 additions & 0 deletions auctions/migrations/0152_copy_description.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.1 on 2024-10-07 12:56

from django.db import migrations, models


def copy_description(apps, schema_editor):
Lot = apps.get_model("auctions", "Lot")
for lot in Lot.objects.all():
lot.summernote_description = lot.description_rendered[:10000] or ""
lot.save()


class Migration(migrations.Migration):
dependencies = [
("auctions", "0151_lot_summernote_description"),
]

operations = [
migrations.AlterField(
model_name="lot",
name="summernote_description",
field=models.CharField(blank=True, default="", max_length=10000, verbose_name="Description"),
),
migrations.RunPython(copy_description),
]
25 changes: 25 additions & 0 deletions auctions/migrations/0153_auction_summernote_description.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.1 on 2024-10-07 15:27

from django.db import migrations, models


def copy_notes(apps, schema_editor):
Auction = apps.get_model("auctions", "Auction")
for auction in Auction.objects.all():
auction.summernote_description = auction.notes_rendered[:10000] or ""
auction.save()


class Migration(migrations.Migration):
dependencies = [
("auctions", "0152_copy_description"),
]

operations = [
migrations.AddField(
model_name="auction",
name="summernote_description",
field=models.CharField(blank=True, default="", max_length=10000, verbose_name="Rules"),
),
migrations.RunPython(copy_notes),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 5.1 on 2024-10-07 16:47

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("auctions", "0153_auction_summernote_description"),
]

operations = [
migrations.RemoveField(
model_name="auction",
name="notes",
),
migrations.RemoveField(
model_name="auction",
name="notes_rendered",
),
migrations.RemoveField(
model_name="lot",
name="description",
),
migrations.RemoveField(
model_name="lot",
name="description_rendered",
),
]
44 changes: 23 additions & 21 deletions auctions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,16 +550,17 @@ class Auction(models.Model):
created_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL)
location = models.CharField(max_length=300, null=True, blank=True)
location.help_text = "State or region of this auction"
notes = MarkdownField(
rendered_field="notes_rendered",
validator=VALIDATOR_STANDARD,
blank=True,
null=True,
verbose_name="Rules",
default="",
)
notes.help_text = "To add a link: [Link text](https://www.google.com)"
notes_rendered = RenderedMarkdownField(blank=True, null=True)
summernote_description = models.CharField(max_length=10000, verbose_name="Rules", default="", blank=True)
# notes = MarkdownField(
# rendered_field="notes_rendered",
# validator=VALIDATOR_STANDARD,
# blank=True,
# null=True,
# verbose_name="Rules",
# default="",
# )
# notes.help_text = "To add a link: [Link text](https://www.google.com)"
# notes_rendered = RenderedMarkdownField(blank=True, null=True)
code_to_add_lots = models.CharField(max_length=255, blank=True, null=True)
code_to_add_lots.help_text = (
"This is like a password: People in your club will enter this code to put their lots in this auction"
Expand Down Expand Up @@ -1209,7 +1210,7 @@ def admin_checklist_location_set(self):

@property
def admin_checklist_rules_updated(self):
if "You should remove this line and edit this section to suit your auction." in self.notes:
if "You should remove this line and edit this section to suit your auction." in self.summernote_description:
return False
return True

Expand Down Expand Up @@ -1949,14 +1950,15 @@ class Lot(models.Model):
image_source.help_text = "Where did you get this image?"
i_bred_this_fish = models.BooleanField(default=False, verbose_name="I bred this fish/propagated this plant")
i_bred_this_fish.help_text = "Check to get breeder points for this lot"
description = MarkdownField(
rendered_field="description_rendered",
validator=VALIDATOR_STANDARD,
blank=True,
null=True,
)
description.help_text = "To add a link: [Link text](https://www.google.com)"
description_rendered = RenderedMarkdownField(blank=True, null=True)
summernote_description = models.CharField(max_length=10000, verbose_name="Description", default="", blank=True)
# description = MarkdownField(
# rendered_field="description_rendered",
# validator=VALIDATOR_STANDARD,
# blank=True,
# null=True,
# )
# description.help_text = "To add a link: [Link text](https://www.google.com)"
# description_rendered = RenderedMarkdownField(blank=True, null=True)
reference_link = models.URLField(blank=True, null=True)
reference_link.help_text = (
"A URL with additional information about this lot. YouTube videos will be automatically embedded."
Expand Down Expand Up @@ -2536,7 +2538,7 @@ def cannot_be_edited_reason(self):
if self.auction:
# if this lot is part of an auction, allow changes right up until lot submission ends
if timezone.now() > self.auction.lot_submission_end_date:
return "Lot submission is over for thsi auction"
return "Lot submission is over for this auction"
# if we are getting here, there are no bids or this lot is not part of an auction
# lots that are not part of an auction can always be edited as long as there are no bids
return False
Expand All @@ -2545,7 +2547,7 @@ def cannot_be_edited_reason(self):
def can_be_edited(self):
"""Check to see if this lot can be edited.
This is needed to prevent people making lots a donation right before the auction ends
Actually, by request from many people, there's nothing at all prventing that right at this moment..."""
Actually, by request from many people, there's nothing at all preventing that right at this moment..."""
if self.cannot_be_edited_reason:
return False
return True
Expand Down
Loading

0 comments on commit 5c65557

Please sign in to comment.