diff --git a/packages/ui/src/app/GlobalModals.tsx b/packages/ui/src/app/GlobalModals.tsx
index f3bfdc6a4d..9f69df316e 100644
--- a/packages/ui/src/app/GlobalModals.tsx
+++ b/packages/ui/src/app/GlobalModals.tsx
@@ -209,6 +209,8 @@ const GUEST_ACCESSIBLE_MODALS: ModalNames[] = [
'EmailConfirmationModal',
'VoteRationaleModal',
'NominatingRedirect',
+ 'CreateOpening',
+ 'LeaveRole',
]
export const MODAL_WITH_CLOSE_CONFIRMATION: ModalNames[] = [
diff --git a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/AboutTab.tsx b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/AboutTab.tsx
index fecb0dad73..f91398be67 100644
--- a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/AboutTab.tsx
+++ b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/AboutTab.tsx
@@ -5,14 +5,11 @@ import { LinkSymbol } from '@/common/components/icons/symbols'
import { Loading } from '@/common/components/Loading'
import { MarkdownPreview } from '@/common/components/MarkdownPreview'
import { MainPanel, RowGapBlock } from '@/common/components/page/PageContent'
-import { SidePanel } from '@/common/components/page/SidePanel'
import { StatisticItem, Statistics, TokenValueStat } from '@/common/components/statistics'
import { NumericValueStat } from '@/common/components/statistics/NumericValueStat'
import { wgListItemMappings } from '@/common/helpers'
import { isDefined } from '@/common/utils'
-import { WorkersList } from '@/working-groups/components/WorkersList'
import { useGroupStatistics } from '@/working-groups/hooks/useGroupStatistics'
-import { useWorkers } from '@/working-groups/hooks/useWorkers'
import { WorkingGroup } from '@/working-groups/types'
import { StatusBadge, StatusGroup, StatusTitleGroup } from '../components/StatusBadges'
@@ -86,14 +83,3 @@ export const AboutTab = ({ workingGroup }: Props) => {
)
}
-
-export const AboutTabSidebar = ({ workingGroup }: Props) => {
- const { workers } = useWorkers({ groupId: workingGroup.id ?? '', status: 'active' })
- const lead = workers?.find((worker) => worker.member.id === workingGroup.leadId)
-
- return (
-
-
-
- )
-}
diff --git a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/OpeningsTab.tsx b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/OpeningsTab.tsx
index 68f1daedc2..fc9a5ecc6f 100644
--- a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/OpeningsTab.tsx
+++ b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/OpeningsTab.tsx
@@ -3,15 +3,12 @@ import styled from 'styled-components'
import { CountBadge } from '@/common/components/CountBadge'
import { MainPanel } from '@/common/components/page/PageContent'
-import { SidePanel } from '@/common/components/page/SidePanel'
import { Statistics, TokenValueStat } from '@/common/components/statistics'
import { Label } from '@/common/components/typography'
import { LoadingOpenings } from '@/working-groups/components/OpeningsList'
-import { WorkersList } from '@/working-groups/components/WorkersList'
import { useGroupDebt } from '@/working-groups/hooks/useGroupDebt'
import { useOpenings } from '@/working-groups/hooks/useOpenings'
import { useUpcomingOpenings } from '@/working-groups/hooks/useUpcomingOpenings'
-import { useWorkers } from '@/working-groups/hooks/useWorkers'
import { WorkingGroup } from '@/working-groups/types'
interface Props {
@@ -67,17 +64,6 @@ export const OpeningsTab = ({ workingGroup }: Props) => {
)
}
-export const OpeningsTabSidebar = ({ workingGroup }: Props) => {
- const { workers } = useWorkers({ groupId: workingGroup.id ?? '', status: 'active' })
- const lead = workers?.find((worker) => worker.member.id === workingGroup.leadId)
-
- return (
-
-
-
- )
-}
-
const OpeningsCategories = styled.div`
display: grid;
grid-row-gap: 24px;
diff --git a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroup.stories.tsx b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroup.stories.tsx
index 6f89572030..cde3e6f577 100644
--- a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroup.stories.tsx
+++ b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroup.stories.tsx
@@ -15,6 +15,7 @@ import {
GetGroupDebtDocument,
GetBudgetSpendingDocument,
GetPastWorkersDocument,
+ GetRoleAccountsDocument,
} from '@/working-groups/queries'
import { WorkingGroupsModule } from '../WorkingGroupsModule'
@@ -27,12 +28,12 @@ type Args = {
type Story = StoryObj>
const WG_DATA = {
- id: 'membershipWorkingGroup',
- name: 'membership',
+ id: 'operationsWorkingGroupAlpha',
+ name: 'operationsWorkingGroupAlpha',
}
const WG_OPENING_METADATA = {
- title: 'Membership worker role',
+ title: 'Builder worker role',
shortDescription: 'Lorem Ipsum...',
description: 'Bigger Lorem ipsum...',
applicationDetails: 'Application process default',
@@ -62,7 +63,7 @@ export default {
component: WorkingGroupsModule,
argTypes: {
- onCreateOpening: { action: 'MembershipWorkingGroup.OpeningCreated' },
+ onCreateOpening: { action: 'OperationsWorkingGroupAlpha.OpeningCreated' },
},
args: {
@@ -72,27 +73,40 @@ export default {
parameters: {
router: { path: '/working-groups/:name', href: `/working-groups/${WG_DATA.name}` },
mocks: ({ args, parameters }: StoryContext): MocksParameters => {
- const alice = member('alice', {
- roles: [
- {
- __typename: 'Worker',
- id: `${WG_DATA.id}-0`,
- createdAt: '2021',
- isLead: args.isLead,
- isActive: true,
- group: {
- __typename: 'WorkingGroup',
- name: WG_DATA.name,
- },
+ const alice = member('alice')
+ const charlie = member('charlie')
+
+ const role = {
+ __typename: 'Worker',
+ id: `${WG_DATA.id}-0`,
+ application: { opening: {} },
+ entry: {},
+ createdAt: '2021',
+ isLead: args.isLead,
+ isActive: true,
+ status: 'WorkerStatusActive',
+ group: { __typename: 'WorkingGroup', ...WG_DATA },
+ } as const
+
+ const workers = [
+ { ...role, membership: alice },
+ {
+ id: `${WG_DATA.id}-1`,
+ group: {
+ id: WG_DATA.id,
+ name: WG_DATA.name,
},
- ],
- })
+ status: 'WorkerStatusActive',
+ membership: charlie,
+ },
+ ]
+
return {
- accounts: { active: { member: alice } },
+ accounts: { active: { member: { ...alice, roles: [role] } } },
chain: {
tx: {
- membershipWorkingGroup: {
+ operationsWorkingGroupAlpha: {
addOpening: {
event: 'OpeningCreated',
onSend: args.onCreateOpening,
@@ -101,7 +115,7 @@ export default {
},
},
consts: {
- membershipWorkingGroup: {
+ operationsWorkingGroupAlpha: {
minimumApplicationStake: joy(10),
minUnstakingPeriodLimit: 100,
},
@@ -115,8 +129,7 @@ export default {
query: GetWorkingGroupDocument,
data: {
workingGroupByUniqueInput: {
- id: WG_DATA.id,
- name: WG_DATA.name,
+ ...WG_DATA,
budget: joy(200),
workers: [],
leader: { membershipId: alice.id, isActive: args.isLead },
@@ -125,31 +138,16 @@ export default {
},
{
query: GetWorkersDocument,
- data: {
- workers: [
- {
- id: `${WG_DATA.id}-0`,
- group: {
- id: WG_DATA.id,
- name: WG_DATA.name,
- },
- status: 'WorkerStatusActive',
- membership: alice,
- },
- {
- id: `${WG_DATA.id}-1`,
- group: {
- id: WG_DATA.id,
- name: WG_DATA.name,
- },
- status: 'WorkerStatusActive',
- membership: member('charlie'),
- },
- ],
- },
+ data: { workers },
},
// Opening tab
+ {
+ query: GetRoleAccountsDocument,
+ data: {
+ workers: args.isLead ? [{ roleAccount: alice.controllerAccount }] : [],
+ },
+ },
{
query: GetGroupDebtDocument,
data: {
@@ -255,12 +253,13 @@ export const CreateOpening: Story = {
await waitFor(() => expect(nextButton).toBeDisabled())
- await userEvent.type(openingTitleField, 'Membership worker role')
+ await userEvent.type(openingTitleField, 'Builder worker role')
await userEvent.type(shortDescriptionField, 'Lorem Ipsum...')
;(await getEditorByLabel(modal, 'Description')).setData('Bigger Lorem ipsum...')
await waitFor(() => expect(nextButton).toBeEnabled())
await userEvent.click(nextButton)
})
+
await step('Duration & Process', async () => {
await waitFor(() => expect(nextButton).toBeDisabled())
;(await getEditorByLabel(modal, 'Application process')).setData('Application process default')
@@ -275,6 +274,7 @@ export const CreateOpening: Story = {
await waitFor(() => expect(nextButton).toBeEnabled())
await userEvent.click(nextButton)
})
+
await step('Application Form', async () => {
await waitFor(() => expect(nextButton).toBeDisabled())
await userEvent.type(modal.getByRole('textbox'), '🐁?')
@@ -286,12 +286,19 @@ export const CreateOpening: Story = {
await waitFor(() => expect(nextButton).toBeEnabled())
await userEvent.click(nextButton)
})
+
await step('Staking Policy & Reward', async () => {
const createButton = getButtonByText(modal, 'Create Opening')
expect(createButton).toBeDisabled()
- await userEvent.type(modal.getByLabelText('Staking amount *'), '100')
- await userEvent.clear(modal.getByLabelText('Role cooldown period'))
- await userEvent.type(modal.getByLabelText('Role cooldown period'), '1000')
+
+ const stakeAmountField = modal.getByLabelText('Staking amount *')
+ await userEvent.clear(stakeAmountField)
+ await userEvent.type(stakeAmountField, '100')
+
+ const coolDownField = modal.getByLabelText('Role cooldown period')
+ await userEvent.clear(coolDownField)
+ await userEvent.type(coolDownField, '1000')
+
await userEvent.type(modal.getByLabelText('Reward amount per Block'), '0.1')
await waitFor(() => expect(createButton).toBeEnabled())
await userEvent.click(createButton)
@@ -314,8 +321,14 @@ export const CreateOpening: Story = {
expect(openingType).toEqual('Regular')
expect(metadataFromBytes(OpeningMetadata, description)).toEqual(WG_OPENING_METADATA)
})
+
+ await step('Link to new Opening', async () => {
+ const openingLink = (await modal.findByText('See my Opening')).parentElement as Element
+ expect(openingLink.getAttribute('href')).toBe('/working-groups/openings/builders-1')
+ })
},
}
+
export const CreateOpeningImport: Story = {
parameters: {
router: { path: '/working-groups/:name/openings', href: `/working-groups/${WG_DATA.name}/openings` },
@@ -342,6 +355,7 @@ export const CreateOpeningImport: Story = {
new File([JSON.stringify(WG_JSON_OPENING)], 'file.json', { type: 'application/json' })
)
})
+
await step('Check imported data', async () => {
expect(await modal.findByText(/File imported successfully, preview your input/))
@@ -366,10 +380,12 @@ export const CreateOpeningImport: Story = {
const createButton = getButtonByText(modal, 'Create Opening')
await userEvent.click(createButton)
})
+
await step('Sign transaction and Create', async () => {
expect(await modal.findByText('You intend to create an Opening.'))
await userEvent.click(modal.getByText('Sign transaction and Create'))
})
+
step('Transaction parameters', () => {
const [description, openingType, stakePolicy, rewardPerBlock] = args.onCreateOpening.mock.calls.at(-1)
diff --git a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroup.tsx b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroup.tsx
index ca8c5e3369..e0927a7e71 100644
--- a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroup.tsx
+++ b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroup.tsx
@@ -7,18 +7,21 @@ import { nameMapping } from '@/common/helpers'
import { useWorkingGroup } from '@/working-groups/hooks/useWorkingGroup'
import { urlParamToWorkingGroupId } from '@/working-groups/model/workingGroupName'
-import { AboutTab, AboutTabSidebar } from './AboutTab'
+import { AboutTab } from './AboutTab'
+import { WorkerListSidebar } from './components/WorkerListSidebar'
import { WorkingGroupPageHeader } from './components/WorkingGroupPageHeader'
export const WorkingGroup = () => {
- const { name } = useParams<{ name: string }>()
- const { isLoading, group } = useWorkingGroup({ name: urlParamToWorkingGroupId(name) })
+ const params = useParams<{ name: string }>()
+ const name = urlParamToWorkingGroupId(params.name)
+
+ const { isLoading, group } = useWorkingGroup({ name })
return (
}
+ header={}
main={isLoading || !group ? : }
- sidebar={!isLoading && group && }
+ sidebar={!isLoading && group && }
sidebarScrollable
lastBreadcrumb={nameMapping(group?.name ?? name)}
/>
diff --git a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroupHistory.tsx b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroupHistory.tsx
index 3ff8e9a872..b1107a1804 100644
--- a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroupHistory.tsx
+++ b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroupHistory.tsx
@@ -10,12 +10,14 @@ import { WorkingGroupPageHeader } from './components/WorkingGroupPageHeader'
import { HistoryTab, HistoryTabSidebar } from './HistoryTab'
export function WorkingGroupHistory() {
- const { name } = useParams<{ name: string }>()
- const { isLoading, group } = useWorkingGroup({ name: urlParamToWorkingGroupId(name) })
+ const params = useParams<{ name: string }>()
+ const name = urlParamToWorkingGroupId(params.name)
+
+ const { isLoading, group } = useWorkingGroup({ name })
return (
}
+ header={}
main={isLoading || !group ? : }
sidebar={!isLoading && group && }
sidebarScrollable
diff --git a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroupOpenings.tsx b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroupOpenings.tsx
index e1d9b73b0a..ac5ab79a47 100644
--- a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroupOpenings.tsx
+++ b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/WorkingGroupOpenings.tsx
@@ -6,18 +6,21 @@ import { Loading } from '@/common/components/Loading'
import { useWorkingGroup } from '@/working-groups/hooks/useWorkingGroup'
import { urlParamToWorkingGroupId } from '@/working-groups/model/workingGroupName'
+import { WorkerListSidebar } from './components/WorkerListSidebar'
import { WorkingGroupPageHeader } from './components/WorkingGroupPageHeader'
-import { OpeningsTab, OpeningsTabSidebar } from './OpeningsTab'
+import { OpeningsTab } from './OpeningsTab'
export function WorkingGroupOpenings() {
- const { name } = useParams<{ name: string }>()
- const { isLoading, group } = useWorkingGroup({ name: urlParamToWorkingGroupId(name) })
+ const params = useParams<{ name: string }>()
+ const name = urlParamToWorkingGroupId(params.name)
+
+ const { isLoading, group } = useWorkingGroup({ name })
return (
}
+ header={}
main={isLoading || !group ? : }
- sidebar={!isLoading && group && }
+ sidebar={!isLoading && group && }
sidebarScrollable
lastBreadcrumb="Openings"
/>
diff --git a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/components/WorkerListSidebar.tsx b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/components/WorkerListSidebar.tsx
new file mode 100644
index 0000000000..6338db4e98
--- /dev/null
+++ b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/components/WorkerListSidebar.tsx
@@ -0,0 +1,21 @@
+import React from 'react'
+
+import { SidePanel } from '@/common/components/page/SidePanel'
+import { WorkersList } from '@/working-groups/components/WorkersList'
+import { useWorkers } from '@/working-groups/hooks/useWorkers'
+import { WorkingGroup } from '@/working-groups/types'
+
+interface Props {
+ workingGroup: WorkingGroup
+}
+
+export const WorkerListSidebar = ({ workingGroup }: Props) => {
+ const { workers } = useWorkers({ groupId: workingGroup.id ?? '', status: 'active' })
+ const lead = workingGroup.isActive ? workers?.find((worker) => worker.member.id === workingGroup.leadId) : undefined
+
+ return (
+
+
+
+ )
+}
diff --git a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/components/WorkingGroupPageHeader.tsx b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/components/WorkingGroupPageHeader.tsx
index fbbb94e841..56496e6d22 100644
--- a/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/components/WorkingGroupPageHeader.tsx
+++ b/packages/ui/src/app/pages/WorkingGroups/WorkingGroup/components/WorkingGroupPageHeader.tsx
@@ -1,10 +1,8 @@
-import React, { useMemo } from 'react'
-import { useParams } from 'react-router-dom'
+import React from 'react'
import { PageHeader } from '@/app/components/PageHeader'
import { nameMapping } from '@/common/helpers'
import { CreateOpeningButton } from '@/working-groups/components/CreateOpeningButton'
-import { useMyWorkers } from '@/working-groups/hooks/useMyWorkers'
import { WorkingGroup } from '@/working-groups/types'
import { StatusBadge, StatusGroup } from '../../components/StatusBadges'
@@ -12,21 +10,15 @@ import { StatusBadge, StatusGroup } from '../../components/StatusBadges'
import { WorkingGroupTabs } from './WorkingGroupTabs'
interface WorkingGroupPageHeaderProps {
+ name: string
group: WorkingGroup | undefined
withButtons?: boolean
}
-export const WorkingGroupPageHeader = React.memo(({ group, withButtons = false }: WorkingGroupPageHeaderProps) => {
- const { name } = useParams<{ name: string }>()
- const { workers } = useMyWorkers()
- const isLead = useMemo(
- () => group?.isActive && workers.find((w) => w.membership.id === group?.leadId),
- [workers, group?.isActive, group?.leadId]
- )
-
+export const WorkingGroupPageHeader = React.memo(({ name, group, withButtons }: WorkingGroupPageHeaderProps) => {
return (
)
}
- buttons={withButtons && group && isLead && }
+ buttons={withButtons && }
tabs={}
/>
)
diff --git a/packages/ui/src/common/components/buttons/LinkButtons.tsx b/packages/ui/src/common/components/buttons/LinkButtons.tsx
index 6ee611ee24..2854ba176f 100644
--- a/packages/ui/src/common/components/buttons/LinkButtons.tsx
+++ b/packages/ui/src/common/components/buttons/LinkButtons.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { MouseEventHandler } from 'react'
import { Link } from 'react-router-dom'
import styled, { css } from 'styled-components'
@@ -12,6 +12,7 @@ export interface LinkButtonProps extends LinkButtonSizingProps {
children?: React.ReactNode
disabled?: boolean
to: string
+ onClick?: MouseEventHandler
}
interface LinkButtonSizingProps {
@@ -39,41 +40,41 @@ const getPadding = (props: BasicLinkButtonStylesProps) => {
return props.$square ? '8px' : '8px 16px'
}
-export function LinkButtonPrimary({ className, children, size, square, disabled, to }: LinkButtonProps) {
+export function LinkButtonPrimary({ children, size, square, ...props }: LinkButtonProps) {
return (
-
+
{children}
)
}
-export function LinkButtonSecondary({ className, children, size, square, disabled, to }: LinkButtonProps) {
+export function LinkButtonSecondary({ children, size, square, ...props }: LinkButtonProps) {
return (
-
+
{children}
)
}
-export function LinkButtonGhost({ className, children, size, square, disabled, to }: LinkButtonProps) {
+export function LinkButtonGhost({ children, size, square, ...props }: LinkButtonProps) {
return (
-
+
{children}
)
}
-export function LinkButtonBareGhost({ className, children, size, square, disabled, to }: LinkButtonProps) {
+export function LinkButtonBareGhost({ children, size, square, ...props }: LinkButtonProps) {
return (
-
+
{children}
)
}
-export function LinkButtonLink({ className, children, square, disabled, to }: LinkButtonProps) {
+export function LinkButtonLink({ children, square, ...props }: LinkButtonProps) {
return (
-
+
{children}
)
diff --git a/packages/ui/src/working-groups/components/CreateOpeningButton.tsx b/packages/ui/src/working-groups/components/CreateOpeningButton.tsx
index fe11aa10eb..878c81e0b4 100644
--- a/packages/ui/src/working-groups/components/CreateOpeningButton.tsx
+++ b/packages/ui/src/working-groups/components/CreateOpeningButton.tsx
@@ -1,24 +1,35 @@
-import React, { useCallback } from 'react'
+import React from 'react'
+import { useMyAccounts } from '@/accounts/hooks/useMyAccounts'
import { TransactionButton } from '@/common/components/buttons/TransactionButton'
import { PlusIcon } from '@/common/components/icons/PlusIcon'
import { useModal } from '@/common/hooks/useModal'
+import { useRoleAccount } from '@/working-groups/hooks/useRoleAccount'
import { CreateOpeningModalCall } from '@/working-groups/modals/CreateOpening/types'
-import { GroupIdName } from '@/working-groups/types'
+import { WorkingGroup } from '@/working-groups/types'
-export interface CreateOpeningButtonProps {
- group: GroupIdName
+type CreateOpeningButtonProps = {
+ name: string
+ group: WorkingGroup | undefined
}
-export const CreateOpeningButton = ({ group }: CreateOpeningButtonProps) => {
+export const CreateOpeningButton = ({ name, group }: CreateOpeningButtonProps) => {
const { showModal } = useModal()
- const createOpening = useCallback(
- () => showModal({ modal: 'CreateOpening', data: { group } }),
- [group]
- )
+
+ const { roleAccount: leadAccount } = useRoleAccount({ isLead_eq: true, isActive_eq: true, group: { name_eq: name } })
+ const { allAccounts } = useMyAccounts()
+ const isLead = allAccounts.some((account) => account.address === leadAccount)
+
+ if (!group || !leadAccount || !isLead) {
+ return null
+ }
return (
-
+ showModal({ modal: 'CreateOpening', data: { group, leadAccount } })}
+ >
Add opening
diff --git a/packages/ui/src/working-groups/hooks/useRoleAccount.ts b/packages/ui/src/working-groups/hooks/useRoleAccount.ts
new file mode 100644
index 0000000000..c7a0287faa
--- /dev/null
+++ b/packages/ui/src/working-groups/hooks/useRoleAccount.ts
@@ -0,0 +1,13 @@
+import { useMemo } from 'react'
+
+import { WorkerWhereInput } from '@/common/api/queries'
+import { useGetRoleAccountsQuery } from '@/working-groups/queries'
+
+type UseRoleAccount = { roleAccount: string | undefined; isLoading: boolean }
+
+export const useRoleAccount = (where: WorkerWhereInput): UseRoleAccount => {
+ const { data, loading } = useGetRoleAccountsQuery({ variables: { where } })
+ const roleAccount = useMemo(() => data?.workers.at(0)?.roleAccount, [data, loading])
+
+ return { roleAccount, isLoading: loading }
+}
diff --git a/packages/ui/src/working-groups/modals/CreateOpening/CreateOpening.tsx b/packages/ui/src/working-groups/modals/CreateOpening/CreateOpening.tsx
index d18860a977..964222b69e 100644
--- a/packages/ui/src/working-groups/modals/CreateOpening/CreateOpening.tsx
+++ b/packages/ui/src/working-groups/modals/CreateOpening/CreateOpening.tsx
@@ -1,3 +1,4 @@
+import { merge } from 'lodash'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import styled from 'styled-components'
@@ -16,39 +17,58 @@ import { isLastStepActive } from '@/common/modals/utils'
import { getSteps } from '@/common/model/machines/getSteps'
import { useYupValidationResolver } from '@/common/utils/validation'
import { machineStateConverter } from '@/council/modals/AnnounceCandidacy/helpers'
-import { useMyMemberships } from '@/memberships/hooks/useMyMemberships'
import { StyledStepperBody } from '@/proposals/modals/AddNewProposal'
import { SuccessModal, CreateOpeningSteps as Steps, ImportOpening } from './components'
import { createOpeningMachine, CreateOpeningMachineState } from './machine'
-import { OpeningConditions, CreateOpeningForm, CreateOpeningModalCall, OpeningSchema, defaultValues } from './types'
+import {
+ OpeningConditions,
+ CreateOpeningForm,
+ CreateOpeningModalCall,
+ OpeningSchema,
+ defaultValues as _defaultValue,
+} from './types'
import { getTxParams } from './utils'
export const CreateOpeningModal = () => {
const [showImport, setShowImport] = useState(false)
const { api } = useApi()
- const { active: activeMember } = useMyMemberships()
const [state, send, service] = useMachine(createOpeningMachine)
const { hideModal, modalData } = useModal()
- const { group } = modalData
- const workingGroupConsts = api?.consts[group]
-
- const context = {
- group,
- minUnstakingPeriodLimit: workingGroupConsts?.minUnstakingPeriodLimit,
- minimumApplicationStake: workingGroupConsts?.minimumApplicationStake,
- } as OpeningConditions
+ const { id: group, name: groupName } = modalData.group
+ const signer = modalData.leadAccount
+
+ const context = useMemo(
+ () =>
+ ({
+ group,
+ minUnstakingPeriodLimit: api?.consts[group].minUnstakingPeriodLimit,
+ minimumApplicationStake: api?.consts[group].minimumApplicationStake,
+ } as OpeningConditions),
+ [api?.isConnected]
+ )
const path = useMemo(() => machineStateConverter(state.value), [state.value])
const resolver = useYupValidationResolver(OpeningSchema, path)
+ const defaultValues = useMemo(
+ () =>
+ merge({}, _defaultValue, {
+ stakingPolicyAndReward: {
+ stakingAmount: context.minimumApplicationStake,
+ leavingUnstakingPeriod: context.minUnstakingPeriodLimit?.toNumber(),
+ },
+ }),
+ [context]
+ )
+
const form = useForm({ resolver, mode: 'onChange', defaultValues, context })
useEffect(() => {
form.trigger(machineStateConverter(state.value) as keyof CreateOpeningForm)
}, [machineStateConverter(state.value)])
const { transaction, feeInfo } = useTransactionFee(
- activeMember?.controllerAccount,
+ signer,
() => {
if (api && group) {
const { ...specifics } = form.getValues() as CreateOpeningForm
@@ -56,8 +76,9 @@ export const CreateOpeningModal = () => {
return api.tx[group].addOpening(description, 'Regular', stakePolicy, String(rewardPerBlock))
}
},
- [api?.isConnected, activeMember?.id, group, form.formState.isValidating]
+ [api?.isConnected, signer, group, form.formState.isValidating]
)
+
const exportedJsonValue = useMemo(() => {
const { ...specifics } = form.getValues() as CreateOpeningForm
const exportValue = {
@@ -85,24 +106,21 @@ export const CreateOpeningModal = () => {
}, [send])
useEffect((): any => {
- if (state.matches('requirementsVerification')) {
- return feeInfo && send(feeInfo.canAfford ? 'NEXT' : 'FAIL')
- }
if (state.matches('beforeTransaction')) {
return feeInfo?.canAfford ? send('NEXT') : send('FAIL')
}
- }, [state, activeMember?.id, feeInfo])
+ }, [state, feeInfo])
- if (!activeMember || state.matches('requirementsFailed')) {
+ if (state.matches('requirementsFailed')) {
return null
}
- if (state.matches('transaction') && transaction && group) {
+ if (state.matches('transaction') && transaction) {
return (
You intend to create an Opening.
@@ -111,7 +129,7 @@ export const CreateOpeningModal = () => {
}
if (state.matches('success') && group) {
- return
+ return
}
return (
diff --git a/packages/ui/src/working-groups/modals/CreateOpening/components/Success.tsx b/packages/ui/src/working-groups/modals/CreateOpening/components/Success.tsx
index c2de543f41..c62991b4e4 100644
--- a/packages/ui/src/working-groups/modals/CreateOpening/components/Success.tsx
+++ b/packages/ui/src/working-groups/modals/CreateOpening/components/Success.tsx
@@ -1,26 +1,23 @@
import React from 'react'
-import { useHistory } from 'react-router-dom'
+import { generatePath } from 'react-router-dom'
-import { ButtonGhost } from '@/common/components/buttons'
+import { LinkButtonGhost } from '@/common/components/buttons/LinkButtons'
import { SuccessSymbol } from '@/common/components/icons/symbols'
import { Info } from '@/common/components/Info'
import { Modal, ModalBody, ModalFooter, ModalHeader } from '@/common/components/Modal'
import { TextMedium } from '@/common/components/typography'
-import { GroupIdToGroupParam } from '@/working-groups/constants'
-import { GroupIdName } from '@/working-groups/types'
+import { nameMapping } from '@/common/helpers'
+import { WorkingGroupsRoutes } from '@/working-groups/constants'
+import { groupNameToURLParam } from '@/working-groups/model/workingGroupName'
interface SuccessModalProps {
onClose: () => void
- groupId: GroupIdName
+ groupName: string
+ openingRuntimeId: number
}
-export const SuccessModal = ({ onClose, groupId }: SuccessModalProps) => {
- const history = useHistory()
-
- const redirect = () => {
- onClose()
- history.push(`/working-groups/${GroupIdToGroupParam[groupId].toLowerCase()}`)
- }
+export const SuccessModal = ({ onClose, groupName, openingRuntimeId }: SuccessModalProps) => {
+ const openingId = `${groupNameToURLParam(nameMapping(groupName))}${openingRuntimeId}`
return (
@@ -31,9 +28,13 @@ export const SuccessModal = ({ onClose, groupId }: SuccessModalProps) => {
-
- Back to Working Group
-
+
+ See my Opening
+
)
diff --git a/packages/ui/src/working-groups/modals/CreateOpening/machine.ts b/packages/ui/src/working-groups/modals/CreateOpening/machine.ts
index 8a94cbdc2f..2186734804 100644
--- a/packages/ui/src/working-groups/modals/CreateOpening/machine.ts
+++ b/packages/ui/src/working-groups/modals/CreateOpening/machine.ts
@@ -14,7 +14,6 @@ import { EmptyObject } from '@/common/types'
import { CreateOpeningForm, TransactionContext } from './types'
export type CreateOpeningState =
- | { value: 'requirementsVerification'; context: EmptyObject }
| { value: 'requirementsFailed'; context: EmptyObject }
| { value: 'workingGroupAndDescription'; context: Required }
| { value: 'durationAndProcess'; context: Required }
@@ -37,9 +36,8 @@ export type CreateOpeningMachineState = State<
type Context = CreateOpeningForm & TransactionContext
export const createOpeningMachine = createMachine, CreateOpeningEvent, CreateOpeningState>({
- initial: 'requirementsVerification',
+ initial: 'workingGroupAndDescription',
states: {
- requirementsVerification: { on: { FAIL: 'requirementsFailed', NEXT: 'workingGroupAndDescription' } },
requirementsFailed: { type: 'final' },
workingGroupAndDescription: {
meta: {
diff --git a/packages/ui/src/working-groups/modals/CreateOpening/types.tsx b/packages/ui/src/working-groups/modals/CreateOpening/types.tsx
index a60c0d3ee3..4cfc63a95d 100644
--- a/packages/ui/src/working-groups/modals/CreateOpening/types.tsx
+++ b/packages/ui/src/working-groups/modals/CreateOpening/types.tsx
@@ -5,10 +5,11 @@ import * as Yup from 'yup'
import { QuestionValueProps } from '@/common/components/EditableInputList/EditableInputList'
import { ModalWithDataCall } from '@/common/providers/modal/types'
import { BNSchema, minContext, minMixed } from '@/common/utils/validation'
-import { GroupIdName } from '@/working-groups/types'
+import { GroupIdName, WorkingGroup } from '@/working-groups/types'
export interface OpeningModalData {
- group: GroupIdName
+ group: WorkingGroup
+ leadAccount: string
}
export type CreateOpeningModalCall = ModalWithDataCall<'CreateOpening', OpeningModalData>
diff --git a/packages/ui/src/working-groups/queries/__generated__/workingGroups.generated.tsx b/packages/ui/src/working-groups/queries/__generated__/workingGroups.generated.tsx
index 112006efcb..693ea4dd0a 100644
--- a/packages/ui/src/working-groups/queries/__generated__/workingGroups.generated.tsx
+++ b/packages/ui/src/working-groups/queries/__generated__/workingGroups.generated.tsx
@@ -285,6 +285,15 @@ export type GetWorkingGroupsQuery = {
}>
}
+export type GetRoleAccountsQueryVariables = Types.Exact<{
+ where?: Types.InputMaybe
+}>
+
+export type GetRoleAccountsQuery = {
+ __typename: 'Query'
+ workers: Array<{ __typename: 'Worker'; roleAccount: string }>
+}
+
export type GetWorkersQueryVariables = Types.Exact<{
where?: Types.InputMaybe
offset?: Types.InputMaybe
@@ -1870,6 +1879,45 @@ export function useGetWorkingGroupsLazyQuery(
export type GetWorkingGroupsQueryHookResult = ReturnType
export type GetWorkingGroupsLazyQueryHookResult = ReturnType
export type GetWorkingGroupsQueryResult = Apollo.QueryResult
+export const GetRoleAccountsDocument = gql`
+ query GetRoleAccounts($where: WorkerWhereInput) {
+ workers(where: $where) {
+ roleAccount
+ }
+ }
+`
+
+/**
+ * __useGetRoleAccountsQuery__
+ *
+ * To run a query within a React component, call `useGetRoleAccountsQuery` and pass it any options that fit your needs.
+ * When your component renders, `useGetRoleAccountsQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useGetRoleAccountsQuery({
+ * variables: {
+ * where: // value for 'where'
+ * },
+ * });
+ */
+export function useGetRoleAccountsQuery(
+ baseOptions?: Apollo.QueryHookOptions
+) {
+ const options = { ...defaultOptions, ...baseOptions }
+ return Apollo.useQuery(GetRoleAccountsDocument, options)
+}
+export function useGetRoleAccountsLazyQuery(
+ baseOptions?: Apollo.LazyQueryHookOptions
+) {
+ const options = { ...defaultOptions, ...baseOptions }
+ return Apollo.useLazyQuery(GetRoleAccountsDocument, options)
+}
+export type GetRoleAccountsQueryHookResult = ReturnType
+export type GetRoleAccountsLazyQueryHookResult = ReturnType
+export type GetRoleAccountsQueryResult = Apollo.QueryResult
export const GetWorkersDocument = gql`
query GetWorkers($where: WorkerWhereInput, $offset: Int, $limit: Int) {
workers(where: $where, offset: $offset, limit: $limit) {
diff --git a/packages/ui/src/working-groups/queries/workingGroups.graphql b/packages/ui/src/working-groups/queries/workingGroups.graphql
index 377fef292e..7b60ce6c51 100644
--- a/packages/ui/src/working-groups/queries/workingGroups.graphql
+++ b/packages/ui/src/working-groups/queries/workingGroups.graphql
@@ -129,6 +129,12 @@ query GetWorkingGroups {
}
}
+query GetRoleAccounts($where: WorkerWhereInput) {
+ workers(where: $where) {
+ roleAccount
+ }
+}
+
query GetWorkers($where: WorkerWhereInput, $offset: Int, $limit: Int) {
workers(where: $where, offset: $offset, limit: $limit) {
...WorkerFields