diff --git a/CHANGELOG.md b/CHANGELOG.md index d49a780454..fb2db380ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.3.0] - 2023-02-17 + +### Added +- Member handles when hovering candidacies. +- Allow full UTF-8 proposal titles. +- `decode` helper command for development. + +### Changed +- Open markdown links in a new tab. +- WG openings list items and selector options. +- Description of the update WG budget proposal. +- Rename proposal "Constants" to "Parameters". + +### Removed +- The virtual member role. + +### Fixed +- Invite member modal. +- New posts preview modal. +- Status of rejected and canceled application. +- Block explorer icon look. +- Do not truncate forum category descriptions. +- Latest threads reply count. +- Typos. + ## [1.2.0] - 2023-02-09 ### Added @@ -51,7 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Blockheight info labels (in the settings). - Replaced/Removed some more lorem ipsum. - Better prevent localstorage overwrites from the forum tread watchlist. -- The hire limit on single postion openings. +- The hire limit on single position openings. - The temporary "Insufficient balance to cover fee" message on the vesting claim modal. ## [1.0.1] - 2023-01-05 @@ -63,7 +88,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Mainnet network in the setting. -- Documentation link to the [Joystrem Handbook](https://joystream.gitbook.io/testnet-workspace) for each working group. +- Documentation link to the [Joystream Handbook](https://joystream.gitbook.io/testnet-workspace) for each working group. - Refresh auto-conf network button. - RPC blockheight and latest processed block in settings. @@ -81,9 +106,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Testnet banner. ### Fixed -- Large election relealing stage (long term fix). +- Large election revealing stage (long term fix). - Recovering the stake locked when applying to an opening. -- Some broken [Joystrem Handbook](https://joystream.gitbook.io/testnet-workspace) links. +- Some broken [Joystream Handbook](https://joystream.gitbook.io/testnet-workspace) links. - Replace placeholder text on vesting tooltips. - Broken text on the insufficient funds modal. - Proposal discussion order. @@ -92,7 +117,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.1.1] - 2022-12-02 -[unreleased]: https://github.com/Joystream/pioneer/compare/v1.2.0...HEAD +[unreleased]: https://github.com/Joystream/pioneer/compare/v1.3.0...HEAD +[1.3.0]: https://github.com/Joystream/pioneer/compare/v1.2.0...v1.3.0 [1.2.0]: https://github.com/Joystream/pioneer/compare/v1.1.1...v1.2.0 [1.1.1]: https://github.com/Joystream/pioneer/compare/v1.1.0...v1.1.1 [1.1.0]: https://github.com/Joystream/pioneer/compare/v1.0.1...v1.1.0 diff --git a/docs/mocks.md b/docs/mocks.md index 99919414d5..b9403f396b 100644 --- a/docs/mocks.md +++ b/docs/mocks.md @@ -55,6 +55,41 @@ Another way to influence the on-chain state for testing purpose, is to provide a --tmp --alice --validator --unsafe-ws-external --unsafe-rpc-external --rpc-cors=all --chain packages/ui/dev/chain-spec/data/chain-spec.json --log runtime ``` ### Other helper commands + +#### Decoding data from the chain: + +```shell +> yarn workspace @joystream/pioneer run helpers decode -t [TYPE] -v [VALUE] +``` + +This command requires two arguments: +- `-t`, `--type`: The expected type of the value to decode. It can be `text`, or the name or alias of a [metadata class](https://github.com/Joystream/joystream/blob/master/metadata-protobuf/doc/index.md). +- `-v`, `--value`: The hash or the string representation of the `Uint8Array` to decode. + +With `-t text` this command will simply decode encoded plaint text values. E.g: +```shell +> yarn workspace @joystream/pioneer run helpers decode -t text -v 0x4c6f72656d20697370756d +Lorem ispum +``` + +Otherwhise the type options should refer to a [metadata class](https://github.com/Joystream/joystream/blob/master/metadata-protobuf/doc/index.md). It can be the name of the class: +```shell +> yarn workspace @joystream/pioneer run helpers decode -t CouncilCandidacyNoteMetadata -v 0x0a0a616... +CouncilCandidacyNoteMetadata { + ... +} +``` + +Or it can be an alias: +```shell +> yarn workspace @joystream/pioneer run helpers decode -t candidacy -v 0x0a0a616... +CouncilCandidacyNoteMetadata { + ... +} +``` +The available aliases are: `post`, `opening`, `thread`, `bounty`, `candidacy`, `candidate`, `application`, `member`, and `membership`. + +#### Others - `yarn workspace @joystream/pioneer run helpers commitment -s [-a ] [-o ] [-c ]` - Calculate a commitment - `yarn workspace @joystream/pioneer run helpers nextCouncilStage` - Wait until the next council stage start diff --git a/packages/ui/dev/helpers/decode.ts b/packages/ui/dev/helpers/decode.ts new file mode 100644 index 0000000000..69dbee4b8c --- /dev/null +++ b/packages/ui/dev/helpers/decode.ts @@ -0,0 +1,47 @@ +import * as MetaClasses from '@joystream/metadata-protobuf' +import { AnyMetadataClass } from '@joystream/metadata-protobuf/types' +import { createType } from '@joystream/types' +import chalk from 'chalk' +import yargs from 'yargs' + +import { metadataFromBytes } from '../../src/common/model/JoystreamNode' + +const MetaClassAliases = { + post: 'ForumPostMetadata', + opening: 'OpeningMetadata', + thread: 'ForumThreadMetadata', + bounty: 'BountyMetadata', + candidacy: 'CouncilCandidacyNoteMetadata', + candidate: 'CouncilCandidacyNoteMetadata', + application: 'ApplicationMetadata', + member: 'MembershipMetadata', + membership: 'MembershipMetadata', +} as Record + +const options = { + type: { type: 'string', alias: 't', example: ['text', 'post', 'ForumPostMetadata'], default: 'text' }, + value: { type: 'string', alias: 'v', demand: true }, +} as const + +type CommandOptions = yargs.InferredOptionTypes +type Args = yargs.Arguments + +const decode = (type: string, value: string): string => { + if (type === 'text') { + return createType('Text', value).toHuman() + } else { + const metaType = (MetaClassAliases[type as any] ?? type) as keyof typeof MetaClasses + const metadata = metadataFromBytes(MetaClasses[metaType] as AnyMetadataClass, value) + return `${metaType} ${JSON.stringify(metadata, null, 2)}` + } +} +const handler = ({ type, value }: Args) => { + process.stdout.write(chalk.green(decode(type, value)) + '\n') +} + +export const decodeModule = { + command: 'decode', + describe: 'Decode chain data', + handler, + builder: (argv: yargs.Argv) => argv.options(options), +} diff --git a/packages/ui/dev/helpers/index.ts b/packages/ui/dev/helpers/index.ts index 9b483ea63d..2bd83fca0a 100644 --- a/packages/ui/dev/helpers/index.ts +++ b/packages/ui/dev/helpers/index.ts @@ -3,6 +3,7 @@ import yargs from 'yargs' import { apiBenchmarking } from './apiBenchmarking' import { setChainSpecModule } from './chain-spec' import { commitmentModule } from './commitment' +import { decodeModule } from './decode' import { nextCouncilStageModule } from './nextCouncilStage' yargs(process.argv.slice(2)) @@ -11,5 +12,6 @@ yargs(process.argv.slice(2)) .command(apiBenchmarking) .command(setChainSpecModule) .command(commitmentModule) + .command(decodeModule) .command(nextCouncilStageModule) .demandCommand().argv diff --git a/packages/ui/src/accounts/components/StakeStep.tsx b/packages/ui/src/accounts/components/StakeStep.tsx index d055af7b23..3d4c00b541 100644 --- a/packages/ui/src/accounts/components/StakeStep.tsx +++ b/packages/ui/src/accounts/components/StakeStep.tsx @@ -49,8 +49,8 @@ export const StakeStep = ({ label="Select account for Staking" required inputSize="l" - tooltipText="If someone voted for a candidate in an election, they will and can recover their stake at a later time.\n\nImportantly, a vote which was devoted to a losing candidate can be freed the moment the election cycle is over, while a vote which was devoted to a winner can only be freed after the announcing period of the next election begins. The idea behind this asymmetry is to more closely expose the winners to the consequences of their decision." - tooltipLinkURL="https://joystream.gitbook.io/testnet-workspace/system/council" + tooltipText="If someone voted for a candidate in an election, they will and can recover their stake at a later time. Importantly, a vote which was devoted to a losing candidate can be freed the moment the election cycle is over, while a vote which was devoted to a winner can only be freed after the announcing period of the next election begins. The idea behind this asymmetry is to more closely expose the winners to the consequences of their decision." + tooltipLinkURL="https://handbook.joystream.org/system/council" > | ModalName | ModalName + | ModalName const modals: Record = { Member: , @@ -149,6 +152,7 @@ const modals: Record = { RevealVote: , RecoverBalance: , IncreaseWorkerStake: , + InviteMemberModal: , OnBoardingModal: , RestoreVotes: , // AddBounty: , diff --git a/packages/ui/src/app/components/SideBar.tsx b/packages/ui/src/app/components/SideBar.tsx index cc2fcbee48..e2950237b6 100644 --- a/packages/ui/src/app/components/SideBar.tsx +++ b/packages/ui/src/app/components/SideBar.tsx @@ -106,7 +106,7 @@ export const SideBar = () => { to={`https://polkadot.js.org/apps/?rpc=${endpoints.nodeRpcEndpoint}#/explorer`} > Explorer - + @@ -197,4 +197,7 @@ const NavigationLinksItem = styled.li` display: flex; height: fit-content; width: 100%; + .sidebarLinkSymbol { + grid-column: 6 !important; + } ` diff --git a/packages/ui/src/app/pages/Forum/ForumCategory.tsx b/packages/ui/src/app/pages/Forum/ForumCategory.tsx index e52c4fa683..29e537c290 100644 --- a/packages/ui/src/app/pages/Forum/ForumCategory.tsx +++ b/packages/ui/src/app/pages/Forum/ForumCategory.tsx @@ -74,7 +74,7 @@ export const ForumCategory = () => { } description={ - + {category.description} } diff --git a/packages/ui/src/common/components/MarkdownPreview/MarkdownPreview.tsx b/packages/ui/src/common/components/MarkdownPreview/MarkdownPreview.tsx index 7d9daa3f09..00e5a3cb5f 100644 --- a/packages/ui/src/common/components/MarkdownPreview/MarkdownPreview.tsx +++ b/packages/ui/src/common/components/MarkdownPreview/MarkdownPreview.tsx @@ -59,7 +59,7 @@ export const MarkdownPreview = ({ markdown, append, ...styleProps }: MarkdownPre {children} ) : ( - + {children} ) diff --git a/packages/ui/src/common/components/Modal/Modal.tsx b/packages/ui/src/common/components/Modal/Modal.tsx index 7a340191cf..731d068bc8 100644 --- a/packages/ui/src/common/components/Modal/Modal.tsx +++ b/packages/ui/src/common/components/Modal/Modal.tsx @@ -281,6 +281,7 @@ export const ScrolledModal = styled(Modal)` &${ModalWrap} { max-height: calc(100% - 128px); grid-template-rows: auto 1fr auto; + position: fixed; } ` diff --git a/packages/ui/src/common/components/icons/symbols/LinkSymbol.tsx b/packages/ui/src/common/components/icons/symbols/LinkSymbol.tsx index 8180ed14e2..4680cc158d 100644 --- a/packages/ui/src/common/components/icons/symbols/LinkSymbol.tsx +++ b/packages/ui/src/common/components/icons/symbols/LinkSymbol.tsx @@ -8,22 +8,34 @@ import { SymbolProps } from './common' export function LinkSymbol({ className, color }: SymbolProps) { return ( - - + {className == 'sidebarLinkSymbol' ? ( + + ) : ( + <> + + + + )} ) } diff --git a/packages/ui/src/common/components/page/Sidebar/NavigationLink.tsx b/packages/ui/src/common/components/page/Sidebar/NavigationLink.tsx index 4841d65911..78047df080 100644 --- a/packages/ui/src/common/components/page/Sidebar/NavigationLink.tsx +++ b/packages/ui/src/common/components/page/Sidebar/NavigationLink.tsx @@ -119,7 +119,21 @@ const NavigationItemLinkChildren = styled.div` ${Overflow.FullDots}; svg { - width: 20px; + width: 16px; + height: 16px; + + path { + fill: ${Colors.Black[400]}!important; + transition: ${Transitions.all}; + } + } + + &:hover { + svg { + path { + fill: ${Colors.White}!important; + } + } } ` diff --git a/packages/ui/src/common/components/selects/components.tsx b/packages/ui/src/common/components/selects/components.tsx index 558e60c487..a5770e3f98 100644 --- a/packages/ui/src/common/components/selects/components.tsx +++ b/packages/ui/src/common/components/selects/components.tsx @@ -22,11 +22,14 @@ interface Props { children: ReactNode onClick: () => void disabled?: boolean + className?: string } -export const Option = ({ children, onClick, disabled }: Props) => ( +export const Option = ({ children, onClick, disabled, className }: Props) => ( - {children} + + {children} + ) diff --git a/packages/ui/src/common/model/JoystreamNode/index.ts b/packages/ui/src/common/model/JoystreamNode/index.ts index aa57af6e6a..ee6c86e272 100644 --- a/packages/ui/src/common/model/JoystreamNode/index.ts +++ b/packages/ui/src/common/model/JoystreamNode/index.ts @@ -1,5 +1,6 @@ export * from './errorEvents' export * from './getDataFromEvent' export * from './isModuleEvent' +export * from './metadataFromBytes' export * from './metadataToBytes' export * from './types' diff --git a/packages/ui/src/common/model/JoystreamNode/metadataFromBytes.ts b/packages/ui/src/common/model/JoystreamNode/metadataFromBytes.ts index 4e150d2833..f3d1945360 100644 --- a/packages/ui/src/common/model/JoystreamNode/metadataFromBytes.ts +++ b/packages/ui/src/common/model/JoystreamNode/metadataFromBytes.ts @@ -1,9 +1,8 @@ import { AnyMessage, AnyMetadataClass, DecodedMetadataObject } from '@joystream/metadata-protobuf/types' +import { createType } from '@joystream/types' import { Bytes } from '@polkadot/types/primitive' import { isObject } from '@polkadot/util' -import { createType } from '@/common/model/createType' - function metaToObject(metaClass: AnyMetadataClass, value: AnyMessage) { return metaClass.toObject(value, { arrays: false, longs: String }) as DecodedMetadataObject } diff --git a/packages/ui/src/council/components/election/CandidateCard/CandidateCard.tsx b/packages/ui/src/council/components/election/CandidateCard/CandidateCard.tsx index 0418aab3ef..6dce1fbc01 100644 --- a/packages/ui/src/council/components/election/CandidateCard/CandidateCard.tsx +++ b/packages/ui/src/council/components/election/CandidateCard/CandidateCard.tsx @@ -56,7 +56,7 @@ export const CandidateCard = ({ - + diff --git a/packages/ui/src/forum/components/ThreadCard/ThreadCard.tsx b/packages/ui/src/forum/components/ThreadCard/ThreadCard.tsx index 44f5533c70..915a6324d8 100644 --- a/packages/ui/src/forum/components/ThreadCard/ThreadCard.tsx +++ b/packages/ui/src/forum/components/ThreadCard/ThreadCard.tsx @@ -22,6 +22,7 @@ interface ThreadCardProps { } export const ThreadCard = ({ thread, className, watchlistButton }: ThreadCardProps) => { + const replies = thread.visiblePostsCount - 1 return ( - - - - + {replies > 0 && ( + + + + + )} {watchlistButton && } diff --git a/packages/ui/src/memberships/components/InviteMemberButton.tsx b/packages/ui/src/memberships/components/InviteMemberButton.tsx index b1c564e5bd..36619230a7 100644 --- a/packages/ui/src/memberships/components/InviteMemberButton.tsx +++ b/packages/ui/src/memberships/components/InviteMemberButton.tsx @@ -1,11 +1,10 @@ import React, { ReactNode } from 'react' import { TransactionButton } from '@/common/components/buttons/TransactionButton' +import { useModal } from '@/common/hooks/useModal' import { useTransactionStatus } from '@/common/hooks/useTransactionStatus' import { ButtonSize } from '../../common/components/buttons' -import { useToggle } from '../../common/hooks/useToggle' -import { InviteMemberModal } from '../modals/InviteMemberModal' interface InviteMemberButtonProps { className?: string @@ -14,21 +13,22 @@ interface InviteMemberButtonProps { } export const InviteMemberButton = ({ className, children, size }: InviteMemberButtonProps) => { - const [isOpen, toggleIsOpen] = useToggle() + const { showModal } = useModal() const { isTransactionPending } = useTransactionStatus() + const openModal = () => showModal({ modal: 'InviteMemberModal' }) + return ( <> {children} - {isOpen && } ) } diff --git a/packages/ui/src/memberships/components/MemberRoles.tsx b/packages/ui/src/memberships/components/MemberRoles.tsx index 21666fae97..d1c0064076 100644 --- a/packages/ui/src/memberships/components/MemberRoles.tsx +++ b/packages/ui/src/memberships/components/MemberRoles.tsx @@ -26,12 +26,6 @@ export interface MemberRolesProps { wrapable?: boolean } -const defaultRole = { - id: '0', - groupName: 'Member Role', - isLead: false, -} - export const rolesToMap = (roles: MemberRole[]): Map => { const mapRoles = new Map() for (const role of roles) { @@ -51,7 +45,7 @@ export const rolesToMap = (roles: MemberRole[]): Map => { export const MemberRoles = ({ size, max, wrapable, roles }: MemberRolesProps) => { if (!roles || !roles.length) { - roles = [defaultRole] + roles = [] } const mapRoles = rolesToMap(roles) const rolesWithCount = [...mapRoles.entries()] diff --git a/packages/ui/src/memberships/modals/InviteMemberModal/InviteMemberModal.tsx b/packages/ui/src/memberships/modals/InviteMemberModal/InviteMemberModal.tsx index 754e709e03..2efa684e9a 100644 --- a/packages/ui/src/memberships/modals/InviteMemberModal/InviteMemberModal.tsx +++ b/packages/ui/src/memberships/modals/InviteMemberModal/InviteMemberModal.tsx @@ -4,6 +4,7 @@ import { useApi } from '@/api/hooks/useApi' import { TextMedium } from '@/common/components/typography' import { useFirstObservableValue } from '@/common/hooks/useFirstObservableValue' import { useMachine } from '@/common/hooks/useMachine' +import { useModal } from '@/common/hooks/useModal' import { SignTransactionModal } from '@/common/modals/SignTransactionModal/SignTransactionModal' import { Address } from '@/common/types' import { toMemberTransactionParams } from '@/memberships/modals/utils' @@ -13,12 +14,9 @@ import { InviteMemberRequirementsModal } from './InviteMemberRequirementsModal' import { InviteMemberSuccessModal } from './InviteMemberSuccessModal' import { inviteMemberMachine } from './machine' -interface MembershipModalProps { - onClose: () => void -} - -export function InviteMemberModal({ onClose }: MembershipModalProps) { +export function InviteMemberModal() { const { api } = useApi() + const { hideModal } = useModal() const workingGroupBudget = useFirstObservableValue( () => api?.query.membershipWorkingGroup.budget(), [api?.isConnected] @@ -34,11 +32,11 @@ export function InviteMemberModal({ onClose }: MembershipModalProps) { }, [workingGroupBudget, membershipPrice]) if (state.matches('requirementsFailed')) { - return + return } if (state.matches('prepare')) { - return send({ type: 'DONE', form: params })} /> + return send({ type: 'DONE', form: params })} /> } if (state.matches('transaction') && api) { @@ -60,7 +58,7 @@ export function InviteMemberModal({ onClose }: MembershipModalProps) { } if (state.matches('success')) { - return + return } return null diff --git a/packages/ui/src/memberships/modals/InviteMemberModal/types.ts b/packages/ui/src/memberships/modals/InviteMemberModal/types.ts new file mode 100644 index 0000000000..b207c59f04 --- /dev/null +++ b/packages/ui/src/memberships/modals/InviteMemberModal/types.ts @@ -0,0 +1,3 @@ +import { ModalCall } from '../../../common/providers/modal/types' + +export type InviteMemberModalCall = ModalCall<'InviteMemberModal'> diff --git a/packages/ui/src/proposals/modals/AddNewProposal/components/ProposalConstantsWrapper.tsx b/packages/ui/src/proposals/modals/AddNewProposal/components/ProposalConstantsWrapper.tsx index 8447b9faa7..ff15993fed 100644 --- a/packages/ui/src/proposals/modals/AddNewProposal/components/ProposalConstantsWrapper.tsx +++ b/packages/ui/src/proposals/modals/AddNewProposal/components/ProposalConstantsWrapper.tsx @@ -10,7 +10,7 @@ export const ProposalConstantsWrapper = ({ constants }: { constants: ProposalCon -

Constants

+

Parameters

diff --git a/packages/ui/src/proposals/modals/AddNewProposal/helpers.ts b/packages/ui/src/proposals/modals/AddNewProposal/helpers.ts index 09639ae25b..2411b90dd7 100644 --- a/packages/ui/src/proposals/modals/AddNewProposal/helpers.ts +++ b/packages/ui/src/proposals/modals/AddNewProposal/helpers.ts @@ -154,8 +154,7 @@ export const schemaFactory = (api?: ProxyApi) => { proposalDetails: Yup.object().shape({ title: Yup.string() .required('Field is required') - .max(api?.consts.proposalsEngine.titleMaxLength.toNumber() ?? 0, 'Title exceeds maximum length') - .matches(/^[\x20-\x7E]*$/, 'Title includes forbidden characters'), + .max(api?.consts.proposalsEngine.titleMaxLength.toNumber() ?? 0, 'Title exceeds maximum length'), rationale: Yup.string() .required('Field is required') .max(api?.consts.proposalsEngine.descriptionMaxLength.toNumber() ?? 0, 'Rationale exceeds maximum length'), diff --git a/packages/ui/src/proposals/model/proposalDescriptions.ts b/packages/ui/src/proposals/model/proposalDescriptions.ts index 79d0c81f4a..daae5a41c0 100644 --- a/packages/ui/src/proposals/model/proposalDescriptions.ts +++ b/packages/ui/src/proposals/model/proposalDescriptions.ts @@ -12,7 +12,7 @@ export const proposalDescriptions: ProposalDescriptions = { createWorkingGroupLeadOpening: 'Same effect as when creating an opening for workers in the given group with given inputs, except the opening type is for lead.', fillWorkingGroupLeadOpening: 'Same effect as when filling opening in group for worker with given inputs.', - updateWorkingGroupBudget: 'Same effect as when filling opening in group for worker with given inputs.', + updateWorkingGroupBudget: 'Positive budget update gets debited from the council budget and credited to the group budget, otherwise the reverse.', decreaseWorkingGroupLeadStake: 'Same effect as when decreasing worker stake in group with given inputs.', slashWorkingGroupLead: 'Same effect as slashing worker in the group, the staking account gets slashed.', setWorkingGroupLeadReward: 'Same effect as updating the reward of the worker.', diff --git a/packages/ui/src/working-groups/components/ApplicationsList.tsx b/packages/ui/src/working-groups/components/ApplicationsList.tsx index d9f8d625c6..699f428dc9 100644 --- a/packages/ui/src/working-groups/components/ApplicationsList.tsx +++ b/packages/ui/src/working-groups/components/ApplicationsList.tsx @@ -57,8 +57,10 @@ const ApplicationListItem = ({ application, past }: { application: WorkingGroupA return 'Hired' case 'ApplicationStatusWithdrawn': return 'Withdrawn' - case 'AppplicationStatusRejected': + case 'ApplicationStatusRejected': return 'Rejected' + case 'ApplicationStatusCancelled': + return 'Cancelled' default: return 'Pending' } diff --git a/packages/ui/src/working-groups/components/OpeningsList/Opening/OpeningListItem.tsx b/packages/ui/src/working-groups/components/OpeningsList/Opening/OpeningListItem.tsx index 9c5c5d94cd..05272778f4 100644 --- a/packages/ui/src/working-groups/components/OpeningsList/Opening/OpeningListItem.tsx +++ b/packages/ui/src/working-groups/components/OpeningsList/Opening/OpeningListItem.tsx @@ -34,7 +34,7 @@ export const OpeningListItem = ({ opening, past, onClick }: OpeningListItemProps ID: {opening.runtimeId} {isInFuture(opening.expectedEnding) && ( - Ends {relativeTime(opening.expectedEnding)} + Ends in {relativeTime(opening.expectedEnding)} )} {opening.groupName} {opening.type === 'LEAD' ? LEAD : null} diff --git a/packages/ui/src/working-groups/components/SelectWorkingGroupOpening/OptionWorkingGroupOpening.tsx b/packages/ui/src/working-groups/components/SelectWorkingGroupOpening/OptionWorkingGroupOpening.tsx index a27d87883d..292d7f2d81 100644 --- a/packages/ui/src/working-groups/components/SelectWorkingGroupOpening/OptionWorkingGroupOpening.tsx +++ b/packages/ui/src/working-groups/components/SelectWorkingGroupOpening/OptionWorkingGroupOpening.tsx @@ -1,6 +1,8 @@ import React from 'react' import styled from 'styled-components' +import { BadgeStatus } from '@/common/components/BadgeStatus' +import { ColumnGapBlock } from '@/common/components/page/PageContent' import { TextSmall } from '@/common/components/typography' import { Colors, Transitions } from '@/common/constants' import { camelCaseToText } from '@/common/helpers' @@ -13,7 +15,10 @@ interface Props { export const OptionWorkingGroupOpening = ({ opening }: Props) => ( ID: {opening.id} - {camelCaseToText(opening.title)} + + {camelCaseToText(opening.title)} + {opening.type === 'LEAD' ? LEAD : null} + ) @@ -26,6 +31,7 @@ const OptionWorkingGroupWrapper = styled.div` max-height: 100%; overflow: hidden; justify-content: center; + gap: 8px; ${TextSmall} { color: ${Colors.Black[500]}; diff --git a/packages/ui/src/working-groups/components/SelectWorkingGroupOpening/OptionsListWorkingGroupOpening.tsx b/packages/ui/src/working-groups/components/SelectWorkingGroupOpening/OptionsListWorkingGroupOpening.tsx index 59efc3cabe..f389894d59 100644 --- a/packages/ui/src/working-groups/components/SelectWorkingGroupOpening/OptionsListWorkingGroupOpening.tsx +++ b/packages/ui/src/working-groups/components/SelectWorkingGroupOpening/OptionsListWorkingGroupOpening.tsx @@ -3,7 +3,10 @@ import styled from 'styled-components' import { TextMedium } from '@/common/components/typography' import { Colors } from '@/common/constants' -import { OptionWorkingGroupOpening } from '@/working-groups/components/SelectWorkingGroupOpening/OptionWorkingGroupOpening' +import { + OptionWorkingGroupOpening, + OptionWorkingGroupTitle, +} from '@/working-groups/components/SelectWorkingGroupOpening/OptionWorkingGroupOpening' import { WorkingGroupOpening } from '@/working-groups/types' import { Option, OptionsListComponent } from '../../../common/components/selects' @@ -17,9 +20,9 @@ export const OptionsListWorkingGroupOpening = React.memo(({ allOpenings, onChang {allOpenings.length ? ( allOpenings.map((option) => ( - + )) ) : (