Skip to content

Commit a07db5d

Browse files
committed
Phase 4: Compose Email Functionality #7056
1 parent 65bf8e7 commit a07db5d

File tree

3 files changed

+85
-5
lines changed

3 files changed

+85
-5
lines changed

apps/email/EPIC_PLAN.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ This document outlines the plan for refactoring the `apps/email` application int
44

55
## Architectural Milestones & Key Learnings
66

7-
This epic has driven significant architectural improvements to the functional component system. For a full understanding of the current state, review these tickets:
7+
This epic has driven significant architectural improvements to the functional component system. For a full understanding of the current state, review this ticket:
88

9-
- **[#ticket-functional-child-component-diffing.md](/.github/ticket-functional-child-component-diffing.md):** The most critical enhancement. We implemented a VDOM config diffing mechanism in `FunctionalBase` to prevent the re-creation of stateful child components (like stores). This allows for a truly declarative VDOM while preserving child state.
10-
- **[#ticket-functional-base-windowid-propagation.md](/.github/ticket-functional-base-windowid-propagation.md):** Fixed a crucial bug where the `windowId` was not being propagated to child components, which is essential for multi-window support and event handling.
119
- **[#ticket-functional-recursive-config-diffing.md](/.github/ticket-functional-recursive-config-diffing.md):** A plan for a future enhancement to make the diffing logic recursive, allowing for deep, declarative control over nested component configurations.
1210

1311
---

apps/email/view/ComposeView.mjs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {defineComponent} from '../../../src/functional/_export.mjs';
2+
import Button from '../../../src/button/Base.mjs';
3+
import TextField from '../../../src/form/field/Text.mjs';
4+
import TextAreaField from '../../../src/form/field/TextArea.mjs';
5+
6+
export default defineComponent({
7+
config: {
8+
className: 'Email.view.ComposeView'
9+
},
10+
createVdom({onClose}) {
11+
const overlayStyle = {
12+
position: 'absolute',
13+
top : '50%',
14+
left : '50%',
15+
transform: 'translate(-50%, -50%)',
16+
width : '600px',
17+
padding : '20px',
18+
border : '1px solid #ccc',
19+
backgroundColor: '#fff',
20+
boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
21+
zIndex : 1000
22+
};
23+
24+
const fieldStyle = {
25+
marginBottom: '10px'
26+
};
27+
28+
return {
29+
style: overlayStyle,
30+
cn: [{
31+
module: TextField,
32+
id : 'compose-to',
33+
label : 'To:',
34+
style : fieldStyle,
35+
width : '100%'
36+
}, {
37+
module: TextField,
38+
id : 'compose-subject',
39+
label : 'Subject:',
40+
style : fieldStyle,
41+
width : '100%'
42+
}, {
43+
module: TextAreaField,
44+
id : 'compose-body',
45+
label : 'Body:',
46+
height: 200,
47+
style : fieldStyle,
48+
width : '100%'
49+
}, {
50+
module: Button,
51+
id : 'compose-close-button',
52+
text : 'Close',
53+
listeners: {
54+
click: onClose
55+
}
56+
}]
57+
}
58+
}
59+
});

apps/email/view/MainView.mjs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Button from '../../../src/button/Base.mjs';
2+
import ComposeView from './ComposeView.mjs';
13
import {defineComponent, useConfig} from '../../../src/functional/_export.mjs';
24
import GridContainer from '../../../src/grid/Container.mjs';
35
import EmailsStore from '../store/Emails.mjs';
@@ -9,6 +11,7 @@ export default defineComponent({
911
cls : ['email-mainview']
1012
},
1113
createVdom() {
14+
const [isComposing, setIsComposing] = useConfig(false);
1215
const [selectedEmail, setSelectedEmail] = useConfig(null);
1316

1417
const paneStyle = {
@@ -17,14 +20,30 @@ export default defineComponent({
1720
padding: '10px'
1821
};
1922

23+
const onComposeClick = () => {
24+
setIsComposing(true);
25+
};
26+
27+
const onCloseCompose = () => {
28+
setIsComposing(false);
29+
};
30+
2031
const onSelectionChange = ({records}) => {
2132
setSelectedEmail(records[0] || null);
2233
};
2334

2435
return {
2536
cn: [{
2637
style: {...paneStyle, flex: '0 0 200px'},
27-
text : 'Folders'
38+
cn: [{
39+
module : Button,
40+
handler: onComposeClick,
41+
id : 'compose-button',
42+
text : 'Compose',
43+
style : {marginBottom: '10px', width: '100%'}
44+
}, {
45+
text : 'Folders'
46+
}]
2847
}, {
2948
style: {...paneStyle, flex: '1 1 600px', padding: '0'},
3049
cn: [{
@@ -59,7 +78,11 @@ export default defineComponent({
5978
] : [{
6079
text: 'Select an email to read'
6180
}]
62-
}]
81+
}, isComposing ? {
82+
module : ComposeView,
83+
id : 'compose-view',
84+
onClose: onCloseCompose
85+
} : null].filter(Boolean)
6386
}
6487
}
6588
});

0 commit comments

Comments
 (0)