Skip to content

Commit e49eb87

Browse files
committed
better templating system (closes #66)
1 parent dc21f5b commit e49eb87

File tree

3 files changed

+98
-3
lines changed

3 files changed

+98
-3
lines changed

Diff for: README.md

+14
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,20 @@ in the array is what to replace it with (leave empty to remove matches).
128128
"shortcut": "1", # key to press in write view
129129
"description": "foo", # description shown in write view
130130
"template": "Thank you for your message." # body of email
131+
},
132+
133+
{
134+
"shortcut": "2", # key to press in write view
135+
"description": "bar", # description shown in write view
136+
"template": { # alternative form where more can be specified -- all fields optional
137+
"from": "foo", # ID of account as defined above
138+
"to": ["Foo Bar <[email protected]>"],
139+
"cc": ["Foo Bar <[email protected]>"],
140+
"bcc": ["Foo Bar <[email protected]>"],
141+
"subject": "This is a test.",
142+
"tags": ["fooTag", "barTag"],
143+
"body": "Thank you for your message."
144+
}
131145
}
132146
]
133147
}

Diff for: client/src/Write.jsx

+14-3
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ export function Write(props) {
171171
} else if(!from) {
172172
from = defAcct?.id;
173173
}
174-
setMessage("from", from);
175174
if(localStorage.getItem(`draft-${draftKey}-subject`)) {
176175
subject = localStorage.getItem(`draft-${draftKey}-subject`);
177176
document.title = `Compose: ${subject}`;
@@ -194,8 +193,20 @@ export function Write(props) {
194193

195194
createEffect(on(useTemplate, () => {
196195
if(useTemplate() && bodyRef().disabled === false) {
197-
bodyRef().value = useTemplate() + message.bodyDefaultValue;
198-
setMessage("body", bodyRef().value);
196+
if(typeof useTemplate() === 'object') {
197+
const tmpl = useTemplate();
198+
for(const k in tmpl) {
199+
if(k === "body") {
200+
bodyRef().value = tmpl.body + message.bodyDefaultValue;
201+
setMessage("body", bodyRef().value);
202+
} else {
203+
setMessage(k, tmpl[k]);
204+
}
205+
}
206+
} else { // assume it's a string
207+
bodyRef().value = useTemplate() + message.bodyDefaultValue;
208+
setMessage("body", bodyRef().value);
209+
}
199210
}
200211
}));
201212

Diff for: client/src/Write.test.jsx

+70
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,76 @@ test("template set with base message", async () => {
335335
expect(getByTestId("body").value).toBe(`blurg\n\n\nOn ${msg.date}, ${msg.from} wrote:\n> Test mail`);
336336
});
337337

338+
test("complex template set by click", async () => {
339+
const tmpl = {"from": "foo", "to": ["[email protected]"], "cc": ["[email protected]"], "bcc": ["[email protected]"],
340+
"subject": "fooSubject", "tags": ["tag1", "tag2"], "body": "barBody"},
341+
cmp = {"templates": [{"shortcut": "1", "description": "foo", "template": tmpl}]};
342+
vi.stubGlobal("data", {"accounts": accts, "allTags": tags, "compose": cmp});
343+
const { getByTestId } = render(() => <Write/>);
344+
345+
await vi.waitFor(() => {
346+
expect(screen.getByText("Send")).toBeInTheDocument();
347+
});
348+
349+
expect(screen.getByText("foo (1)")).toBeInTheDocument();
350+
expect(getByTestId("from").value).toBe("bar");
351+
expect(getByTestId("to").querySelectorAll(".chip").length).toBe(0);
352+
expect(getByTestId("cc").querySelectorAll(".chip").length).toBe(0);
353+
expect(getByTestId("bcc").querySelectorAll(".chip").length).toBe(0);
354+
expect(getByTestId("subject").value).toBe("");
355+
expect(getByTestId("tagedit").querySelectorAll(".chip").length).toBe(0);
356+
expect(getByTestId("body").value).toBe("");
357+
358+
await userEvent.click(screen.getByText("foo (1)"));
359+
expect(getByTestId("from").value).toBe("foo");
360+
expect(getByTestId("to").querySelectorAll(".chip").length).toBe(1);
361+
expect(getByTestId("to").querySelectorAll(".chip")[0].textContent).toBe("[email protected]");
362+
expect(getByTestId("cc").querySelectorAll(".chip").length).toBe(1);
363+
expect(getByTestId("cc").querySelectorAll(".chip")[0].textContent).toBe("[email protected]");
364+
expect(getByTestId("bcc").querySelectorAll(".chip").length).toBe(1);
365+
expect(getByTestId("bcc").querySelectorAll(".chip")[0].textContent).toBe("[email protected]");
366+
expect(getByTestId("subject").value).toBe("fooSubject");
367+
expect(getByTestId("tagedit").querySelectorAll(".chip").length).toBe(2);
368+
expect(getByTestId("tagedit").querySelectorAll(".chip")[0].textContent).toBe("tag1");
369+
expect(getByTestId("tagedit").querySelectorAll(".chip")[1].textContent).toBe("tag2");
370+
expect(getByTestId("body").value).toBe("barBody");
371+
});
372+
373+
test("complex template set by shortcut", async () => {
374+
const tmpl = {"from": "foo", "to": ["[email protected]"], "cc": ["[email protected]"], "bcc": ["[email protected]"],
375+
"subject": "fooSubject", "tags": ["tag1", "tag2"], "body": "barBody"},
376+
cmp = {"templates": [{"shortcut": "1", "description": "foo", "template": tmpl}]};
377+
vi.stubGlobal("data", {"accounts": accts, "allTags": tags, "compose": cmp});
378+
const { getByTestId } = render(() => <Write/>);
379+
380+
await vi.waitFor(() => {
381+
expect(screen.getByText("Send")).toBeInTheDocument();
382+
});
383+
384+
expect(screen.getByText("foo (1)")).toBeInTheDocument();
385+
expect(getByTestId("from").value).toBe("bar");
386+
expect(getByTestId("to").querySelectorAll(".chip").length).toBe(0);
387+
expect(getByTestId("cc").querySelectorAll(".chip").length).toBe(0);
388+
expect(getByTestId("bcc").querySelectorAll(".chip").length).toBe(0);
389+
expect(getByTestId("subject").value).toBe("");
390+
expect(getByTestId("tagedit").querySelectorAll(".chip").length).toBe(0);
391+
expect(getByTestId("body").value).toBe("");
392+
393+
await userEvent.type(document.body, "1");
394+
expect(getByTestId("from").value).toBe("foo");
395+
expect(getByTestId("to").querySelectorAll(".chip").length).toBe(1);
396+
expect(getByTestId("to").querySelectorAll(".chip")[0].textContent).toBe("[email protected]");
397+
expect(getByTestId("cc").querySelectorAll(".chip").length).toBe(1);
398+
expect(getByTestId("cc").querySelectorAll(".chip")[0].textContent).toBe("[email protected]");
399+
expect(getByTestId("bcc").querySelectorAll(".chip").length).toBe(1);
400+
expect(getByTestId("bcc").querySelectorAll(".chip")[0].textContent).toBe("[email protected]");
401+
expect(getByTestId("subject").value).toBe("fooSubject");
402+
expect(getByTestId("tagedit").querySelectorAll(".chip").length).toBe(2);
403+
expect(getByTestId("tagedit").querySelectorAll(".chip")[0].textContent).toBe("tag1");
404+
expect(getByTestId("tagedit").querySelectorAll(".chip")[1].textContent).toBe("tag2");
405+
expect(getByTestId("body").value).toBe("barBody");
406+
});
407+
338408
test("addresses editable and complete", async () => {
339409
const { getByTestId } = render(() => <Write/>);
340410

0 commit comments

Comments
 (0)