[ABANDONED] React/Redux front end for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

162 lines
4.4 KiB

import {
EntityType,
EntityStore,
Entity,
User,
Invitation,
GroupLog,
App,
} from '../types'
import compact from 'lodash/compact'
export interface NormalizeResult {
keys: string[]
entities: EntityStore
}
type NormalizedInstallation = Entity & {
app: string
}
type NormalizedUser = Entity & {
installations: NormalizedInstallation[]
}
function set(type: EntityType, store: EntityStore, entity?: Entity): string | undefined {
if (!entity) return
const collection = store[type] || {}
const existing = collection[entity.id] || {}
collection[entity.id] = {
...existing,
...entity,
}
store[type] = collection
return entity.id
}
function get(type: EntityType, store: EntityStore, id?: string): Entity | undefined {
if (!id) return
const collection = store[type] || {}
return collection[id]
}
export function normalize(entities: Entity[], type: EntityType): NormalizeResult {
let keys: Array<string | undefined> = []
const newStore: EntityStore = {}
switch (type) {
case EntityType.User:
keys = entities.map(entity => {
const user = entity as User
const { installations = [] } = user
return set(type, newStore, {
...user,
group: set(EntityType.Group, newStore, user.group),
installations: installations.map(installation => {
return {
...installation,
app: set(EntityType.App, newStore, installation.app),
}
})
})
})
break
case EntityType.Group:
keys = entities.map(entity => set(type, newStore, entity))
break
case EntityType.Invitation:
keys = entities.map(entity => {
const invitation = entity as Invitation
return set(type, newStore, {
...invitation,
user: set(EntityType.User, newStore, invitation.user),
})
})
break
case EntityType.Log:
keys = entities.map(entity => {
const log = entity as GroupLog
return set(type, newStore, {
...log,
user: set(EntityType.User, newStore, log.user),
})
})
break
case EntityType.App:
keys = entities.map(entity => {
const app = entity as App
return set(type, newStore, {
...app,
user: set(EntityType.User, newStore, app.user)
})
})
break
}
return {
keys: compact(keys),
entities: newStore,
}
}
export function denormalize(keys: string[], type: EntityType, store: EntityStore): Entity[] {
const entities = keys.map(key => {
switch (type) {
case EntityType.User:
const user = get(type, store, key) as NormalizedUser
if (!user) return
return {
...user,
group: get(EntityType.Group, store, user.group),
installations: user.installations.map(installation => {
return {
...installation,
app: get(EntityType.App, store, installation.app),
}
})
}
case EntityType.Group:
return get(type, store, key)
case EntityType.Invitation:
const invitation = get(type, store, key)
if (!invitation) return
return {
...invitation,
user: get(EntityType.User, store, invitation.user),
}
case EntityType.Log:
const log = get(type, store, key)
if (!log) return
return {
...log,
user: get(EntityType.User, store, log.user),
}
case EntityType.App:
const app = get(type, store, key)
if (!app) return
return {
...app,
user: get(EntityType.User, store, app.user),
}
}
})
return compact(entities)
}