Move HomepageTimer and use props over config (#7533)

This commit is contained in:
Andre Wanlin
2021-10-12 12:54:44 -05:00
committed by GitHub
parent a79f0f879d
commit 2435d7a49b
11 changed files with 304 additions and 12 deletions
@@ -0,0 +1,88 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { renderInTestApp } from '@backstage/test-utils';
import { HeaderWorldClock, ClockConfig } from './HeaderWorldClock';
import React from 'react';
import { lightTheme } from '@backstage/theme';
import { ThemeProvider } from '@material-ui/core';
describe('HeaderWorldClock with valid Time Zones', () => {
it('displays Time Zones as expected', async () => {
const clockConfigs: ClockConfig[] = [
{
label: 'NYC',
timeZone: 'America/New_York',
},
{
label: 'UTC',
timeZone: 'UTC',
},
{
label: 'STO',
timeZone: 'Europe/Stockholm',
},
{
label: 'TYO',
timeZone: 'Asia/Tokyo',
},
];
const rendered = await renderInTestApp(
<ThemeProvider theme={lightTheme}>
<HeaderWorldClock clockConfigs={clockConfigs} />
</ThemeProvider>,
);
expect(rendered.getByText('NYC')).toBeInTheDocument();
expect(rendered.getByText('UTC')).toBeInTheDocument();
expect(rendered.getByText('STO')).toBeInTheDocument();
expect(rendered.getByText('TYO')).toBeInTheDocument();
});
});
describe('HeaderWorldClock with no Time Zones provided', () => {
it('should not appear in output', async () => {
const clockConfigs: ClockConfig[] = [];
const rendered = await renderInTestApp(
<ThemeProvider theme={lightTheme}>
<HeaderWorldClock clockConfigs={clockConfigs} />
</ThemeProvider>,
);
expect(rendered.container).toBeEmptyDOMElement();
});
});
describe('HeaderWorldClock with invalid Time Zone', () => {
it('uses GMT as fallback Time Zone', async () => {
const clockConfigs: ClockConfig[] = [
{
label: 'New York',
timeZone: 'America/New_Pork',
},
];
const rendered = await renderInTestApp(
<ThemeProvider theme={lightTheme}>
<HeaderWorldClock clockConfigs={clockConfigs} />
</ThemeProvider>,
);
expect(rendered.getByText('GMT')).toBeInTheDocument();
});
});
@@ -0,0 +1,105 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { HeaderLabel } from '@backstage/core-components';
const timeFormat: Intl.DateTimeFormatOptions = {
hour: '2-digit',
minute: '2-digit',
};
type TimeObj = {
time: string;
label: string;
};
export type ClockConfig = {
label: string;
timeZone: string;
};
function getTimes(clockConfigs: ClockConfig[]) {
const d = new Date();
const lang = window.navigator.language;
const clocks: TimeObj[] = [];
if (!clockConfigs) {
return clocks;
}
for (const clockConfig of clockConfigs) {
let label = clockConfig.label;
const options: Intl.DateTimeFormatOptions = {
timeZone: clockConfig.timeZone,
...timeFormat,
};
try {
new Date().toLocaleString(lang, options);
} catch (e) {
// eslint-disable-next-line no-console
console.warn(
`The timezone ${options.timeZone} is invalid. Defaulting to GMT`,
);
options.timeZone = 'GMT';
label = 'GMT';
}
const time = d.toLocaleTimeString(lang, options);
clocks.push({ time, label });
}
return clocks;
}
export const HeaderWorldClock = ({
clockConfigs,
}: {
clockConfigs: ClockConfig[];
}) => {
const defaultTimes: TimeObj[] = [];
const [clocks, setTimes] = React.useState(defaultTimes);
React.useEffect(() => {
setTimes(getTimes(clockConfigs));
const intervalId = setInterval(() => {
setTimes(getTimes(clockConfigs));
}, 1000);
return () => {
clearInterval(intervalId);
};
}, [clockConfigs]);
if (clocks.length !== 0) {
return (
<>
{clocks.map(clock => (
<HeaderLabel
label={clock.label}
value={clock.time}
key={clock.label}
/>
))}
</>
);
}
return null;
};
@@ -0,0 +1,17 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { HeaderWorldClock } from './HeaderWorldClock';
export type { ClockConfig } from './HeaderWorldClock';
+2
View File
@@ -16,3 +16,5 @@
export { HomepageCompositionRoot } from './HomepageCompositionRoot';
export { SettingsModal } from './SettingsModal';
export { HeaderWorldClock } from './HeaderWorldClock';
export type { ClockConfig } from './HeaderWorldClock';
+2 -1
View File
@@ -29,5 +29,6 @@ export {
ComponentTab,
WelcomeTitle,
} from './plugin';
export { SettingsModal } from './components';
export { SettingsModal, HeaderWorldClock } from './components';
export type { ClockConfig } from './components';
export { createCardExtension } from './extensions';