Skip to content

Commit fcb76ca

Browse files
feat: implement importing scripts into ViewGroup (#1070)
1 parent 565028b commit fcb76ca

File tree

8 files changed

+49
-6
lines changed

8 files changed

+49
-6
lines changed

.changeset/wise-cats-melt.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@ensembleui/react-framework": patch
3+
"@ensembleui/react-kitchen-sink": patch
4+
"@ensembleui/react-runtime": patch
5+
---
6+
7+
feat: allow scripts import into ViewGroup

apps/kitchen-sink/src/ensemble/screens/menu.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
Import:
2+
- common
13
ViewGroup:
24
SideBar:
35
id: sidebar
@@ -29,7 +31,7 @@ ViewGroup:
2931
padding: 20px 0
3032
source: /logo.svg
3133
items:
32-
- label: Home
34+
- label: ${getHomeWidgetLabel()}
3335
icon: HomeOutlined
3436
page: home
3537
selected: true

apps/kitchen-sink/src/ensemble/scripts/common.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ const productTitleName = "SgrDvr";
22

33
const getDateLabel = (val) => {
44
return `i am a date label ${val}`
5+
}
6+
const getHomeWidgetLabel = () => {
7+
return 'Home';
58
}

packages/framework/src/hooks/useScreenContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { CustomThemeContext } from "./useThemeContext";
2424
import { useDeviceObserver } from "./useDeviceObserver";
2525

2626
interface ScreenContextProps {
27-
screen: EnsembleScreenModel;
27+
screen: Partial<EnsembleScreenModel>;
2828
context?: Partial<ScreenContextDefinition>;
2929
}
3030

packages/framework/src/parser.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ export const EnsembleParser = {
8787
const screen = parse(yaml) as EnsembleScreenYAML;
8888
const viewGroup = get(screen, "ViewGroup");
8989
if (viewGroup) {
90-
return EnsembleParser.parseMenu(viewGroup);
90+
// add Import block to the viewGroup
91+
set(viewGroup, "Import", get(screen, "Import"));
92+
return EnsembleParser.parseMenu(viewGroup, app);
9193
}
9294

9395
const pageScreen = EnsembleParser.parseScreen(id, name, screen, app);
@@ -255,7 +257,7 @@ export const EnsembleParser = {
255257
global,
256258
header: unwrapHeader(header),
257259
footer: unwrapFooter(footer),
258-
menu: menu ? EnsembleParser.parseMenu(menu) : undefined,
260+
menu: menu ? EnsembleParser.parseMenu(menu, app) : undefined,
259261
body: viewWidget,
260262
apis,
261263
styles: get(view, "styles"),
@@ -293,7 +295,7 @@ export const EnsembleParser = {
293295
};
294296
},
295297

296-
parseMenu: (menu: object): EnsembleMenuModel => {
298+
parseMenu: (menu: object, app: ApplicationDTO): EnsembleMenuModel => {
297299
const menuType = head(Object.keys(menu));
298300
if (!menuType || !includes(["SideBar", "Drawer"], String(menuType))) {
299301
throw Error("Invalid ViewGroup definition: invalid menu type");
@@ -305,13 +307,30 @@ export const EnsembleParser = {
305307
const footerDef = get(menu, [menuType, "footer"]) as
306308
| { [key: string]: unknown }
307309
| undefined;
310+
311+
// handle import block
312+
const importBlock = get(menu, "Import") as unknown[] | undefined;
313+
let importedScripts: string | undefined;
314+
if (isArray(importBlock)) {
315+
const matchingScripts = filter(app.scripts, (script) =>
316+
includes(importBlock, script.name),
317+
);
318+
if (!isEmpty(matchingScripts)) {
319+
importedScripts = matchingScripts.reduce(
320+
(acc, script) => acc.concat(script.content, "\n\n"),
321+
"",
322+
);
323+
}
324+
}
325+
308326
return {
309327
id: get(menu, [menuType, "id"]) as string | undefined,
310328
type: menuType as EnsembleMenuModelType,
311329
items: (get(menu, [menuType, "items"]) as []) ?? [],
312330
header: headerDef ? unwrapWidget(headerDef) : undefined,
313331
footer: footerDef ? unwrapWidget(footerDef) : undefined,
314332
styles: get(menu, [menuType, "styles"]) as { [key: string]: unknown },
333+
importedScripts,
315334
};
316335
},
317336
};

packages/framework/src/shared/models.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface EnsembleMenuModel {
5656
header?: EnsembleWidget;
5757
footer?: EnsembleWidget;
5858
styles: { [key: string]: unknown };
59+
importedScripts?: string;
5960
}
6061

6162
export enum EnsembleMenuModelType {

packages/runtime/src/runtime/entry.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
ScreenContextProvider,
23
type EnsembleEntryPoint,
34
type EnsembleScreenModel,
45
} from "@ensembleui/react-framework";
@@ -50,7 +51,16 @@ export const EnsembleEntry: React.FC<EnsembleEntryProps> = ({
5051

5152
if (hasMenu) {
5253
const { type: menuType, ...menu } = entry;
53-
return <EnsembleMenu type={menuType} menu={menu} />;
54+
const screen = {
55+
id: entry.id,
56+
name: entry.id,
57+
importedScripts: menu.importedScripts,
58+
};
59+
return (
60+
<ScreenContextProvider screen={screen}>
61+
<EnsembleMenu menu={menu} type={menuType} />
62+
</ScreenContextProvider>
63+
);
5464
}
5565

5666
if (location.pathname !== "/") {

packages/runtime/src/runtime/menu.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ interface MenuBaseProps<T> {
7272
header?: EnsembleWidget;
7373
footer?: EnsembleWidget;
7474
onCollapse?: EnsembleAction;
75+
importedScripts?: string;
7576
}
7677

7778
interface MenuStyles {

0 commit comments

Comments
 (0)