Skip to content

Commit f6a2827

Browse files
author
ahmetkuslular
committed
ADD server side data functions and response setter
1 parent dd82862 commit f6a2827

File tree

12 files changed

+251
-76
lines changed

12 files changed

+251
-76
lines changed

config/string.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ function replaceString() {
3636
replace: normalizeUrl(voltranConfig.routing.requestConfigs),
3737
flags: 'g'
3838
},
39+
{
40+
search: '__V_PREVIEW_PAGES__',
41+
replace: normalizeUrl(voltranConfig.routing.previewPages),
42+
flags: 'g'
43+
},
3944
{
4045
search: '@voltran/core',
4146
replace: normalizeUrl(path.resolve(__dirname, '../src/index')),

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"classnames": "2.2.6",
4141
"clean-webpack-plugin": "1.0.0",
4242
"cli-color": "^2.0.0",
43+
"colors": "^1.4.0",
4344
"compose-middleware": "5.0.0",
4445
"compression": "^1.7.4",
4546
"cookie-parser": "1.4.3",

src/index.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import withBaseComponent from './universal/partials/withBaseComponent';
1+
import voltran from './universal/partials/withBaseComponent';
22
import { SERVICES } from './universal/utils/constants';
3+
import { ClientApiManager, ServerApiManager } from './universal/core/api';
34

4-
export default {
5-
withBaseComponent,
6-
SERVICES
7-
};
5+
export default voltran;
6+
export { SERVICES, ClientApiManager, ServerApiManager };

src/renderMultiple.js

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,39 @@ import { matchUrlInRouteConfigs } from './universal/core/route/routeUtils';
44
import Component from './universal/model/Component';
55
import Renderer from './universal/model/Renderer';
66
import Preview from './universal/components/Preview';
7-
import { isRequestDispatcher, isPreview, isWithoutHTML } from './universal/service/RenderService';
7+
import {
8+
isRequestDispatcher,
9+
isPreview,
10+
isWithoutHTML,
11+
isWithoutState,
12+
getPreviewLayout
13+
} from './universal/service/RenderService';
814
import metrics from './metrics';
915
import { HTTP_STATUS_CODES } from './universal/utils/constants';
1016
import logger from './universal/utils/logger';
1117

18+
const previewPages = require('__V_PREVIEW_PAGES__');
19+
20+
const getRenderOptions = req => {
21+
const isPreviewValue = isPreview(req.query) || false;
22+
const isWithoutHTMLValue = isWithoutHTML(req.query) || false;
23+
const isWithoutStateValue = isWithoutState(req.query) || false;
24+
25+
return {
26+
isPreview: isPreviewValue,
27+
isWithoutHTML: isWithoutHTMLValue,
28+
isWithoutState: isWithoutStateValue
29+
};
30+
};
31+
1232
function getRenderer(name, req) {
1333
const { query, cookies, url, headers, params } = req;
1434
const path = `/${params?.path || ''}`;
1535
const userAgent = headers['user-agent'];
1636

1737
const componentPath = Component.getComponentPath(name);
1838
const routeInfo = matchUrlInRouteConfigs(componentPath);
39+
const renderOptions = getRenderOptions(req);
1940

2041
if (routeInfo) {
2142
const urlWithPath = url.replace('/', path);
@@ -26,6 +47,7 @@ function getRenderer(name, req) {
2647
cookies,
2748
url: urlWithPath,
2849
userAgent,
50+
...renderOptions
2951
};
3052

3153
if (Component.isExist(componentPath)) {
@@ -177,11 +199,21 @@ async function getResponses(renderers) {
177199
return responses;
178200
}
179201

180-
async function getPreview(responses, requestCount) {
181-
return Preview(
182-
[...Object.keys(responses).map(name => responses[name].fullHtml)].join('\n'),
183-
`${requestCount} request!`
184-
);
202+
async function getPreview(responses, requestCount, req) {
203+
const layoutName = getPreviewLayout(req.query);
204+
const { layouts } = previewPages.default;
205+
let PreviewFile = Preview;
206+
207+
if (layouts[layoutName]) {
208+
PreviewFile = layouts[layoutName];
209+
}
210+
211+
const content = Object.keys(responses).map(name => {
212+
const componentName = responses?.[name]?.activeComponent?.componentName ?? '';
213+
return getLayoutWithClass(componentName, responses[name].fullHtml);
214+
});
215+
216+
return PreviewFile([...content].join('\n'), `${requestCount} request!`);
185217
}
186218

187219
const DEFAULT_PARTIALS = ['RequestDispatcher'];
@@ -199,6 +231,17 @@ export const getPartials = req => {
199231
return partials;
200232
};
201233

234+
function cr(condition, ok, cancel) {
235+
return condition ? ok : cancel || '';
236+
}
237+
238+
const getLayoutWithClass = (name, html, id = '', style = null) => {
239+
const idAttr = cr(id !== '', `id=${id}`);
240+
const styleAttr = cr(style !== null, `style=${style}`);
241+
242+
return `<div class="${name}" ${idAttr} ${styleAttr}>${html}</div>`;
243+
};
244+
202245
const renderMultiple = async (req, res) => {
203246
const partials = getPartials(req);
204247

@@ -228,7 +271,7 @@ const renderMultiple = async (req, res) => {
228271
const responses = await getResponses(renderers);
229272

230273
if (isPreview(req.query)) {
231-
const preview = await getPreview(responses, requestCount);
274+
const preview = await getPreview(responses, requestCount, req);
232275
res.html(preview);
233276
} else {
234277
res.json(responses);

src/universal/core/api/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as ClientApiManager } from './ClientApiManagerCache';
2+
export { default as ServerApiManager } from './ServerApiManagerCache';

src/universal/model/Renderer.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
import ServerApiManagerCache from '../core/api/ServerApiManagerCache';
1+
import omit from 'lodash/omit';
22
import { isPreview, renderComponent, renderLinksAndScripts } from '../service/RenderService';
33

4+
const blacklistOutput = [
5+
'componentName',
6+
'fullWidth',
7+
'isMobileComponent',
8+
'isPreviewQuery',
9+
'responseOptions'
10+
];
411
export default class Renderer {
512
constructor(component, context) {
613
this.component = component;
@@ -13,44 +20,42 @@ export default class Renderer {
1320
this.isPredefinedInitialStateSupported() &&
1421
(process.env.BROWSER || (!process.env.BROWSER && !this.context.isWithoutState))
1522
) {
16-
this.servicesMap = this.getServicesMap();
23+
this.servicesMap = this.getServicesWithMultiple();
1724
this.winnerMap = {};
1825
}
1926
}
2027

2128
setInitialState(prepareInitialStateArgs) {
2229
this.initialState = {
23-
data: this.component.object.prepareInitialState(...prepareInitialStateArgs)
30+
data: this.component.object.getInitialStateWithMultiple(...prepareInitialStateArgs)
2431
};
2532
}
2633

2734
isPredefinedInitialStateSupported() {
28-
return this.component.object.getServicesMap && this.component.object.prepareInitialState;
29-
}
30-
31-
getServicesMap() {
32-
const services = this.component.object.services.map(
33-
serviceName => ServerApiManagerCache[serviceName]
35+
return (
36+
this.component.object.getServicesWithMultiple &&
37+
this.component.object.getInitialStateWithMultiple
3438
);
39+
}
3540

36-
const params = [...services, this.context];
37-
return this.component.object.getServicesMap(...params);
41+
getServicesWithMultiple() {
42+
const options = { isServer: false };
43+
return this.component.object.getServicesWithMultiple(this.context, options);
3844
}
3945

4046
render() {
4147
return new Promise(resolve => {
4248
renderComponent(this.component, this.context, this.initialState).then(response => {
43-
const { output, links, scripts, activeComponent, seoState, fullHtml } = response;
49+
const { output, links, fullHtml, ...rest } = response;
50+
const otherParams = omit(rest, blacklistOutput);
4451
const html = renderLinksAndScripts(output, '', '');
4552

4653
resolve({
4754
key: this.component.name,
4855
value: {
4956
html,
50-
scripts,
5157
style: links,
52-
activeComponent,
53-
seoState,
58+
...otherParams,
5459
...(isPreview(this.context?.query) && { fullHtml })
5560
},
5661
id: this.component.id

src/universal/partials/Welcome/PartialList.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const Welcome = () => {
1212
const { live = [], dev = [], page = [] } = groupBy(partials, item => item.status);
1313

1414
const renderItem = item => (
15-
<ListItem>
15+
<ListItem status={item.status}>
1616
<Link href={item.previewUrl ? item.previewUrl : `${item.url}?preview`} target="_blank">
1717
<Name>{item.name}</Name>
1818
<Url>{item.url}</Url>
@@ -26,12 +26,24 @@ const Welcome = () => {
2626
);
2727
return (
2828
<List>
29-
<HeaderName>Live</HeaderName>
30-
{live.map(item => renderItem(item))}
31-
<HeaderName>Pages</HeaderName>
32-
{page.map(item => renderItem(item))}
33-
<HeaderName>Development</HeaderName>
34-
{dev.map(item => renderItem(item))}
29+
{live.length > 0 && (
30+
<>
31+
<HeaderName>Live</HeaderName>
32+
{live.map(item => renderItem(item))}
33+
</>
34+
)}
35+
{page.length > 0 && (
36+
<>
37+
<HeaderName>Pages</HeaderName>
38+
{page.map(item => renderItem(item))}
39+
</>
40+
)}
41+
{dev.length > 0 && (
42+
<>
43+
<HeaderName>Development</HeaderName>
44+
{dev.map(item => renderItem(item))}
45+
</>
46+
)}
3547
</List>
3648
);
3749
};

src/universal/partials/Welcome/partials.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import components from '../../core/route/components';
22

3+
const previewPages = require('__V_PREVIEW_PAGES__');
4+
35
const partials = [];
46

57
Object.keys(components).forEach(path => {
@@ -10,5 +12,6 @@ Object.keys(components).forEach(path => {
1012
status: info.status
1113
});
1214
});
15+
partials.push(...previewPages.default.pages);
1316

1417
export default partials;

src/universal/partials/Welcome/styled.js

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import styled from 'styled-components';
22

33
const STATUS_COLOR = {
44
live: '#8dc63f',
5-
dev: '#FF6000'
5+
dev: '#FF6000',
6+
page: '#00abff'
67
};
8+
79
export const List = styled.ul`
810
list-style: none;
911
margin: 0;
1012
padding: 0;
13+
margin-bottom: 20px;
1114
`;
1215

1316
export const HeaderName = styled.div`
@@ -18,19 +21,41 @@ export const HeaderName = styled.div`
1821

1922
export const ListItem = styled.li`
2023
padding: 20px;
21-
border-radius: 2px;
22-
background: white;
23-
box-shadow: 0 2px 1px rgba(170, 170, 170, 0.25);
24-
position: relative;
2524
display: inline-block;
2625
vertical-align: top;
2726
height: 120px;
2827
width: 320px;
2928
margin: 10px;
3029
cursor: pointer;
30+
border-radius: 20px;
31+
border: 1px solid ${({ status }) => (status && STATUS_COLOR[status]) || '#8dc63f'};
32+
33+
position: relative;
34+
background-color: #fff;
35+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
36+
-webkit-transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
37+
transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
38+
39+
:after {
40+
content: '';
41+
border-radius: 20px;
42+
position: absolute;
43+
z-index: -1;
44+
top: 0;
45+
left: 0;
46+
width: 100%;
47+
height: 100%;
48+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
49+
opacity: 0;
50+
-webkit-transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
51+
transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
52+
}
3153
3254
&:hover {
33-
background: #efefef;
55+
transform: scale(1.02, 1.02);
56+
:after {
57+
opacity: 1;
58+
}
3459
}
3560
3661
@media screen and (max-width: 600px) {
@@ -58,7 +83,7 @@ export const Link = styled.a`
5883
`;
5984

6085
export const Name = styled.span`
61-
font-weight: 400;
86+
font-weight: 800;
6287
display: block;
6388
max-width: 80%;
6489
font-size: 16px;

0 commit comments

Comments
 (0)