[CP-2347] Added theme and block boxes (#1624)

This commit is contained in:
Michał Kurczewski
2024-01-05 14:14:41 +01:00
committed by GitHub
parent a8124b7695
commit d3b9e48db5
31 changed files with 310 additions and 61 deletions

View File

@@ -3,3 +3,4 @@ jest
jest.config.ts jest.config.ts
jest.preset.js jest.preset.js
demo-data demo-data
auth-server.test.ts

View File

@@ -128,5 +128,4 @@ module.exports = {
version: "detect", version: "detect",
}, },
}, },
ignorePatterns: ["auth-server.test.ts", "./jest"],
} }

View File

@@ -8,6 +8,7 @@ import { useParams } from "react-router"
import { useSelector } from "react-redux" import { useSelector } from "react-redux"
import { ReduxRootState } from "Core/__deprecated__/renderer/store" import { ReduxRootState } from "Core/__deprecated__/renderer/store"
import { isEmpty } from "lodash" import { isEmpty } from "lodash"
import { GenericThemeProvider } from "generic-view/theme"
import RecursiveLayout from "../recursive-layout/recursive-layout" import RecursiveLayout from "../recursive-layout/recursive-layout"
export const GenericView: FunctionComponent = () => { export const GenericView: FunctionComponent = () => {
@@ -22,7 +23,11 @@ export const GenericView: FunctionComponent = () => {
return <div>Not found</div> return <div>Not found</div>
} }
return <RecursiveLayout viewKey={viewKey} componentKey={"main"} /> return (
<GenericThemeProvider>
<RecursiveLayout viewKey={viewKey} componentKey={"main"} />
</GenericThemeProvider>
)
} }
export default GenericView export default GenericView

View File

@@ -4,7 +4,6 @@
*/ */
// TODO: demo code, file to be removed // TODO: demo code, file to be removed
import { wait } from "fork-ts-checker-webpack-plugin/lib/utils/async/wait"
import { import {
generateMcCalendarLayout, generateMcCalendarLayout,
generateMcOverviewLayout, generateMcOverviewLayout,
@@ -33,11 +32,9 @@ export const useGenericStoreDemo = () => {
} }
// Simulate menu setup after device connection // Simulate menu setup after device connection
await wait(2000)
dispatch(setMenu(generateMenu(menuConfig))) dispatch(setMenu(generateMenu(menuConfig)))
// Simulate mc-overview layout // Simulate mc-overview layout
await wait(1000)
dispatch( dispatch(
setViewLayout({ setViewLayout({
feature: "mc-overview", feature: "mc-overview",
@@ -46,7 +43,6 @@ export const useGenericStoreDemo = () => {
) )
// Simulate mc-calendar layout // Simulate mc-calendar layout
await wait(1000)
dispatch( dispatch(
setViewLayout({ setViewLayout({
feature: "mc-calendar", feature: "mc-calendar",
@@ -54,7 +50,6 @@ export const useGenericStoreDemo = () => {
}) })
) )
await wait(1000)
dispatch( dispatch(
setViewData({ setViewData({
feature: "mc-overview", feature: "mc-overview",

View File

@@ -0,0 +1,20 @@
{
"presets": [
[
"@nx/react/babel",
{
"runtime": "automatic",
"useBuiltIns": "usage"
}
]
],
"plugins": [
[
"styled-components",
{
"pure": true,
"ssr": true
}
]
]
}

View File

@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.js"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@@ -0,0 +1,7 @@
# generic-view-theme
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test generic-view-theme` to execute the unit tests via [Jest](https://jestjs.io).

View File

@@ -0,0 +1,11 @@
/* eslint-disable */
export default {
displayName: "generic-view-theme",
preset: "../../../jest.preset.js",
transform: {
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nx/react/plugins/jest",
"^.+\\.[tj]sx?$": ["babel-jest", { presets: ["@nx/react/babel"] }],
},
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
coverageDirectory: "../../../coverage/libs/generic-view/theme",
}

View File

@@ -0,0 +1,20 @@
{
"name": "generic-view-theme",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/generic-view/theme/src",
"projectType": "library",
"tags": [],
"targets": {
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"]
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/generic-view/theme/jest.config.ts"
}
}
}
}

View File

@@ -0,0 +1,7 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
export * from "./lib/generic-theme-provider"
export * from "./lib/theme"

View File

@@ -0,0 +1,9 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
export const color = {
white: "#FFFFFF",
grey6: "#FBFBFB",
} as const

View File

@@ -0,0 +1,8 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
export const fontSize = {
headline3: "24px",
} as const

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
import React, { FunctionComponent, PropsWithChildren } from "react"
import { createGlobalStyle, ThemeProvider } from "styled-components"
import { Theme, theme } from "./theme"
export const GenericThemeProvider: FunctionComponent<PropsWithChildren> = ({
children,
}) => {
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
{children}
</ThemeProvider>
)
}
const GlobalStyle = createGlobalStyle<{ theme: Theme }>`
* {
box-sizing: border-box;
}
`

View File

@@ -0,0 +1,8 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
export const lineHeight = {
headline3: "32px",
} as const

View File

@@ -0,0 +1,8 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
export const radius = {
sm: "4px",
} as const

View File

@@ -0,0 +1,12 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
export const space = {
xs: "4px",
sm: "8px",
md: "12px",
lg: "16px",
xl: "24px",
} as const

View File

@@ -0,0 +1,20 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
import { color } from "./color"
import { fontSize } from "./font-size"
import { radius } from "./radius"
import { space } from "./space"
import { lineHeight } from "./line-height"
export const theme = {
color,
radius,
space,
fontSize,
lineHeight,
} as const
export type Theme = typeof theme

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../../../tsconfig.base.json"
}

View File

@@ -0,0 +1,23 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": [
"node",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts",
]
},
"exclude": [
"jest.config.ts",
"src/**/*.spec.ts",
"src/**/*.test.ts",
"src/**/*.spec.tsx",
"src/**/*.test.tsx",
"src/**/*.spec.js",
"src/**/*.test.js",
"src/**/*.spec.jsx",
"src/**/*.test.jsx"
],
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
}

View File

@@ -0,0 +1,20 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.test.tsx",
"src/**/*.spec.tsx",
"src/**/*.test.js",
"src/**/*.spec.js",
"src/**/*.test.jsx",
"src/**/*.spec.jsx",
"src/**/*.d.ts"
]
}

View File

@@ -1,6 +1,6 @@
{ {
"extends": ["../../../.eslintrc.js"], "extends": ["../../../.eslintrc.js"],
"ignorePatterns": ["!**/*"], "ignorePatterns": ["!**/*", "styled.d.ts"],
"overrides": [ "overrides": [
{ {
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
@@ -8,7 +8,9 @@
}, },
{ {
"files": ["*.ts", "*.tsx"], "files": ["*.ts", "*.tsx"],
"rules": {} "rules": {
"@typescript-eslint/no-unsafe-return": "off"
}
}, },
{ {
"files": ["*.js", "*.jsx"], "files": ["*.js", "*.jsx"],

View File

@@ -19,19 +19,24 @@ const BlockBox: APIFC<undefined, BlockBoxParameters> = ({
...props ...props
}) => { }) => {
return ( return (
<BoxWrapper {...props} className={`${className} custom`}> <Block {...props} className={className}>
{config?.title && <h1>{config.title}</h1>} {config?.title && <Headline>{config.title}</Headline>}
{children} {children}
</BoxWrapper> </Block>
) )
} }
export default withConfig(BlockBox) export default withConfig(BlockBox)
const BoxWrapper = styled.div` const Block = styled.div`
&.custom { background-color: ${({ theme }) => theme.color.white};
height: 90%; border-radius: ${({ theme }) => theme.radius.sm};
} padding: ${({ theme }) => theme.space.xl};
box-sizing: border-box;
background-color: #ccc; `
const Headline = styled.h3`
margin: 0;
font-size: ${({ theme }) => theme.fontSize.headline3};
line-height: ${({ theme }) => theme.lineHeight.headline3};
` `

View File

@@ -4,11 +4,9 @@
*/ */
import React from "react" import React from "react"
import styled from "styled-components"
import { APIFC } from "generic-view/utils" import { APIFC } from "generic-view/utils"
export const BlockWrapper: APIFC = ({ config, data, ...props }) => { export const BlockPlain: APIFC = ({ config, data, ...props }) => {
return <Wrapper {...props} /> return <div {...props} />
} }
const Wrapper = styled.div``

View File

@@ -1,17 +0,0 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
import React from "react"
import styled from "styled-components"
import { APIFC } from "generic-view/utils"
export const BlockVanilla: APIFC = ({ config, data, ...props }) => {
return <BoxWrapper {...props} />
}
const BoxWrapper = styled.div`
width: 100%;
height: 100%;
`

View File

@@ -4,11 +4,9 @@
*/ */
import BlockBox from "./block-box" import BlockBox from "./block-box"
import { BlockVanilla } from "./block-vanilla" import { BlockPlain } from "./block-plain"
import { BlockWrapper } from "./block-wrapper"
export const blocks = { export const blocks = {
"block-plain": BlockPlain,
"block-box": BlockBox, "block-box": BlockBox,
"block-vanilla": BlockVanilla,
"block-wrapper": BlockWrapper,
} }

13
libs/generic-view/ui/styled.d.ts vendored Normal file
View File

@@ -0,0 +1,13 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
import "styled-components"
import { Theme } from "../theme/src"
type CustomTheme = Theme
declare module "styled-components" {
export interface DefaultTheme extends CustomTheme {}
}

View File

@@ -7,7 +7,6 @@
"strict": true "strict": true
}, },
"files": [], "files": [],
"include": [],
"references": [ "references": [
{ {
"path": "./tsconfig.lib.json" "path": "./tsconfig.lib.json"

View File

@@ -4,7 +4,6 @@
"outDir": "../../../dist/out-tsc", "outDir": "../../../dist/out-tsc",
"types": [ "types": [
"node", "node",
"@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts" "@nx/react/typings/image.d.ts"
] ]
@@ -20,5 +19,11 @@
"src/**/*.spec.jsx", "src/**/*.spec.jsx",
"src/**/*.test.jsx" "src/**/*.test.jsx"
], ],
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] "include": [
"src/**/*.js",
"src/**/*.jsx",
"src/**/*.ts",
"src/**/*.tsx",
"./styled.d.ts"
]
} }

View File

@@ -18,7 +18,7 @@ export const generateMcCalendarLayout: ViewGenerator<CalendarConfig> = (
) => { ) => {
return { return {
main: { main: {
component: "block-vanilla", component: "block-plain",
parameters: { parameters: {
layout: { layout: {
gridLayout: { gridLayout: {

View File

@@ -124,11 +124,11 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
) => { ) => {
return { return {
main: { main: {
component: "block-wrapper", component: "block-plain",
layout: { layout: {
padding: "2rem", padding: "32px",
gridLayout: { gridLayout: {
rows: [1, 1, 1], rows: ["261px", "205px", 1],
columns: [1, 2], columns: [1, 2],
columnGap: "2rem", columnGap: "2rem",
rowGap: "2rem", rowGap: "2rem",
@@ -137,11 +137,17 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
grow: 1, grow: 1,
}, },
}, },
childrenKeys: ["summary", "status", "update"], childrenKeys: [
"summary",
...config.sections.map((section) => section.key),
],
}, },
...(config.summary.show && { ...(config.summary.show && {
summary: { summary: {
component: "block-box", component: "block-box",
config: {
title: "Summary",
},
layout: { layout: {
gridPlacement: { gridPlacement: {
row: 1, row: 1,
@@ -154,9 +160,7 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
justifyContent: "space-between", justifyContent: "space-between",
}, },
}, },
config: {
title: "Summary",
},
childrenKeys: [ childrenKeys: [
config.summary.showImg ? "summaryImg" : undefined, config.summary.showImg ? "summaryImg" : undefined,
config.summary.showSerialNumber ? "serial-number" : undefined, config.summary.showSerialNumber ? "serial-number" : undefined,
@@ -164,7 +168,7 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
].filter(Boolean) as string[], ].filter(Boolean) as string[],
}, },
summaryImg: { summaryImg: {
component: "block-box", component: "block-plain",
layout: { layout: {
flexPlacement: { flexPlacement: {
alignSelf: "center", alignSelf: "center",
@@ -175,7 +179,7 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
}, },
}, },
"serial-number": { "serial-number": {
component: "block-box", component: "block-plain",
layout: { layout: {
flexPlacement: { flexPlacement: {
alignSelf: "center", alignSelf: "center",
@@ -186,7 +190,7 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
}, },
}, },
about: { about: {
component: "block-box", component: "block-plain",
layout: { layout: {
flexPlacement: { flexPlacement: {
alignSelf: "center", alignSelf: "center",
@@ -199,6 +203,9 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
}), }),
status: { status: {
component: "block-box", component: "block-box",
config: {
title: "Status",
},
layout: { layout: {
gridPlacement: { gridPlacement: {
row: 1, row: 1,
@@ -210,9 +217,7 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
direction: "column", direction: "column",
}, },
}, },
parameters: {
title: "Status",
},
childrenKeys: ["battery", "connection"], childrenKeys: ["battery", "connection"],
}, },
battery: { battery: {
@@ -228,6 +233,9 @@ export const generateMcOverviewLayout: ViewGenerator<OverviewConfig> = (
}, },
update: { update: {
component: "block-box", component: "block-box",
config: {
title: "MuditaOS",
},
layout: { layout: {
gridPlacement: { gridPlacement: {
row: 2, row: 2,

View File

@@ -33,6 +33,7 @@
"device/models": ["libs/device/models/src/index.ts"], "device/models": ["libs/device/models/src/index.ts"],
"generic-view/feature": ["libs/generic-view/feature/src/index.ts"], "generic-view/feature": ["libs/generic-view/feature/src/index.ts"],
"generic-view/store": ["libs/generic-view/store/src/index.ts"], "generic-view/store": ["libs/generic-view/store/src/index.ts"],
"generic-view/theme": ["libs/generic-view/theme/src/index.ts"],
"generic-view/ui": ["libs/generic-view/ui/src/index.ts"], "generic-view/ui": ["libs/generic-view/ui/src/index.ts"],
"generic-view/utils": ["libs/generic-view/utils/src/index.ts"], "generic-view/utils": ["libs/generic-view/utils/src/index.ts"],
"generic-view/views": ["libs/generic-view/views/src/index.ts"] "generic-view/views": ["libs/generic-view/views/src/index.ts"]
@@ -42,6 +43,7 @@
"node_modules", "node_modules",
"./apps/mudita-center/node_modules", "./apps/mudita-center/node_modules",
"./apps/mudita-center/dist", "./apps/mudita-center/dist",
"./apps/mudita-center/__mocks__" "./apps/mudita-center/__mocks__",
"./libs/generic-view/ui/styled.d.ts"
] ]
} }