Skip to content

Commit cfec7f7

Browse files
authored
chore: Update bgAdmin.tsx to latest patterns API (#1918)
1 parent 03b3a10 commit cfec7f7

File tree

2 files changed

+106
-117
lines changed

2 files changed

+106
-117
lines changed

recipes/bgAdmin.tsx renamed to packages/background-charm-service/bgAdmin.tsx

Lines changed: 105 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,54 @@
11
/// <cts-enable />
2-
import {
3-
derive,
4-
handler,
5-
JSONSchema,
6-
lift,
7-
Mutable,
8-
NAME,
9-
recipe,
10-
Schema,
11-
UI,
12-
} from "commontools";
2+
import { Cell, Default, derive, handler, NAME, recipe, UI } from "commontools";
133

144
const DISABLED_VIA_UI = "Disabled via UI";
155

16-
// NOTE(ja): this must be the same as the schema in background-charm-service/src/schema.ts
17-
const BGCharmEntrySchema = {
18-
type: "object",
19-
properties: {
20-
space: { type: "string" },
21-
charmId: { type: "string" },
22-
integration: { type: "string" },
23-
createdAt: { type: "number" },
24-
updatedAt: { type: "number" },
25-
disabledAt: { type: "number", default: 0 },
26-
lastRun: { type: "number", default: 0 },
27-
status: { type: "string", default: "" },
28-
},
29-
required: [
30-
"space",
31-
"charmId",
32-
"integration",
33-
"createdAt",
34-
"updatedAt",
35-
"lastRun",
36-
"status",
37-
],
38-
} as const satisfies JSONSchema;
39-
type BGCharmEntry = Mutable<Schema<typeof BGCharmEntrySchema>>;
40-
41-
const BGCharmEntriesSchema = {
42-
type: "array",
43-
items: BGCharmEntrySchema,
44-
default: [],
45-
} as const satisfies JSONSchema;
46-
type BGCharmEntries = Schema<typeof BGCharmEntriesSchema>;
47-
48-
const InputSchema = {
49-
type: "object",
50-
properties: {
51-
charms: BGCharmEntriesSchema,
52-
},
53-
} as const satisfies JSONSchema;
54-
55-
const ResultSchema = {
56-
type: "object",
57-
properties: {
58-
charms: {
59-
type: "array",
60-
items: BGCharmEntrySchema,
61-
},
62-
},
63-
} as const satisfies JSONSchema;
6+
type BGCharmEntry = {
7+
space: string;
8+
charmId: string;
9+
integration: string;
10+
createdAt: number;
11+
updatedAt: number;
12+
disabledAt: Default<number, 0>;
13+
lastRun: Default<number, 0>;
14+
status: Default<string, "">;
15+
};
16+
17+
type InputSchema = {
18+
charms: Default<BGCharmEntry[], []>;
19+
};
20+
21+
type ResultSchema = {
22+
charms: BGCharmEntry[];
23+
};
6424

6525
const deleteCharm = handler<
6626
never,
67-
{ charms: BGCharmEntry[]; charm: BGCharmEntry }
27+
{ charms: Cell<BGCharmEntry[]>; charm: Cell<BGCharmEntry> }
6828
>(
6929
(_, { charm, charms }) => {
70-
const idx = charms.findIndex((i) =>
71-
i.space === charm.space && i.charmId === charm.charmId
30+
const { space, charmId } = charm.get();
31+
const newList = charms.get().slice();
32+
const index = newList.findIndex((i) =>
33+
i.space === space && i.charmId === charmId
7234
);
73-
if (idx !== -1) charms.splice(idx, 1);
35+
if (index >= 0 && index < newList.length) {
36+
newList.splice(index, 1);
37+
charms.set(newList);
38+
}
7439
},
7540
);
7641

77-
const toggleCharm = handler<never, { charm: BGCharmEntry }>((_, { charm }) => {
78-
if (charm.disabledAt) {
79-
charm.disabledAt = undefined;
80-
charm.status = "Initializing...";
81-
} else {
82-
charm.disabledAt = Date.now();
83-
charm.status = DISABLED_VIA_UI;
84-
}
85-
});
42+
const toggleCharm = handler<never, { charm: Cell<BGCharmEntry> }>(
43+
(_, { charm }) => {
44+
const data = charm.get();
45+
if (data.disabledAt) {
46+
charm.set({ ...data, disabledAt: 0, status: "Initializing..." });
47+
} else {
48+
charm.set({ ...data, disabledAt: Date.now(), status: DISABLED_VIA_UI });
49+
}
50+
},
51+
);
8652

8753
// Minimal "moment" style formatting to get a string
8854
// representation of an (older) date relative to now,
@@ -136,19 +102,31 @@ function StatusIcon(
136102
return (
137103
<div
138104
title={title}
139-
style={`background-color: ${color}; width: 20px; height: 20px; border-radius: 20px`}
105+
style={{
106+
backgroundColor: color,
107+
width: "20px",
108+
borderRadius: "20px",
109+
}}
140110
>
141111
</div>
142112
);
143113
}
144114

145-
const BGCharmRow = lift((
146-
{ charm, charms }: { charm: BGCharmEntry; charms: BGCharmEntries },
147-
) => {
148-
const { integration, createdAt, updatedAt, disabledAt, lastRun, status } =
149-
charm;
150-
const space = charm.space.slice(-4);
151-
const charmId = charm.charmId.slice(-4);
115+
function getRenderData(
116+
charm: BGCharmEntry,
117+
) {
118+
const {
119+
integration,
120+
space: rawSpace,
121+
charmId: rawCharmId,
122+
createdAt,
123+
updatedAt,
124+
disabledAt,
125+
lastRun,
126+
status,
127+
} = charm;
128+
const space = rawSpace.slice(-4);
129+
const charmId = rawCharmId.slice(-4);
152130
const name = `#${space}/#${charmId}`;
153131

154132
const createdAtDate = new Date(createdAt);
@@ -164,32 +142,15 @@ Last run ${lastRunDate ? fromNow(lastRunDate) : "never"} ${
164142
lastRunDate ? `(${lastRunDate.toLocaleString()})` : ""
165143
}`;
166144

167-
return (
168-
<div className="bg-charm-row">
169-
<div className="toggle-button">
170-
<button
171-
onClick={toggleCharm({ charm })}
172-
type="button"
173-
>
174-
<StatusIcon status={status} disabledAt={disabledAt}></StatusIcon>
175-
</button>
176-
</div>
177-
<div className="name ellipsis" title={details}>
178-
{name}
179-
<span className="integration">{integration}</span>
180-
</div>
181-
<div className="status ellipsis">{statusDisplay}</div>
182-
<div className="delete">
183-
<button
184-
onClick={deleteCharm({ charm, charms })}
185-
type="button"
186-
>
187-
Delete
188-
</button>
189-
</div>
190-
</div>
191-
);
192-
});
145+
return {
146+
status,
147+
statusDisplay,
148+
disabledAt,
149+
details,
150+
integration,
151+
name,
152+
};
153+
}
193154

194155
const css = `
195156
.bg-charm-container {
@@ -233,9 +194,8 @@ const css = `
233194
}
234195
`;
235196

236-
export default recipe(
237-
InputSchema,
238-
ResultSchema,
197+
export default recipe<InputSchema, ResultSchema>(
198+
"BG Admin",
239199
({ charms }) => {
240200
derive(charms, (charms) => {
241201
console.log("bg charm list:", charms);
@@ -246,13 +206,42 @@ export default recipe(
246206
<div>
247207
<style>{css}</style>
248208
<div className="bg-charm-container">
249-
{charms.map((charm) => (
250-
<BGCharmRow
251-
charms={charms}
252-
charm={charm}
253-
>
254-
</BGCharmRow>
255-
))}
209+
{charms.map((charm) => {
210+
const {
211+
status,
212+
disabledAt,
213+
details,
214+
name,
215+
integration,
216+
statusDisplay,
217+
} = getRenderData(charm);
218+
return (
219+
<div className="bg-charm-row">
220+
<div className="toggle-button">
221+
<button
222+
onClick={toggleCharm({ charm })}
223+
type="button"
224+
>
225+
<StatusIcon status={status} disabledAt={disabledAt}>
226+
</StatusIcon>
227+
</button>
228+
</div>
229+
<div className="name ellipsis" title={details}>
230+
{name}
231+
<span className="integration">{integration}</span>
232+
</div>
233+
<div className="status ellipsis">{statusDisplay}</div>
234+
<div className="delete">
235+
<button
236+
onClick={deleteCharm({ charm, charms })}
237+
type="button"
238+
>
239+
Delete
240+
</button>
241+
</div>
242+
</div>
243+
);
244+
})}
256245
</div>
257246
</div>
258247
),

packages/background-charm-service/deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"tasks": {
44
"start": "deno run -A --unstable-worker-options src/main.ts",
55
"help": "deno run -A src/main.ts --help",
6-
"add-admin-charm": "deno run -A cast-admin.ts --recipePath=../recipes/bgAdmin.tsx",
6+
"add-admin-charm": "deno run -A cast-admin.ts --recipePath=bgAdmin.tsx",
77
"test": "deno test test/*.test.ts",
88
"check": "deno check src/**/*.ts",
99
"lint": "deno lint",

0 commit comments

Comments
 (0)