-
Notifications
You must be signed in to change notification settings - Fork 6
Exp/preact web components #2043
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
base: develop
Are you sure you want to change the base?
Conversation
9a06a7a to
2a2d9d3
Compare
src/open_inwoner/react/lib/web-component/web-component.spec.tsx
Outdated
Show resolved
Hide resolved
src/open_inwoner/react/components/KVKBranchSelector/KVKBranchSelector.stories.tsx
Show resolved
Hide resolved
src/open_inwoner/react/components/KVKBranchSelector/KVKBranchSelector.tsx
Show resolved
Hide resolved
|
|
||
| // Normalize to MenuItem[][] - check if first element is an array | ||
| const normalized = | ||
| rawData.length > 0 && Array.isArray(rawData[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so it is always at least 1 item, but what if What if rawData is empty? (not sure if we have that situation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a layer to work with the actual accepted props for the MenuItems.
With this we accept their standard MenuItem[][], this renders mutliple lists with spacing.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #2043 +/- ##
===========================================
- Coverage 92.65% 92.65% -0.01%
===========================================
Files 1222 1222
Lines 46832 46854 +22
===========================================
+ Hits 43392 43411 +19
- Misses 3440 3443 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
swrichards
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some preliminary comments, let me know if you think we should discuss. Otherwise good work here.
f1f9fc4 to
20a1b74
Compare
aa95568 to
d3e742b
Compare
9efc12c to
d4efc2f
Compare
8a60764 to
d0bb07e
Compare
jiromaykin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost ready to merge :-)
| children?: ComponentChildren; | ||
| }>; | ||
|
|
||
| const HomepagePluginSection: FC<IHomepagePluginSectionProps> = ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A general question, also to @swrichards : this is a very rudimentary component that either exists or doesn't so do we not need front-end spec tests for these?
Are we going to work in such a way most testing is done by the back-end for these type of simple components?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not write a test for this component yet (time), but in my opinion every should this component have a test.
|
|
||
| # test item | ||
| items = pyquery.find(".card-container .card") | ||
| items = pyquery.find("oip-homepage-plugin-card") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: not about to this test file, but adding to the _/cms/plugins/cms_plugins/appointments.py file: I would love to have a proper mock for the front-end .
If I copy the text from the Figma design and use this code, I think it could be better @swrichards ?:
from django.utils.translation import gettext as _
import structlog
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from open_inwoner.cms.plugins.models.appointments import UserAppointments
from open_inwoner.qmatic.client import NoServiceConfigured, qmatic_client_factory
logger = structlog.stdlib.get_logger(__name__)
@plugin_pool.register_plugin
class UserAppointmentsPlugin(CMSPluginBase):
model = UserAppointments
module = _("General")
name = _("My appointments")
render_template = "cms/plugins/appointments/appointments.html"
def render(self, context, instance, placeholder):
request = context["request"]
if not request.user.is_authenticated or not request.user.has_verified_email():
appointments = []
else:
try:
client = qmatic_client_factory()
except NoServiceConfigured:
logger.exception("Error occurred while creating Qmatic client")
appointments = []
else:
appointments = client.list_appointments_for_customer(
request.user.verified_email
)
# MOCK DATA
if not appointments:
from datetime import datetime
class MockBranch:
timeZone = "Europe/Amsterdam"
class MockAppointment:
def __init__(self, service_name, date_str, address_line, city, public_id):
self.title = service_name
self.start = datetime.fromisoformat(date_str)
self.services = [type('Service', (), {'name': service_name})()]
self.branch = type('Branch', (), {
'timeZone': "Europe/Amsterdam",
'addressLine2': address_line,
'addressCity': city,
})()
self.publicId = public_id
appointments = [
MockAppointment("rijbewijs ophalen", "2025-09-21T13:15:00+02:00", "Raadhuisplein 10", "Haren", "rijbewijs-001"),
MockAppointment("VOG aanvragen", "2025-09-30T15:45:00+02:00", "Kreupelstraat 1", "Groningen", "vog-001"),
]
context.update(
{
"instance": instance,
"appointments": appointments,
}
)
return context
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used this to mock the appointments:
import factory
from open_inwoner.qmatic.tests.factories import (
AppointmentFactory,
BranchDetailFactory,
QmaticServiceFactory,
)
appointments_mocks = [
AppointmentFactory.build(
title=factory.Faker("catch_phrase").evaluate(None, None, {"locale": "nl_NL"}),
start=factory.Faker(
"date_time_between", start_date="now", end_date="+30d"
).evaluate(None, None, {"locale": "nl_NL"}),
notes=factory.Faker("text", max_nb_chars=120).evaluate(
None, None, {"locale": "nl_NL"}
),
branch=BranchDetailFactory.build(
name=factory.Faker("company").evaluate(None, None, {"locale": "nl_NL"}),
timeZone=factory.Faker("timezone").evaluate(
None, None, {"locale": "nl_NL"}
),
addressCity=factory.Faker("city").evaluate(None, None, {"locale": "nl_NL"}),
addressLine1=factory.Faker("street_name").evaluate(
None, None, {"locale": "nl_NL"}
),
addressLine2=factory.Faker("street_address").evaluate(
None, None, {"locale": "nl_NL"}
),
addressZip=factory.Faker("postcode").evaluate(
None, None, {"locale": "nl_NL"}
),
),
services=[
QmaticServiceFactory.build(
name=factory.Faker("sentence", nb_words=2).evaluate(
None, None, {"locale": "nl_NL"}
)
)
],
)
for i in range(0, 10)
]
Summary
This PR refactors the usage of
ReactPreact, Web components and Storybook.With these changes we can easily create web components.
This PR refactored the following components:
material-icon(not yet used as web component).side-navigationkvk-branch-selectoraction-listoip-homepage-plugin-sectionoip-homepage-plugin-card(this includes the required changes for balie afspraken)oip-loading-spinnerExample rendering
Django template examples
{{ data|json_script:"id" }} <action-list actions-id="id"></action-list>Also this PR pins Node in the CI to 20.
Issue References
Multiple:
Checklist
docker-compose.ymlenvironment variablesenvironment variables