Skip to content

Commit

Permalink
Merge pull request #64 from daichitakahashi/sharedModal
Browse files Browse the repository at this point in the history
Shared modal
  • Loading branch information
daichitakahashi authored Dec 10, 2024
2 parents 756cb98 + abe0a89 commit f47c320
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 13 deletions.
6 changes: 6 additions & 0 deletions web-console/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @cf-eventhub/web-console

## 0.0.9

### Patch Changes

- 261c207: Use shared modal for dispatch details

## 0.0.8

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion web-console/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@cf-eventhub/web-console",
"type": "module",
"version": "0.0.8",
"version": "0.0.9",
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy --minify",
Expand Down
9 changes: 7 additions & 2 deletions web-console/src/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Button } from "../components/Button";
import { CreateEvent } from "../components/CreateEvent";
import { Event } from "../components/Event";
import { SunMedium } from "../components/Icon";
import { Modal } from "../components/Modal";
import { Modal, useSharedModal } from "../components/Modal";
import { Pagination } from "../components/Pagination";
import { type DateTime, factory } from "../factory";

Expand Down Expand Up @@ -112,6 +112,10 @@ export const createHandler = ({
})()
: undefined;

const [SharedModal, sharedModalData] = useSharedModal({
modalId: "dispatch-detail-modal",
});

return c.render(
<div>
<div class="h-2 bg-blue-300" />
Expand All @@ -134,14 +138,15 @@ export const createHandler = ({
{(_) => <CreateEvent closeModal={_} />}
</Modal>
</div>

<SharedModal />
<div class="flex flex-col justify-center gap-12 overflow-hidden pt-1 pb-6">
{events.length > 0 ? (
events.map((e) => (
<Event
key={e.id}
event={e}
formatDate={c.var.dateFormatter}
sharedModal={sharedModalData}
/>
))
) : (
Expand Down
30 changes: 20 additions & 10 deletions web-console/src/components/Event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { DateTime } from "../factory";
import { Button } from "./Button";
import { Description, DescriptionList } from "./DescriptionList";
import { ScanSearch, Sunrise } from "./Icon";
import { Modal } from "./Modal";
import { SharedModalContent, type SharedModalData } from "./Modal";
import { StatusIndicator } from "./StatusIndicator";
import {
Table,
Expand All @@ -20,7 +20,8 @@ import type { EventWithDispatches } from "./types";
export const Event: FC<{
event: EventWithDispatches;
formatDate: (d: DateTime) => string;
}> = ({ event, formatDate }) => {
sharedModal: SharedModalData;
}> = ({ event, formatDate, sharedModal }) => {
let eventStatus: "ongoing" | "complete" | "ignored" | "failed" = "ongoing";
const statuses = event.dispatches
.map((d) => d.status)
Expand Down Expand Up @@ -71,6 +72,7 @@ export const Event: FC<{
key={dispatch.id}
dispatch={dispatch}
formatDate={formatDate}
sharedModal={sharedModal}
/>
))
) : (
Expand All @@ -89,7 +91,8 @@ export const Event: FC<{
export const Dispatch: FC<{
dispatch: EventWithDispatches["dispatches"][number];
formatDate: (d: DateTime) => string;
}> = ({ dispatch, formatDate }) => (
sharedModal: SharedModalData;
}> = ({ dispatch, formatDate, sharedModal }) => (
<TableRow>
<TableCell>
<code>{dispatch.destination}</code>
Expand All @@ -111,21 +114,27 @@ export const Dispatch: FC<{
)}
</TableCell>
<TableCell>
<Modal
target={(_: string) => (
<div class="w-fit cursor-pointer hover:text-gray-500" _={_}>
<SharedModalContent
sharedModal={sharedModal}
contentFrameId={`dispatch-${dispatch.id}`}
trigger={(openModal) => (
<div
class="w-fit cursor-pointer hover:text-gray-500"
hx-swap-oob={`.dispatch-${dispatch.id}`}
_={openModal}
>
<ScanSearch title="Show detail" />
</div>
)}
>
{(_) => (
{(closeModal) => (
<DispatchDetails
dispatch={dispatch}
closeModal={_}
closeModal={closeModal}
formatDate={formatDate}
/>
)}
</Modal>
</SharedModalContent>
</TableCell>
</TableRow>
);
Expand All @@ -135,7 +144,7 @@ const DispatchDetails: FC<{
closeModal: string;
formatDate: (d: DateTime) => string;
}> = ({ dispatch, closeModal, formatDate }) => (
<div>
<div class={`dispatch-${dispatch.id}`}>
<h2 class="text-2xl font-semibold">
<span class="flex gap-2 items-center">
<Sunrise title="" /> Dispatch details
Expand All @@ -145,6 +154,7 @@ const DispatchDetails: FC<{
<DescriptionList>
<Description title="Destination">
<code>{dispatch.destination}</code>
{new Date().toISOString()}
</Description>
<Description title="Max retries">{dispatch.maxRetries}</Description>
<Description title="Delay seconds">
Expand Down
65 changes: 65 additions & 0 deletions web-console/src/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,68 @@ export const Modal: FC<{
</dialog>
</div>
);

export type SharedModalData = {
getOpenModalScript: (contentFrameId: string) => string;
closeModalScript: string;
};

export const useSharedModal = ({ modalId }: { modalId: string }) => {
const modalFrameId = `modal-frame-${modalId}`;

const getOpenModalScript = (contentFrameId: string) => `
on click
set dialog to #${modalId}
set frame to #${modalFrameId}
if dialog does not match @open
put innerHTML of #${contentFrameId} into frame
call htmx.process(frame)
call dialog.showModal()
end`;
const closeModalScript = `
on click
set dialog to #${modalId}
if dialog match @open
call dialog.close()
end`;

const SharedModal: FC = () => (
<dialog
id={modalId}
class="outline-none rounded-xl backdrop:bg-gray-100/30 backdrop:backdrop-blur-[2px]"
>
<div
id={modalFrameId}
class="m-[1px] p-4 rounded-xl outline outline-1 outline-gray-900/20"
/>
</dialog>
);

return [
SharedModal,
{
getOpenModalScript,
closeModalScript,
} satisfies SharedModalData as SharedModalData,
] as const;
};

export const SharedModalContent: FC<{
sharedModal: SharedModalData;
contentFrameId: string;
trigger: (openModalScript: string) => Child;
children: (closeModalScript: string) => Child;
}> = ({
sharedModal: { getOpenModalScript, closeModalScript },
contentFrameId,
trigger,
children,
}) => {
const openModalScript = getOpenModalScript(contentFrameId);
return (
<div>
{trigger(openModalScript)}
<template id={contentFrameId}>{children(closeModalScript)}</template>
</div>
);
};

0 comments on commit f47c320

Please sign in to comment.