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

CONCD-654 Merge Feature branch into Main #2276

Merged
merged 62 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
4ccbee8
CONCD-488 Delete Quick Tips module, but keep Simple Content Blocks (f…
rasarkar Sep 7, 2023
66d46d8
CONCD-492 Create database tables for Tutorial slides (Requires DB Mig…
rasarkar Sep 12, 2023
e09273b
CONCD-488 Delete Quick Tips module in Django admin (#2084)
rasarkar Sep 12, 2023
c830d1d
CONCD-491 post_save signal handler (#2094)
rasarkar Sep 13, 2023
f2c1363
CONCD-531 conflicting migrations (#2105)
rasarkar Sep 19, 2023
bff228a
CONCD-482 Build Tutorial popup and cards navigation (WiP)
rasarkar Oct 2, 2023
1363a58
CONCD-482 Modal dialog (WiP)
rasarkar Oct 2, 2023
34ee5d4
CONCD-480 Create manual link for opening tutorial (#2119)
rasarkar Oct 3, 2023
0959d5b
CONCD-482 dialog layout (WiP)
rasarkar Oct 3, 2023
85de00f
CONCD-482 Work in Progress
rasarkar Oct 4, 2023
bf23590
CONCD-482 Bootstrap carousel
rasarkar Oct 4, 2023
d5463dd
CONCD-482 Carousel styling (WiP)
rasarkar Oct 11, 2023
418a7df
CONCD-482 header, close button
rasarkar Oct 12, 2023
9ae6d55
CONCD-482 style fixes
rasarkar Oct 12, 2023
0762ac9
CONCD-482 card images
rasarkar Oct 13, 2023
dbfd607
CONCD-482 The first card should not have a Back button
rasarkar Oct 13, 2023
ed7de8b
CONCD-482 Borders
rasarkar Oct 13, 2023
c60a942
CONCD-480 Link text should be bolded, cursor should change to a hand …
rasarkar Oct 16, 2023
1f5dafc
CONCD-482 Change Meta options on Card (ordering) and Tutorial Card (v…
rasarkar Oct 16, 2023
d26077b
CONCD-482 field order
rasarkar Oct 16, 2023
e60b122
CONCD-480 Link should be underlined (#2134)
rasarkar Oct 17, 2023
a24d124
CONCD-530 Add rich text editor for django admin fields (WiP)
rasarkar Oct 17, 2023
a7734d4
CONCD-530 added django-tinymce to Pipfile.lock
rasarkar Oct 17, 2023
8273761
CONCD-530 all of Pipfile.lock needs to be updated (instead of just ad…
rasarkar Oct 17, 2023
3bd7e81
CONCD-530 still getting the Pipfile.lock error
rasarkar Oct 17, 2023
2375a9c
CONCD-483 Implement tutorial popup rules based on session activity an…
rasarkar Oct 18, 2023
e1e4486
CONCD-483 show modal
rasarkar Oct 18, 2023
2dd0d91
CONCD-483 if user is not logged in, remove key from local storage
rasarkar Oct 18, 2023
82919a9
CONCD-483 if an anonymouse user navigates to another page in the site…
rasarkar Oct 19, 2023
0a28e1e
CONCD-483 moved session code to base template
rasarkar Oct 19, 2023
c89a586
CONCD-530 numlist, searchreplace, wordcount
rasarkar Oct 20, 2023
5f9c980
CONCD-483 fixed an issue (#2155)
rasarkar Oct 30, 2023
ebec638
CONCD-576 When adding cards to a family, display card title (rather t…
rasarkar Nov 16, 2023
5d24e30
CONCD-590 database migrations (#2186)
rasarkar Nov 17, 2023
92c3c1c
CONCD-590 cherry-picked a commit with missing libraries (#2194)
rasarkar Nov 17, 2023
1286398
CONCD-576 trigger when popup is dismissed (#2197)
rasarkar Nov 21, 2023
5dfc87f
CONCD-629 Create data model for How To Guide (#2208)
rasarkar Dec 4, 2023
5be2dd9
CONCD-630 Create database tables for How To Guide (#2218)
rasarkar Dec 20, 2023
e7d0805
CONCD-588 Add card display heading, create date, and campaign fields …
rasarkar Jan 9, 2024
de6371d
Initial implementation of maintenance mode (#2227) (#2231)
rasarkar Jan 12, 2024
d956228
CONCD-592 (#2233)
rasarkar Jan 16, 2024
81a5dfc
CONCD-650 Build front end for How To Guide (#2235)
rasarkar Jan 22, 2024
25cbdb2
CONCD-650 A couple things (#2243)
rasarkar Jan 23, 2024
6f76501
CONCD-651 Share data between simple pages and guides (#2242)
rasarkar Jan 23, 2024
e808d4e
CONCD-650 Initial feedback (#2245)
rasarkar Jan 26, 2024
2a2cc5c
Modified daily data backfill functions to split them using tasks and …
rasarkar Jan 26, 2024
f41d5b4
CONCD-675 Refactor simple pages (#2250)
rasarkar Jan 29, 2024
91cc166
CONCD-674 display heading data has not yet been added (#2251)
rasarkar Jan 31, 2024
a3775ef
CONCD-674 display heading should not be larger than the title (#2254)
rasarkar Jan 31, 2024
cee62e2
CONCD-650 A few more mostly small tweaks (#2255)
rasarkar Feb 2, 2024
c13393b
CONCD-675 pull content for Simple Page from the corresponding Guide (…
rasarkar Feb 5, 2024
fc6900f
CONCD-588 Card fields (#2262)
rasarkar Feb 5, 2024
1ad4487
CONCD-675 How to transcribe (#2264)
rasarkar Feb 6, 2024
7d240f3
CONCD-675 reverting this change (will no longer be needed) (#2267)
rasarkar Feb 6, 2024
9490857
CONCD-674 rsar reduce padding (#2270)
rasarkar Feb 7, 2024
66c8648
CONCD-650 move title bar out of carousel (#2272)
rasarkar Feb 7, 2024
54ab2dd
CONCD-675 include intro text from simple page body (#2273)
rasarkar Feb 9, 2024
07d5a98
Concd 650 rsar guide tweaks (#2274)
rasarkar Feb 9, 2024
9c67655
CONCD-654 squashed migrations
rasarkar Feb 13, 2024
96e2cc5
CONCD-654 resolved conflicts
rasarkar Feb 13, 2024
38ed724
CONCD-654 these are now controlled through the admin, and should no l…
rasarkar Feb 13, 2024
09030ab
CONCD-654 removed all prettier and stylelint libraries from package.json
rasarkar Feb 13, 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
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ django-admin-multiple-choice-list-filter = "*"
django-npm = "*"
fpdf2 = "==2.5.5"
pymemcache = "*"
black = ">=24"
weasyprint = "*"
tesseract = "==0.1.3"
pytesseract = "*"
Expand Down
190 changes: 144 additions & 46 deletions Pipfile.lock

Large diffs are not rendered by default.

50 changes: 35 additions & 15 deletions concordia/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,20 @@
Banner,
Campaign,
CampaignRetirementProgress,
Card,
CardFamily,
CarouselSlide,
Guide,
Item,
Project,
Resource,
ResourceFile,
SimpleContentBlock,
SimplePage,
SiteReport,
Tag,
Topic,
Transcription,
TutorialCard,
UserAssetTagCollection,
UserProfileActivity,
)
Expand All @@ -61,6 +64,7 @@
AssetCampaignListFilter,
AssetCampaignStatusListFilter,
AssetProjectListFilter,
CardCampaignListFilter,
ItemCampaignListFilter,
ItemCampaignStatusListFilter,
ItemProjectListFilter,
Expand All @@ -86,9 +90,10 @@
from .forms import (
AdminItemImportForm,
CampaignAdminForm,
CardAdminForm,
GuideAdminForm,
ProjectAdminForm,
SanitizedDescriptionAdminForm,
SimpleContentBlockAdminForm,
)

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -193,6 +198,7 @@ class CampaignAdmin(admin.ModelAdmin, CustomListDisplayFieldsMixin):
)
list_display_links = ("title",)
prepopulated_fields = {"slug": ("title",)}
raw_id_fields = ("card_family",)
search_fields = ["title", "description"]
list_filter = (
"published",
Expand Down Expand Up @@ -793,19 +799,6 @@ def export_to_excel(self, request, queryset):
actions = (export_to_csv, export_to_excel)


@admin.register(SimpleContentBlock)
class SimpleContentBlockAdmin(admin.ModelAdmin):
form = SimpleContentBlockAdminForm

list_display = ("slug", "created_on", "updated_on")
readonly_fields = ("created_on", "updated_on")

fieldsets = (
(None, {"fields": ("created_on", "updated_on", "slug")}),
("Body", {"classes": ("markdown-preview",), "fields": ("body",)}),
)


@admin.register(CarouselSlide)
class CarouselSlideAdmin(admin.ModelAdmin):
list_display = ("headline", "published", "ordering")
Expand Down Expand Up @@ -991,3 +984,30 @@ def completion(self, obj):
total = obj.project_total + obj.item_total + obj.asset_total
removed = obj.projects_removed + obj.items_removed + obj.assets_removed
return "{}%".format(round(removed / total * 100, 2))


@admin.register(Card)
class CardAdmin(admin.ModelAdmin):
form = CardAdminForm
fields = ("title", "display_heading", "body_text", "image", "image_alt_text")
list_display = ["title", "created_on", "updated_on"]
list_filter = (CardCampaignListFilter, "updated_on")


class TutorialInline(admin.TabularInline):
model = TutorialCard
extra = 1
raw_id_fields = ("card",)


@admin.register(CardFamily)
class CardFamilyAdmin(admin.ModelAdmin):
inlines = (TutorialInline,)

class Media:
js = ("admin/custom-inline.js",)


@admin.register(Guide)
class GuideAdmin(admin.ModelAdmin):
form = GuideAdminForm
25 changes: 25 additions & 0 deletions concordia/admin/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,31 @@ def queryset(self, request, queryset):
return queryset


class CardCampaignListFilter(admin.SimpleListFilter):
"""
Allow CMs to filter cards by campaign
"""

title = _("campaign")
parameter_name = "campaign"

def lookups(self, request, model_admin):
return Campaign.objects.exclude(card_family__isnull=True).values_list(
"pk", "title"
)

def queryset(self, request, queryset):
campaign_id = self.value()
if campaign_id:
card_family = Campaign.objects.get(pk=campaign_id).card_family
if card_family is None:
pks = []
else:
pks = card_family.cards.values_list("pk", flat=True)
queryset = queryset.filter(id__in=pks)
return queryset


class ProjectCampaignListFilter(CampaignListFilter):
parameter_name = "campaign__id__exact"
status_filter_parameter = "campaign__status"
Expand Down
22 changes: 20 additions & 2 deletions concordia/admin/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django import forms
from tinymce.widgets import TinyMCE

from ..models import Campaign, Project
from ..models import Campaign, Card, Guide, Project

FRAGMENT_ALLOWED_TAGS = {
"a",
Expand Down Expand Up @@ -89,7 +89,7 @@ def clean_short_description(self):
)


class CampaignAdminForm(forms.ModelForm):
class CampaignAdminForm(SanitizedDescriptionAdminForm):
class Meta(SanitizedDescriptionAdminForm.Meta):
model = Campaign
widgets = {
Expand All @@ -114,3 +114,21 @@ def clean_body(self):
tags=BLOCK_ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES,
)


class CardAdminForm(forms.ModelForm):
class Meta:
model = Card
widgets = {
"body_text": TinyMCE(),
}
fields = "__all__"


class GuideAdminForm(forms.ModelForm):
class Meta:
model = Guide
widgets = {
"body": TinyMCE(),
}
fields = "__all__"
19 changes: 19 additions & 0 deletions concordia/admin/views.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import re
import tempfile
import time
from http import HTTPStatus

from bittersweet.models import validated_get_or_create
from celery import Celery
from django.apps import apps
from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import permission_required
from django.core.exceptions import ValidationError
from django.db.models import OuterRef, Subquery
from django.http import JsonResponse
from django.shortcuts import render
from django.utils.text import slugify
from django.views import View
from django.views.decorators.cache import never_cache
from tabular_export.core import export_to_csv_response, flatten_queryset

Expand Down Expand Up @@ -611,3 +615,18 @@ def admin_retired_site_report_view(request):
data.append(row)

return export_to_csv_response("retired-site-report.csv", headers, data)


class SerializedObjectView(View):
def get(self, request, *args, **kwargs):
model_name = request.GET.get("model_name")
object_id = request.GET.get("object_id")
field_name = request.GET.get("field_name")

model = apps.get_model(app_label="concordia", model_name=model_name)
try:
instance = model.objects.get(pk=object_id)
value = getattr(instance, field_name)
return JsonResponse({field_name: value})
except model.DoesNotExist:
return JsonResponse({"status": "false"}, status=HTTPStatus.NOT_FOUND)
6 changes: 6 additions & 0 deletions concordia/admin_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ConcordiaAdminSite(admin.AdminSite):

def get_urls(self):
from concordia.admin.views import (
SerializedObjectView,
admin_bulk_import_review,
admin_bulk_import_view,
admin_retired_site_report_view,
Expand Down Expand Up @@ -37,6 +38,11 @@ def get_urls(self):
project_level_export,
name="project-level-export",
),
path(
"serialized_object/",
SerializedObjectView.as_view(),
name="serialized_object",
),
]

return custom_urls + urls
136 changes: 136 additions & 0 deletions concordia/migrations/0087_auto_20240213_0756.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Generated by Django 3.2.23 on 2024-02-13 12:56

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


class Migration(migrations.Migration):

dependencies = [
("concordia", "0086_auto_20231215_1311"),
]

operations = [
migrations.CreateModel(
name="Card",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("image_alt_text", models.TextField(blank=True)),
(
"image",
models.ImageField(blank=True, null=True, upload_to="card_images"),
),
("title", models.CharField(max_length=80)),
("body_text", models.TextField(blank=True)),
("created_on", models.DateTimeField(auto_now_add=True)),
("updated_on", models.DateTimeField(auto_now=True, null=True)),
(
"display_heading",
models.CharField(blank=True, max_length=80, null=True),
),
],
options={
"ordering": ("title",),
},
),
migrations.CreateModel(
name="CardFamily",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"slug",
models.SlugField(allow_unicode=True, max_length=80, unique=True),
),
("default", models.BooleanField(default=False)),
],
options={
"verbose_name_plural": "card families",
},
),
migrations.CreateModel(
name="Guide",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("title", models.CharField(max_length=80)),
("body", models.TextField(blank=True)),
("order", models.IntegerField(default=1)),
("link_text", models.CharField(blank=True, max_length=80, null=True)),
("link_url", models.CharField(blank=True, max_length=255, null=True)),
],
),
migrations.CreateModel(
name="TutorialCard",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("order", models.IntegerField(default=0)),
(
"card",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="concordia.card"
),
),
(
"tutorial",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="concordia.cardfamily",
),
),
],
options={
"verbose_name_plural": "cards",
},
),
migrations.DeleteModel(
name="SimpleContentBlock",
),
migrations.AddField(
model_name="cardfamily",
name="cards",
field=models.ManyToManyField(
through="concordia.TutorialCard", to="concordia.Card"
),
),
migrations.AddField(
model_name="campaign",
name="card_family",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="concordia.cardfamily",
),
),
]
Loading