Skip to content

[Work In Progress Do Not Merge] New UI #534

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

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
167 changes: 167 additions & 0 deletions commcare_connect/opportunity/tw_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import django_tables2 as tables
from django.utils.html import format_html
from django_tables2.utils import A


class BaseTailwindTable(tables.Table):
"""Base table using Tailwind styling and custom template."""

class Meta:
template_name = "tailwind/base_table.html" # Use your custom template
attrs = {"class": "w-full text-left text-sm text-gray-600"}


class WorkerFlaggedTable(BaseTailwindTable):
index = tables.Column(verbose_name="", orderable=False)
time = tables.Column(verbose_name="Time")
entityName = tables.Column(verbose_name="Entity Name")
flags = tables.TemplateColumn(
verbose_name="Flags",
orderable=False,
template_code="""
<div class="flex relative justify-start text-sm text-brand-deep-purple font-normal w-72">
{% if value %}
{% for flag in value|slice:":2" %}
{% include "tailwind/components/badges/badge_sm.html" with text=flag %}
{% endfor %}
{% if value|length > 2 %}
{% include "tailwind/components/badges/badge_sm_dropdown.html" with title='All Flags' list=value %}
{% endif %}
{% endif %}
</div>
""",
)
reportIcons = tables.TemplateColumn(
verbose_name="",
orderable=False,
template_code="""

""",
)

class Meta:
attrs = {
"class": "w-full max-w-full",
"thead": {"class": "hidden"},
"tbody": {"class": "block w-full bg-gray-200 rounded-lg h-[400px] overflow-y-auto"},
}
row_attrs = {
"class": "flex w-full justify-between gap-x-4 p-3 bg-white hover:bg-gray-100 relative transition-colors duration-300 group",
"x-data": "{ hovered: false }",
"@mouseenter": "hovered = true",
"@mouseleave": "hovered = false",
}
sequence = ("index", "time", "entityName", "flags", "reportIcons")

def render_index(self, value, record):
return format_html(
"""
<div class="flex justify-center text-sm text-brand-deep-purple font-normal w-12">
<span x-show="!hovered && !isRowSelected({})">{}</span>
<i x-show="hovered || isRowSelected({})"
:class="isRowSelected({}) ? 'fa-regular fa-square-check' : 'fa-regular fa-square'"
class="text-brand-deep-purple cursor-pointer"
x-on:click="hovered && toggleRow({})"></i>
</div>
""",
value,
value,
value,
value,
value,
)

def render_time(self, value):
return format_html(
'<div class="flex justify-start text-sm text-brand-deep-purple font-normal w-28">{}</div>', value
)

def render_entityName(self, value):
return format_html(
'<div class="flex justify-start text-sm text-brand-deep-purple font-normal w-28">{}</div>', value
)

def render_reportIcons(self):
return format_html(
"""
<div class="flex relative justify-start text-sm text-brand-deep-purple font-normal w-4">
<i class="fa-light fa-flag-swallowtail"></i>
</div>
"""
)


class VisitsTable(BaseTailwindTable):
index = tables.Column(verbose_name="#", orderable=False)
user_id = tables.Column(verbose_name="User ID")
name = tables.Column(verbose_name="Name")
max_visit = tables.Column(verbose_name="Max Visits")
used_visits = tables.Column(verbose_name="Used Visits")
end_date = tables.Column(verbose_name="End Date")

class Meta:
attrs = {
"thead": {"class": "hidden"},
"class": "",
}
row_attrs = {
"class": "grid grid-cols-[30px_222px_213px_168px_172px_151px] text-slate-900 pl-5 py-4 items-center text-xs ml-1"
}
sequence = ("index", "user_id", "name", "max_visit", "used_visits", "end_date")

def render_index(self, value):
return format_html('<div class="text-brand-deep-purple">{}</div>', value)

def render_user_id(self, value):
return format_html("<div>{}</div>", value)

def render_name(self, value):
return format_html("<div>{}</div>", value)

def render_max_visit(self, value):
return format_html(
"""
<div x-data='{{"originalValue": "{}", "currentValue": "{}", "hasChanged": false, "isValid": true}}'
x-init="$watch('currentValue', value => {{
if (value === '') {{
currentValue = '0';
return;
}}
hasChanged = value !== originalValue;
isValid = !isNaN(value) && parseInt(value) >= 0;
}})">
<div class="flex items-center">
<input
type="text"
x-model="currentValue"
x-on:input="currentValue = $event.target.value.replace(/[^0-9]/g, '')"
:class="{{
'border border-transparent focus:border focus:border-slate-300 focus:outline-none rounded p-1.5 text-start': true,
'w-20': !(hasChanged && isValid),
'bg-indigo-100 border-none rounded-2xl w-10': hasChanged && isValid,
}}"
inputmode="numeric"
pattern="[0-9]*"
value="{}">
</div>
</div>
""",
value,
value,
value,
)

def render_used_visits(self, value):
return format_html("<div>{}</div>", value)

def render_end_date(self, value):
return format_html(
"""
<div>
<input type="date"
class="border focus:border-slate-300 focus:outline-none rounded w-28 p-2"
value="{}">
</div>
""",
value,
)
Loading