Skip to content

Commit c97d470

Browse files
theskumarwes-otfsandeepsajan0frjo
committed
Support for themes and new design system. (HyphaApp#4543)
Implementing theme support with https://daisyui.com Co-authored-by: Wes Appler <wes@opentech.fund> Co-authored-by: Wes Appler <145372368+wes-otf@users.noreply.github.com> Co-authored-by: sandeepsajan0 <sandeepsajan0@gmail.com> Co-authored-by: Fredrik Jonsson <frjo@xdeb.org>
1 parent 8b77b6b commit c97d470

374 files changed

Lines changed: 8876 additions & 11353 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
__pycache__
1010
db.sqlite3
1111
media/
12-
static/
1312
tmp/
13+
/static/
1414

1515
# Node
1616
node_modules/

.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@
1212
"svgwrite",
1313
"WAGTAILADMIN",
1414
"wagtailcore"
15-
]
15+
],
16+
"html.format.templating": true,
17+
"files.associations": {
18+
"*.html": "django-html"
19+
}
1620
}

docs/setup/administrators/machine-translations.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,42 @@ This requirements file will specifically attempt to install the CPU version of [
2323

2424
## Installing languages
2525

26-
Argostranslate handles translations via it's own packages - ie. Arabic -> English translation would be one package, while English -> Arabic would be another.
26+
Argostranslate handles translations via its own packages—e.g., Arabic English translation is one package, while English Arabic is another.
2727

28-
Installing/uninstalling these packages can be done with the management commands `install_languages`/`uninstall_languages` respectively, utilizing the format of <from language code>_<to language code>. For example, installing the Arabic -> English & French -> English packages would look like:
28+
You can install/uninstall these packages using the management commands `install_languages` and `uninstall_languages`, respectively. The format for specifying a package is `<from language code>_<to language code>`. For example, to install the Arabic English and French English packages:
2929

3030
```bash
3131
python3 manage.py install_languages ar_en fr_en
3232
```
3333

34+
### Additional options
35+
36+
The `install_languages` command supports several options for flexibility:
37+
38+
- **Install all available packages:**
39+
```bash
40+
python3 manage.py install_languages --all
41+
```
42+
> ⚠️ This may install many packages and consume significant disk space.
43+
44+
- **Interactively select packages:**
45+
```bash
46+
python3 manage.py install_languages --select
47+
```
48+
This will present a numbered list of available language packages for you to choose from.
49+
50+
- **Skip confirmation prompts:**
51+
```bash
52+
python3 manage.py install_languages ar_en --noinput
53+
```
54+
This will install the specified packages without asking for confirmation.
55+
56+
You can combine these options as needed. For example, to interactively select packages and skip confirmation:
57+
58+
```bash
59+
python3 manage.py install_languages --select --noinput
60+
```
61+
3462
## Enabling on the system
3563

3664
To enable machine translations on an instance, the proper configuration variables need to be set. These can be found in the [configuration options](configuration.md#hypha-custom-settings)

hypha/addressfield/static/address_form.js

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
};
2727

2828
function labelFor(field) {
29-
return $('label[for="' + $(field).attr("id") + '"]');
29+
var fieldId = $(field).attr("id");
30+
var label = $('label[for="' + fieldId + '"]');
31+
return label;
3032
}
3133

3234
function makeFieldNotRequired(field) {
@@ -54,13 +56,11 @@
5456
oldValidate.call(this, field, config);
5557
};
5658

57-
var selectWrap = '<div class="form__select"></div>';
58-
5959
// Hook into the select builder to update the display
6060
var oldConvertToSelect = $.fn.addressfield.convertToSelect;
6161
$.fn.addressfield.convertToSelect = function () {
6262
var $select = oldConvertToSelect.call(this);
63-
$select.wrap(selectWrap);
63+
$select.wrap('<div class="form__select"></div>');
6464
return $select;
6565
};
6666

@@ -73,19 +73,21 @@
7373
};
7474

7575
$(document).ready(function formReady() {
76-
$(".form div.address").each(function () {
77-
$(".form div#" + this.id).addressfield({
76+
$(".form .address").each(function () {
77+
var config = {
7878
json: "/static/addressfield.min.json",
7979
fields: {
80-
country: ".country",
81-
thoroughfare: ".thoroughfare",
82-
premise: ".premise",
83-
locality: ".locality",
84-
localityname: ".localityname",
85-
administrativearea: ".administrativearea",
86-
postalcode: ".postalcode",
80+
country: "[data-js-addressfield-name='country']",
81+
thoroughfare: "[data-js-addressfield-name='thoroughfare']",
82+
premise: "[data-js-addressfield-name='premise']",
83+
locality: "[data-js-addressfield-name='locality']",
84+
localityname: "[data-js-addressfield-name='localityname']",
85+
administrativearea:
86+
"[data-js-addressfield-name='administrativearea']",
87+
postalcode: "[data-js-addressfield-name='postalcode'] ",
8788
},
88-
});
89+
};
90+
$(".form div#" + this.id).addressfield(config);
8991
});
9092
});
9193
})(jQuery);
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
<div {% include "django/forms/widgets/attrs.html" %}>{% spaceless %}
1+
<div {% include "django/forms/widgets/attrs.html" %}>
22
{% for widget in widget.subwidgets %}
33
{% if not widget.subwidgets %}
4-
<div class="form__group">
5-
<label class="form__question" for="{{ widget.attrs.id }}">{{ widget.attrs.display }}</label>
4+
<div class="fieldset">
5+
<label class="label" for="{{ widget.attrs.id }}">{{ widget.attrs.display }}</label>
66
{% endif %}
77

88
{% include widget.template_name %}
@@ -11,4 +11,4 @@
1111
</div>
1212
{% endif %}
1313
{% endfor %}
14-
{% endspaceless %}</div>
14+
</div>

hypha/addressfield/widgets.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ class KeepAttrsTextInput(KeepOwnAttrsWidget, forms.TextInput):
2020
pass
2121

2222

23-
def classify(field):
23+
def classify(field: str) -> str:
2424
return field.replace("_", "")
2525

2626

27-
def display(field):
27+
def display(field: str) -> str:
2828
return field.replace("_", " ").title()
2929

3030

@@ -36,6 +36,7 @@ def __init__(self, *args, **kwargs):
3636
widget(
3737
attrs={
3838
"class": classify(field),
39+
"data-js-addressfield-name": classify(field),
3940
"required": False,
4041
"display": display(field),
4142
}
@@ -95,6 +96,6 @@ class Media:
9596

9697
def __init__(self, *args, **kwargs):
9798
attrs = kwargs.get("attrs", {})
98-
attrs["class"] = "address"
99+
attrs["class"] = "address -mt-2"
99100
kwargs["attrs"] = attrs
100101
super().__init__(*args, **kwargs)

hypha/apply/activity/templates/activity/include/activity_list.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{% load i18n %}
22

3-
<div class="border-b-2 border-b-slate-300">
4-
<section class="ml-4 max-w-3xl md:ml-20">
3+
<div class="border-b-2 border-b-base-300">
4+
<section class="max-w-3xl ms-4 md:ms-20">
55

6-
<div class="timeline">
6+
<div class="h-timeline">
77
{% for activity in activities %}
88
{% if activity.type == "comment" %}
99
{% include "activity/ui/activity-comment-item.html" with activity=activity %}
@@ -15,12 +15,12 @@
1515
{% if page.has_next %}
1616
<a
1717
href="{{ request.path }}?page={{ page.next_page_number }}"
18-
class="block py-2 text-sm text-slate-500 hover:text-slate-700"
18+
class="btn btn-sm"
1919
hx-get="{{ request.path }}?page={{ page.next_page_number }}"
2020
hx-trigger="intersect"
2121
hx-target="this"
2222
hx-swap="outerHTML transition:true"
23-
hx-select=".timeline"
23+
hx-select=".h-timeline"
2424
>Show more...</a>
2525
{% endif %}
2626
</div>

hypha/apply/activity/templates/activity/notifications.html

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,36 @@
22
{% load i18n activity_tags heroicons %}
33
{% block title %}{% trans "Notifications" %}{% endblock %}
44

5-
{% block content %}
6-
7-
{% adminbar %}
8-
{% slot header %}{% trans "Notifications" %}{% endslot %}
9-
{% slot sub_heading %}
10-
{% if PROJECTS_ENABLED %}
11-
{% trans "Activity feed across all applications and projects" %}
12-
{% else %}
13-
{% trans "Activity feed across all the applications" %}
14-
{% endif %}
15-
{% endslot %}
16-
17-
<form
18-
class="[&>label]:sr-only text-black flex items-center justify-between gap-2"
19-
method="get"
5+
{% block hero %}
6+
<c-hero>
7+
<c-hero.header
8+
title="{% trans 'Notifications' %}"
9+
subtitle="{% if PROJECTS_ENABLED %}{% trans 'Activity feed across all applications and projects' %}{% else %}{% trans 'Activity feed across all the applications' %}{% endif %}"
2010
>
21-
{{ filter.form }}
22-
<button class="button button--primary" type="submit" value="Filter">
23-
{% trans "Filter" %}
24-
</button>
25-
</form>
26-
{% endadminbar %}
11+
<form
12+
class="[&>label]:sr-only text-base-content flex items-center justify-between gap-2"
13+
method="get"
14+
>
15+
{{ filter.form }}
16+
<button class="btn btn-primary" type="submit" value="Filter">
17+
{% trans "Filter" %}
18+
</button>
19+
</form>
20+
</c-hero.header>
21+
</c-hero>
22+
{% endblock %}
2723

28-
<div class="wrapper wrapper--large wrapper--outer-space-medium">
29-
<div class="border-b-2 border-b-slate-300">
24+
{% block content %}
25+
<div class="my-4">
26+
<div class="border-b-2 border-b-base-300">
3027
<section class="ml-4 max-w-3xl md:ml-20">
3128

32-
<div class="timeline">
29+
<div class="h-timeline">
3330
{% for activity in object_list %}
3431
{% with activity|display_for:request.user as activity_text %}
35-
<div class="relative timeline-item" id="communications#{{ activity.id }}">
32+
<div class="relative h-timeline-item" id="communications#{{ activity.id }}">
3633
{% ifchanged activity.source.id %}
37-
<div class="py-0.5 mt-4 bg-gray-100 ps-5 pe-2 border-s-2 border-slate-300">
34+
<div class="py-0.5 mt-4 bg-base-200 ps-5 pe-2 border-s-2 border-slate-300">
3835
<span class="text-sm font-semibold text-fg-muted">{{ activity.source_content_type.name|source_type }}</span> <a href="{{ activity.source.get_absolute_url }}">{{ activity.source.fund_name }} #{{ activity.source.application_id }}: {{ activity.source.title|capfirst|truncatechars:50 }}</a>
3936
</div>
4037
{% endifchanged %}

hypha/apply/activity/templates/activity/partial_comment_message.html

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,11 @@
1212
{% if attachments %}
1313
<div class="flex flex-wrap gap-2 pb-2 mt-4 max-w-xl min-w-40">
1414
{% for attachment in attachments %}
15-
<a href="{{attachment.get_absolute_url }}"
16-
class="inline-flex items-center py-2 px-3 font-medium rounded-sm border transition-colors bg-slate-50 hover:bg-slate-200"
17-
target="_blank"
18-
rel="noopener noreferrer"
19-
title="{{ attachment.filename }}"
20-
>
21-
<span class="text-sm truncate">
22-
{% heroicon_mini "paper-clip" class="inline align-text-bottom" aria_hidden=true %}
23-
{{ attachment.filename|truncatechars_middle:45 }}
24-
</span>
25-
</a>
15+
<c-card-attachment
16+
:href="attachment.get_absolute_url"
17+
:title="attachment.filename"
18+
:filename="attachment.filename"
19+
/>
2620
{% endfor %}
2721
</div>
2822
{% endif %}

hypha/apply/activity/templates/activity/ui/activity-action-item.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{% load i18n activity_tags heroicons %}
22

33
{% with activity|display_for:request.user as activity_text %}
4-
<div class="relative timeline-item" id="communications#{{ activity.id }}">
4+
<div class="relative h-timeline-item" id="communications#{{ activity.id }}">
55
<div
6-
class="flex items-center py-2 -ml-3 before:block before:-z-10 before:absolute before:top-0 before:bottom-0 before:left-0 before:w-0.5 before:bg-slate-300"
6+
class="flex items-center py-2 -ml-3 before:block before:absolute before:top-0 before:bottom-0 before:left-0 before:w-(--border) before:bg-base-300"
77
>
8-
<div class="inline-flex relative justify-center items-start me-2">
9-
<div class="relative rounded-full inline-flex items-center justify-center border-white border-2 -ms-0.5 {% if activity.user.is_staff %}bg-slate-200 {% else %}bg-gray-200{% endif %}">
8+
<div class="inline-flex relative justify-center items-start me-2 z-1">
9+
<div class="inline-flex relative justify-center items-center rounded-full bg-base-100">
1010
<div class="inline-flex justify-center items-center w-6 h-6 text-fg-muted">
1111
{% if 'edit' in activity_text.lower %}
1212
{% heroicon_micro "pencil-square" class="inline" aria_hidden=true size=14 %}
@@ -40,7 +40,7 @@
4040
{% if not submission_title and activity|user_can_see_related:request.user %}
4141
{% with url=activity.related_object.get_absolute_url %}
4242
{% if url %}
43-
<a href="{{ url }}" class="font-semibold transition-opacity hover:opacity-70 ms-2">
43+
<a href="{{ url }}" class="link">
4444
{% trans "View" %}
4545
</a>
4646
{% endif %}

0 commit comments

Comments
 (0)