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

feat: add profile labels to machine profile type #3904

Merged
merged 7 commits into from
Oct 23, 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
2 changes: 1 addition & 1 deletion functions/src/userUpdates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { backupUser } from './backupUser'
import { updateDiscussionComments } from './updateDiscussionComments'
import { updateMapPins } from './updateMapPins'

import type { IUserDB } from 'oa-shared/models/user'
import type { IDBDocChange } from '../models'
import { IUserDB } from 'oa-shared/models/user'

/*********************************************************************
* Side-effects to be carried out on various user updates, namely:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IUserDB } from 'oa-shared/models/user'
import { updateDiscussionComments } from './updateDiscussionComments'

import type { IUserDB } from 'oa-shared/models/user'

const prevUser = {
_id: 'hjg235z',
location: { countryCode: 'UK' },
Expand Down
9 changes: 6 additions & 3 deletions functions/src/userUpdates/updateMapPins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { db } from '../Firebase/firestoreDB'
import {
getCreatorImage,
getFirstCoverImage,
getValidTags,
hasDetailsForMapPinChanged,
} from './utils'

Expand Down Expand Up @@ -32,14 +33,15 @@ export const updateMapPins = async (prevUser: IUserDB, user: IUserDB) => {
coverImages,
displayName,
isContactableByPublic,
location,
profileType,
workspaceType,
userImage,
location,
workspaceType,
} = user
const creatorImage = getCreatorImage(userImage)
const coverImage = getFirstCoverImage(coverImages)
const countryCode = location?.countryCode || country || ''
const tags = user.tags ? getValidTags(user.tags) : []

const creator = {
_lastActive,
Expand All @@ -50,8 +52,9 @@ export const updateMapPins = async (prevUser: IUserDB, user: IUserDB) => {
displayName,
isContactableByPublic,
profileType,
workspaceType,
tags,
userImage: creatorImage,
workspaceType,
}

// Only one expected
Expand Down
104 changes: 100 additions & 4 deletions functions/src/userUpdates/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,86 @@ import {
hasDetailsForMapPinChanged,
hasLocationDetailsChanged,
hasUserImageChanged,
hasUserTagsChanged,
} from './utils'

import type { IUploadedFileMeta } from 'oa-shared'
import type { IUserDB } from 'oa-shared/models/user'

const unimportantUserDetails = {
_authID: '00',
_id: 'unchangeable',
_created: '',
_deleted: false,
userName: 'unchangeable',
verified: false,
coverImages: [],
links: [],
}

describe('hasDetailsChanged', () => {
it("returns false for every field that's the same", () => {
const user = {
_lastActive: 'same',
about: 'about',
displayName: 'same',
isContactableByPublic: true,
profileType: 'member',
userImage: {
downloadUrl: 'https://more.same/image.jpg',
},
} as IUploadedFileMeta,
badges: {
verified: true,
supporter: false,
},
tags: {
hguowewer: true,
'76khbrw': false,
},
...unimportantUserDetails,
} as IUserDB

expect(hasDetailsChanged(user, user)).toEqual([false, false, false, false])
})

it("returns true for every field that's different", () => {
const prevUser = {
_lastActive: 'yesterday',
about: 'Old about',
displayName: 'old',
profileType: 'member',
workspaceType: null,
userImage: {
downloadUrl: 'https://more.old/image.jpg',
},
} as IUploadedFileMeta,
badges: {
verified: true,
supporter: true,
},
tags: {
hguowewer: true,
},
...unimportantUserDetails,
} as IUserDB

const user = {
_lastActive: 'today',
about: 'New about description.',
displayName: 'new',
profileType: 'space',
workspaceType: 'extrusion',
userImage: {
downloadUrl: 'https://more.new/image.jpg',
},
} as IUploadedFileMeta,
badges: {
verified: false,
supporter: false,
},
tags: {
hguowewer: true,
'76khbrw': true,
},
...unimportantUserDetails,
} as IUserDB

expect(hasDetailsChanged(prevUser, user)).toEqual([true, true, true, true])
Expand Down Expand Up @@ -99,7 +138,6 @@ describe('hasDetailsForCommentsChanged', () => {
userImage: {
downloadUrl: 'http://etc.',
},

badges: {
verified: true,
supporter: false,
Expand Down Expand Up @@ -196,3 +234,61 @@ describe('hasUserImageChanged', () => {
expect(hasUserImageChanged(prevUser, user)).toEqual(true)
})
})

describe('hasUserTagsChanged', () => {
it('returns false when nothing has changed', () => {
const user = {
displayName: 'displayName',
profileType: 'member',
tags: {
gyi: false,
bnhjo: true,
},
...unimportantUserDetails,
} as IUserDB
expect(hasUserTagsChanged(user, user)).toEqual(false)
})

it('returns true when a tag is added', () => {
const prevUser = {
displayName: 'displayName',
profileType: 'member',
tags: {
gyi: false,
},
...unimportantUserDetails,
} as IUserDB

const user = {
displayName: 'displayName',
profileType: 'member',
tags: {
gyi: false,
bnhjo: true,
},
...unimportantUserDetails,
} as IUserDB
expect(hasUserTagsChanged(prevUser, user)).toEqual(true)
})

it('returns true when a tag is changed', () => {
const prevUser = {
displayName: 'displayName',
profileType: 'member',
tags: {
gyi: false,
},
...unimportantUserDetails,
} as IUserDB

const user = {
displayName: 'displayName',
profileType: 'member',
tags: {
gyi: true,
},
...unimportantUserDetails,
} as IUserDB
expect(hasUserTagsChanged(prevUser, user)).toEqual(true)
})
})
23 changes: 22 additions & 1 deletion functions/src/userUpdates/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { profileTags } from 'oa-shared'

import { valuesAreDeepEqual } from '../Utils'

import type { IUserDB } from 'oa-shared/models/user'
import type { ISelectedTags, ITag, IUserDB } from 'oa-shared'

export const hasDetailsChanged = (
prevUser: IUserDB,
Expand Down Expand Up @@ -46,6 +48,7 @@ export const hasDetailsForMapPinChanged = (
prevUser.isContactableByPublic !== user.isContactableByPublic,
prevUser.profileType !== user.profileType,
prevUser.workspaceType !== user.workspaceType,
hasUserTagsChanged(prevUser, user),
...hasDetailsChanged(prevUser, user),
...hasLocationDetailsChanged(prevUser, user),
]
Expand All @@ -66,10 +69,28 @@ export const hasUserImageChanged = (
if (!prevUser.userImage && user.userImage) return true
}

export const hasUserTagsChanged = (
prevUser: IUserDB,
user: IUserDB,
): boolean => {
return !valuesAreDeepEqual(prevUser.tags, user.tags)
}

export const getCreatorImage = (userImage: IUserDB['userImage']) => {
return userImage?.downloadUrl || null
}

export const getFirstCoverImage = (coverImages: IUserDB['coverImages']) => {
return coverImages?.[0]?.downloadUrl || null
}

// For ease, duplicated from src/utils/getValidTags.ts
export const getValidTags = (tagIds: ISelectedTags) => {
const selectedTagIds = Object.keys(tagIds).filter((id) => tagIds[id] === true)
const tags: ITag[] = selectedTagIds
.map((id) => profileTags.find(({ _id }) => id === _id))
.filter((tag): tag is ITag => !!tag)
.filter(({ _deleted }) => _deleted !== true)

return tags
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"main": "lib/index.js",
"type": "module",
"scripts": {
"start": "concurrently --kill-others --names themes,components,platform --prefix-colors cyan,blue,magenta \"yarn start:shared\" \"yarn start:themes\" \"yarn start:components\" \"yarn start:platform\"",
"start-ci": "concurrently --kill-others --names themes,components,platform --prefix-colors cyan,blue,magenta \"yarn start:themes\" \"yarn start:components\" \"yarn start:platform-ci\"",
"start": "concurrently --kill-others --names shared,themes,components,platform --prefix-colors cyan,blue,magenta \"yarn start:shared\" \"yarn start:themes\" \"yarn start:components\" \"yarn start:platform\"",
"start-ci": "concurrently --kill-others --names shared,themes,components,platform --prefix-colors cyan,blue,magenta \"yarn start:themes\" \"yarn start:components\" \"yarn start:platform-ci\"",
"start:themes": "yarn workspace oa-themes dev",
"start:components": "yarn workspace oa-components dev",
"start:shared": "yarn workspace oa-shared dev",
Expand All @@ -38,7 +38,7 @@
"format:style": "prettier --write '**/*.{json,js,tsx,ts}'",
"serve": "npx serve -s build",
"test": "yarn workspace oa-cypress start",
"test:components": "yarn workspace oa-components test",
"test:components": "yarn build:themes && yarn build:components && yarn workspace oa-components test",
"test:unit": "yarn build:themes && yarn build:components && vitest",
"test:madge": "npx madge --circular --extensions ts,tsx ./ --exclude src/stores",
"storybook": "yarn workspace oa-components start",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import '@testing-library/jest-dom/vitest'

import { describe, expect, it } from 'vitest'

import { render } from '../test/utils'
import { Default } from './{{ComponentName}}.stories'
import type { IProps } from './{{ComponentName}}'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Box, Flex, Image, Text } from 'theme-ui'

import { Category } from '../Category/Category'
import { MemberBadge } from '../MemberBadge/MemberBadge'
import { ProfileTagsList } from '../ProfileTagsList/ProfileTagsList'
import { Username } from '../Username/Username'

import type { IProfileCreator } from 'oa-shared'
Expand All @@ -19,6 +20,7 @@ export const CardDetailsSpaceProfile = ({ creator, isLink }: IProps) => {
countryCode,
coverImage,
profileType,
tags,
workspaceType,
} = creator

Expand Down Expand Up @@ -82,7 +84,8 @@ export const CardDetailsSpaceProfile = ({ creator, isLink }: IProps) => {
isLink={isLink}
/>
</Flex>
{workspaceType && (

{workspaceType && profileType === 'workspace' && (
<Category
category={{ label: workspaceLabel }}
sx={{
Expand All @@ -92,6 +95,9 @@ export const CardDetailsSpaceProfile = ({ creator, isLink }: IProps) => {
}}
/>
)}

{tags && <ProfileTagsList tags={tags} />}

{about && (
<Text variant="quiet" sx={{ fontSize: 2 }}>
{aboutTextStart || about}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ProfileTagsList } from './ProfileTagsList'

import type { Meta, StoryFn } from '@storybook/react'

export default {
title: 'Components/ProfileTagsList',
component: ProfileTagsList,
} as Meta<typeof ProfileTagsList>

export const Default: StoryFn<typeof ProfileTagsList> = () => (
<ProfileTagsList
tags={[
{
_id: 'hwh',
_created: 'today',
_deleted: false,
label: 'Electronics',
},
{
_id: 'a45397uh',
_created: 'yesterday',
_deleted: false,
label: 'Electronics II',
},
]}
/>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import '@testing-library/jest-dom/vitest'

import { describe, expect, it } from 'vitest'

import { render } from '../test/utils'
import { Default } from './ProfileTagsList.stories'

import type { IProps } from './ProfileTagsList'

describe('ProfileTagsList', () => {
it('validates the component behaviour', () => {
const { getByText } = render(<Default {...(Default.args as IProps)} />)

expect(getByText('Electronics')).toBeInTheDocument()
})
})
22 changes: 22 additions & 0 deletions packages/components/src/ProfileTagsList/ProfileTagsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Flex } from 'theme-ui'

import { Category } from '../Category/Category'

import type { ITag } from 'oa-shared'

export interface IProps {
tags: ITag[]
}

export const ProfileTagsList = ({ tags }: IProps) => {
return (
<Flex sx={{ gap: 2, flexWrap: 'wrap' }}>
{tags.map(
(tag, index) =>
tag?.label && (
<Category key={index} category={{ label: tag.label }} />
),
)}
</Flex>
)
}
Loading
Loading