Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CP-3322] Implement Dynamic Category Display Based on EntityTypes Configuration #2211

Merged
merged 5 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const contactsView: View = {
main: {
component: "mc-contacts-view",
config: {
entityType: "contacts",
entityTypes: ["contacts"],
},
// @ts-ignore
screenTitle: "Contacts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import { View } from "generic-view/utils"
export const fileManagerView: View = {
main: {
component: "mc-file-manager-view",
config: {
entityTypes: [
"audioFiles",
"imageFiles",
"ebookFiles",
"applicationFiles",
mkurczewski marked this conversation as resolved.
Show resolved Hide resolved
],
},
// @ts-ignore
screenTitle: "Manage Files",
},
Expand Down
2 changes: 1 addition & 1 deletion libs/generic-view/models/src/lib/entities-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { z } from "zod"
const dataValidator = z.undefined()

const configValidator = z.object({
entitiesTypes: z.array(z.string()),
entityTypes: z.array(z.string()),
text: z.string().optional(),
})

Expand Down
2 changes: 1 addition & 1 deletion libs/generic-view/models/src/lib/mc-contacts-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { z } from "zod"
const dataValidator = z.undefined()

const configValidator = z.object({
entityType: z.string().min(1),
entityTypes: z.array(z.string()).min(1),
})

export type McContactsView = z.infer<typeof configValidator>
Expand Down
4 changes: 3 additions & 1 deletion libs/generic-view/models/src/lib/mc-file-manager-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import { z } from "zod"

const dataValidator = z.undefined()

const configValidator = z.undefined()
const configValidator = z.object({
entityTypes: z.array(z.string()).min(1),
})

export type McFileManagerView = z.infer<typeof configValidator>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,21 @@ export const getGenericConfig = createAsyncThunk<
const response = await getFeatureConfigRequest(deviceId, feature)

if (response.ok) {
let fullView = transformGenericComponents(response.data)
let fullView

if (process.env.DEV_API_CONFIG === "1") {
if (process.env.DEV_API_CONFIG !== "1") {
fullView = transformGenericComponents(response.data)
} else {
const devConfig =
feature in devViews
? devViews[feature as keyof typeof devViews]
: undefined

fullView = transformGenericComponents({
...response.data,
...devConfig,
})

fullView = {
...fullView,
...devConfig,
Expand Down
25 changes: 10 additions & 15 deletions libs/generic-view/ui/src/lib/entities/entities-loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*/

import React, { useCallback, useEffect, useState } from "react"
import { useDispatch, useSelector } from "react-redux"
import styled from "styled-components"
import { sum } from "lodash"
import { APIFC } from "generic-view/utils"
import { EntitiesLoaderConfig } from "generic-view/models"
import {
Expand All @@ -12,12 +15,9 @@ import {
selectActiveApiDeviceId,
selectEntitiesLoadingState,
} from "generic-view/store"
import { useDispatch, useSelector } from "react-redux"
import { Dispatch, ReduxRootState } from "Core/__deprecated__/renderer/store"
import styled from "styled-components"
import { H3 } from "../texts/headers"
import { ProgressBar } from "../interactive/progress-bar/progress-bar"
import { sum } from "lodash"

export const EntitiesLoader: APIFC<undefined, EntitiesLoaderConfig> = ({
config,
Expand All @@ -30,7 +30,7 @@ export const EntitiesLoader: APIFC<undefined, EntitiesLoaderConfig> = ({
const entitiesLoadingStates = useSelector((state: ReduxRootState) =>
selectEntitiesLoadingState(state, { deviceId })
)
const allLoaded = config.entitiesTypes.every(
const allLoaded = config.entityTypes.every(
(entitiesType) => entitiesLoadingStates[entitiesType]?.state === "loaded"
)
const [showProgress, setShowProgress] = useState(!allLoaded)
Expand All @@ -45,13 +45,13 @@ export const EntitiesLoader: APIFC<undefined, EntitiesLoaderConfig> = ({
)

useEffect(() => {
const progress = config.entitiesTypes.reduce((acc, entitiesType) => {
acc[entitiesType] = 0
const entity = entitiesLoadingStates[entitiesType]
const progress = config.entityTypes.reduce((acc, entityType) => {
acc[entityType] = 0
const entity = entitiesLoadingStates[entityType]
if (entity?.state === "idle") {
void fetchEntityData(entitiesType)
void fetchEntityData(entityType)
} else if (entity?.state === "loading" || entity?.state === "loaded") {
acc[entitiesType] = entity.progress
acc[entityType] = entity.progress
}
return acc
}, {} as Record<string, number>)
Expand All @@ -61,12 +61,7 @@ export const EntitiesLoader: APIFC<undefined, EntitiesLoaderConfig> = ({
? sum(Object.values(progress)) / Object.keys(progress).length
: 0
setTotalProgress(totalProgress)
}, [
config.entitiesTypes,
dispatch,
entitiesLoadingStates,
fetchEntityData,
])
}, [config.entityTypes, dispatch, entitiesLoadingStates, fetchEntityData])

useEffect(() => {
let timeout: NodeJS.Timeout
Expand Down
2 changes: 1 addition & 1 deletion libs/generic-view/ui/src/lib/generated/mc-contacts-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const generateMcContactsView: ComponentGenerator<McContactsView> = (
contactsLoader: {
component: "entities-loader",
config: {
entitiesTypes: [config.entityType],
entityTypes: config.entityTypes,
text: "Loading contacts, please wait...",
},
layout: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,40 @@ interface CategoryListItemConfig {
icon: IconType
}

const CONFIG_MAP: Record<string, Omit<CategoryListItemConfig, "id">> = {
audioFiles: {
name: "Music",
icon: IconType.MusicNote,
markerColor: "#E38577",
entitiesType: "audioFiles",
},
imageFiles: {
name: "Photos",
icon: IconType.PhotoCatalog,
markerColor: "#0E7490",
entitiesType: "imageFiles",
},
ebookFiles: {
name: "Ebooks",
icon: IconType.Book,
markerColor: "#A8DADC",
entitiesType: "ebookFiles",
},
applicationFiles: {
name: "Apps",
icon: IconType.Grid,
markerColor: "#AEBEC9",
entitiesType: "applicationFiles",
},
mkurczewski marked this conversation as resolved.
Show resolved Hide resolved
}

function getConfigByEntityType(
entityType: string,
id: string
): CategoryListItemConfig | undefined {
return { ...CONFIG_MAP[entityType], id } || undefined
}

const generateFileCategoryListItem = ({
id,
name,
Expand Down Expand Up @@ -162,11 +196,7 @@ const generateFileCategoryListItem = ({
}
}

export const generateFileCategoryList = ({
configs,
}: {
configs: CategoryListItemConfig[]
}): Subview => {
export const generateFileCategoryList = (entitiesTypes: string[]): Subview => {
const initialListConfig: Subview = {
fileCategoryList: {
component: "block-plain",
Expand All @@ -179,7 +209,11 @@ export const generateFileCategoryList = ({
},
}

return configs.reduce((previousValue, config) => {
return entitiesTypes.reduce((previousValue, entitiesType, index) => {
const config = getConfigByEntityType(entitiesType, String(index))
if (!config) {
return previousValue
}
const categoryItemKey = `${config.id}CategoryListItem`
previousValue["fileCategoryList"]?.childrenKeys?.push(categoryItemKey)
previousValue = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,32 @@ interface FileListConfig {
entitiesType: string
}

const CONFIG_MAP: Record<string, Omit<FileListConfig, "id">> = {
audioFiles: {
name: "Music",
entitiesType: "audioFiles",
},
imageFiles: {
name: "Photos",
entitiesType: "imageFiles",
},
ebookFiles: {
name: "Ebooks",
entitiesType: "ebookFiles",
},
applicationFiles: {
name: "Apps",
entitiesType: "applicationFiles",
},
mkurczewski marked this conversation as resolved.
Show resolved Hide resolved
}

function getConfigByEntityType(
entityType: string,
id: string
): FileListConfig | undefined {
return { ...CONFIG_MAP[entityType], id } || undefined
}

const generateFileList = ({
id,
name,
Expand Down Expand Up @@ -438,11 +464,7 @@ const generateFileList = ({
}
}

export const generateFileListWrapper = ({
configs,
}: {
configs: FileListConfig[]
}): Subview => {
export const generateFileListWrapper = (entitiesTypes: string[]): Subview => {
const initialListConfig: Subview = {
fileListWrapper: {
component: "block-plain",
Expand All @@ -456,7 +478,11 @@ export const generateFileListWrapper = ({
},
}

return configs.reduce((previousValue, config) => {
return entitiesTypes.reduce((previousValue, entitiesType, index) => {
const config = getConfigByEntityType(entitiesType, String(index))
if (!config) {
return previousValue
}
const categoryItemKey = `${config.id}fileListContainer`
previousValue["fileListWrapper"]?.childrenKeys?.push(categoryItemKey)
previousValue = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { generateOtherFilesList } from "./other-files-list"

export const generateMcFileManagerView: ComponentGenerator<
McFileManagerView
> = (key) => {
> = (key, config) => {
return {
[key]: {
component: "block-plain",
Expand All @@ -34,7 +34,9 @@ export const generateMcFileManagerView: ComponentGenerator<
formOptions: {
defaultValues: {
activeFileCategoryId: "0",
fileCategoryIds: ["0", "1", "2", "3"],
fileCategoryIds: config.entityTypes.map((_, index) =>
index.toString()
),
},
},
},
Expand All @@ -43,12 +45,7 @@ export const generateMcFileManagerView: ComponentGenerator<
fileManagerLoader: {
component: "entities-loader",
config: {
entitiesTypes: [
"audioFiles",
"imageFiles",
"ebookFiles",
"applicationFiles",
],
entityTypes: config.entityTypes,
text: "Loading, please wait...",
},
layout: {
Expand Down Expand Up @@ -86,38 +83,7 @@ export const generateMcFileManagerView: ComponentGenerator<
},
childrenKeys: ["fileCategoryList", "fileCategoryOtherFilesItem"],
},
...generateFileCategoryList({
configs: [
{
id: "0",
name: "Music",
icon: IconType.MusicNote,
markerColor: "#E38577",
entitiesType: "audioFiles",
},
{
id: "1",
name: "Photos",
icon: IconType.PhotoCatalog,
markerColor: "#0E7490",
entitiesType: "imageFiles",
},
{
id: "2",
name: "Ebooks",
icon: IconType.Book,
markerColor: "#A8DADC",
entitiesType: "ebookFiles",
},
{
id: "3",
name: "Apps",
icon: IconType.Grid,
markerColor: "#AEBEC9",
entitiesType: "applicationFiles",
},
],
}),
...generateFileCategoryList(config.entityTypes),
fileCategoryOtherFilesItem: {
component: "block-plain",
layout: {
Expand Down Expand Up @@ -209,29 +175,6 @@ export const generateMcFileManagerView: ComponentGenerator<
{ id: "1", name: "Other" },
],
}),
...generateFileListWrapper({
configs: [
{
id: "0",
name: "Music",
entitiesType: "audioFiles",
},
{
id: "1",
name: "Photos",
entitiesType: "imageFiles",
},
{
id: "2",
name: "Ebooks",
entitiesType: "ebookFiles",
},
{
id: "3",
name: "Apps",
entitiesType: "applicationFiles",
},
],
}),
...generateFileListWrapper(config.entityTypes),
}
}
3 changes: 1 addition & 2 deletions libs/generic-view/ui/src/lib/table/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import styled from "styled-components"
import { difference, intersection } from "lodash"
import { APIFC, useViewFormContext } from "generic-view/utils"
import {
tableCell,
TableConfig,
TableData,
tableHeaderCell,
Expand Down Expand Up @@ -155,7 +154,7 @@ export const Table: APIFC<TableData, TableConfig> & {
const filteredChildren = React.Children.toArray(children).map((child) => {
if (
!React.isValidElement(child) ||
child.props.componentName !== tableCell.key
child.props.componentName === tableHeaderCell.key
) {
return null
}
Expand Down