Skip to content

Commit

Permalink
feat: merge internal and federated messages into i18n
Browse files Browse the repository at this point in the history
This commit adds code to merge in module i18n messages into the messages object in the runtime.  This means that when new modules, their localized messages will be available.
  • Loading branch information
davidjoy committed Nov 5, 2024
1 parent aa90191 commit a9f5145
Show file tree
Hide file tree
Showing 22 changed files with 193 additions and 72 deletions.
2 changes: 1 addition & 1 deletion runtime/i18n/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export {
IntlProvider,
createIntl,
defineMessages,
useIntl
useIntl,
} from 'react-intl';

export {
Expand Down
2 changes: 1 addition & 1 deletion runtime/i18n/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ export function handleRtl() {
* @returns {Object}
* @memberof module:Internationalization
*/
export function mergeMessages(newMessages) {
export function mergeMessages(newMessages = {}) {
const msgs = Array.isArray(newMessages) ? merge({}, ...newMessages) : newMessages;
messages = merge(messages, msgs);

Expand Down
4 changes: 3 additions & 1 deletion shell/bootstrap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '../runtime';

import { SHELL_ID } from './data/constants';
import { getFederationRemotes } from './data/moduleUtils';
import { getFederationRemotes, mergeInternalMessages } from './data/moduleUtils';
import messages from './i18n';
import createRouter from './router/createRouter';

Expand All @@ -22,6 +22,8 @@ subscribe(APP_READY, () => {

const router = createRouter();

mergeInternalMessages();

ReactDOM.render(
<RouterProvider router={router} />,
document.getElementById('root'),
Expand Down
10 changes: 9 additions & 1 deletion shell/data/moduleUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { loadRemote } from '@module-federation/runtime';
import { getConfig } from '../../runtime';
import { getConfig, mergeMessages } from '../../runtime';
import {
AppConfig, AppConfigTypes, ApplicationModuleConfig,
AppsConfig,
Expand Down Expand Up @@ -49,3 +49,11 @@ export function getInternalModules() {
const { apps } = getConfig();
return filterAppsByType<InternalAppConfig>(apps, AppConfigTypes.INTERNAL);
}

export function mergeInternalMessages() {
const modules = getInternalModules();

Object.values(modules).forEach((module) => {
mergeMessages(module.config.messages);
});
}
21 changes: 0 additions & 21 deletions shell/dev-project/HomePage.tsx

This file was deleted.

File renamed without changes.
24 changes: 24 additions & 0 deletions shell/dev-project/home/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Link } from 'react-router-dom';
import { useIntl } from '../../../runtime';
import { getAppUrl } from '../../../runtime/routing';
import messages from './messages';

export default function HomePage() {
const moduleOneUrl = getAppUrl('moduleOne');
const dashboardUrl = getAppUrl('learnerDashboard');
const intl = useIntl();

return (
<div className="p-3">
<p>{intl.formatMessage(messages.homeContent)}</p>
<ul>
{moduleOneUrl !== null && (
<li><Link to={moduleOneUrl}>Go to module one page</Link></li>
)}
{dashboardUrl !== null && (
<li><Link to={dashboardUrl}>Go to dashboard page</Link></li>
)}
</ul>
</div>
);
}
27 changes: 27 additions & 0 deletions shell/dev-project/home/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Placeholder be overridden by `make pull_translations`
export default {
ar: {},
'zh-hk': {},
'zh-cn': {},
uk: {},
'tr-tr': {},
th: {},
te: {},
ru: {},
'pt-pt': {},
'pt-br': {},
'it-it': {},
id: {},
hi: {},
he: {},
'fr-ca': {
'home.content': 'Home content in French.'
},
fa: {},
'es-es': {},
'es-419': {},
el: {},
'de-de': {},
da: {},
bo: {},
};
12 changes: 12 additions & 0 deletions shell/dev-project/home/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import HomePage from './HomePage';
import messages from './i18n';

const config = {
route: {
path: '/',
Component: HomePage,
},
messages,
};

export default config;
11 changes: 11 additions & 0 deletions shell/dev-project/home/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineMessages } from '../../../runtime';

const messages = defineMessages({
homeContent: {
id: 'home.content',
defaultMessage: 'Home page content.',
description: 'Content for the dev project home page.',
},
});

export default messages;
File renamed without changes.
25 changes: 25 additions & 0 deletions shell/dev-project/learner-dashboard/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Placeholder be overridden by `make pull_translations`
export default {
ar: {},
'zh-hk': {},
'zh-cn': {},
uk: {},
'tr-tr': {},
th: {},
te: {},
ru: {},
'pt-pt': {},
'pt-br': {},
'it-it': {},
id: {},
hi: {},
he: {},
'fr-ca': {},
fa: {},
'es-es': {},
'es-419': {},
el: {},
'de-de': {},
da: {},
bo: {},
};
10 changes: 10 additions & 0 deletions shell/dev-project/learner-dashboard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import DashboardPage from './DashboardPage';

const config = {
route: {
path: 'dashboard',
Component: DashboardPage,
}
};

export default config;
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Link } from 'react-router-dom';

export default function ChildOnePage() {
export default function ModuleOnePage() {
return (
<div className="p-3">
<p>Child one content.</p>
<p>Module one content.</p>
<Link to="/">Go to home page</Link>
</div>
);
Expand Down
25 changes: 25 additions & 0 deletions shell/dev-project/module-one/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Placeholder be overridden by `make pull_translations`
export default {
ar: {},
'zh-hk': {},
'zh-cn': {},
uk: {},
'tr-tr': {},
th: {},
te: {},
ru: {},
'pt-pt': {},
'pt-br': {},
'it-it': {},
id: {},
hi: {},
he: {},
'fr-ca': {},
fa: {},
'es-es': {},
'es-419': {},
el: {},
'de-de': {},
da: {},
bo: {},
};
26 changes: 26 additions & 0 deletions shell/dev-project/module-one/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { primaryLinks } from '../../header/defaults';
import ModuleOnePage from './ModuleOnePage';

const config = {
header: {
primaryLinks: [
{
label: 'Child Link',
url: '#'
},
...primaryLinks,
],
secondaryLinks: [
{
label: 'Child Help',
appId: 'support',
}
],
},
route: {
path: 'module-one',
Component: ModuleOnePage,
}
};

export default config;
2 changes: 1 addition & 1 deletion shell/footer/data/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function resolveFooterConfig(appId: string | null): ResolvedFooterConfig

const config: ResolvedFooterConfig = {
logoUrl: siteConfig.LOGO_URL,
logoDestinationUrl: getAppUrl('learner-dashboard'),
logoDestinationUrl: getAppUrl('learnerDashboard'),
leftLinks,
centerLinks,
rightLinks,
Expand Down
2 changes: 1 addition & 1 deletion shell/header/data/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function resolveHeaderConfig(appId: string | null): ResolvedHeaderConfig

const config = {
logoUrl: siteConfig.LOGO_URL,
logoDestinationUrl: getAppUrl('learner-dashboard'),
logoDestinationUrl: getAppUrl('learnerDashboard'),
primaryLinks,
secondaryLinks,
anonymousLinks,
Expand Down
4 changes: 2 additions & 2 deletions shell/header/defaults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import RegisterButton from './anonymous-menu/RegisterButton';

export const primaryLinks: MenuItemConfig[] = [
{
appId: 'learner-dashboard',
appId: 'learnerDashboard',
label: 'Courses',
},
];
Expand All @@ -19,7 +19,7 @@ export const anonymousLinks: MenuItemConfig[] = [

export const authenticatedLinks: ChildMenuItemConfig[] = [
{
appId: 'learner-dashboard',
appId: 'learnerDashboard',
label: messages['header.user.menu.dashboard']
},
{
Expand Down
2 changes: 2 additions & 0 deletions shell/router/patchRoutesOnNavigation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { RouteObject } from 'react-router';
import { mergeMessages } from '../../runtime';
import { patchAppModuleConfig } from '../../runtime/config';
import { FederatedAppConfig } from '../../types';
import { SHELL_ID } from '../data/constants';
Expand Down Expand Up @@ -29,6 +30,7 @@ export default async function patchRoutesOnNavigation({ path, patch }: PatchRout
patchAppIdIntoRouteHandle(missingAppId, moduleConfig.route);
patch(SHELL_ID, [moduleConfig.route]);
patchAppModuleConfig(missingAppId, moduleConfig);
mergeMessages(moduleConfig.messages);
} else {
// TODO: What do we do if it doesn't work?
console.log('uhoh, no module config.');
Expand Down
51 changes: 10 additions & 41 deletions shell/site.config.dev.shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,25 @@ import { Button } from '@openedx/paragon';
import { Divider } from '../runtime';
import { AppConfigTypes, EnvironmentTypes, ProjectSiteConfig } from '../types';

import ChildOnePage from './dev-project/ChildOnePage';
import CoursesLink from './dev-project/CoursesLink';
import DashboardPage from './dev-project/DashboardPage';
import HomePage from './dev-project/HomePage';
import { primaryLinks } from './header/defaults';
import CoursesLink from './dev-project/header/CoursesLink';
import homeConfig from './dev-project/home';
import learnerDashboardConfig from './dev-project/learner-dashboard';
import moduleOneConfig from './dev-project/module-one';
import './index.scss';

const config: ProjectSiteConfig = {
apps: {
home: {
type: AppConfigTypes.INTERNAL,
config: {
route: {
path: '/',
Component: HomePage,
}
}
config: homeConfig,
},
child1: {
moduleOne: {
type: AppConfigTypes.INTERNAL,
config: {
header: {
primaryLinks: [
{
label: 'Child Link',
url: '#'
},
...primaryLinks,
],
secondaryLinks: [
{
label: 'Child Help',
appId: 'support',
}
],
},
route: {
path: 'child1',
Component: ChildOnePage,
}
}
config: moduleOneConfig,
},
'learner-dashboard': {
learnerDashboard: {
type: AppConfigTypes.INTERNAL,
config: {
route: {
path: 'dashboard',
Component: DashboardPage,
}
}
config: learnerDashboardConfig,
},
support: {
type: AppConfigTypes.EXTERNAL,
Expand All @@ -67,7 +36,7 @@ const config: ProjectSiteConfig = {
primaryLinks: [
{
label: (<CoursesLink />),
appId: 'learner-dashboard',
appId: 'learnerDashboard',
},
{
label: 'Other',
Expand Down
1 change: 1 addition & 0 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface ApplicationModuleConfig {
route: AppModuleRouteObject,
header?: HeaderConfig,
footer?: FooterConfig,
messages?: Record<string, Record<string, string>>,
}

export interface InternalAppConfig {
Expand Down

0 comments on commit a9f5145

Please sign in to comment.