Skip to content

Commit

Permalink
Merge pull request #43 from TalismanSociety/feat/vault-description
Browse files Browse the repository at this point in the history
[FEAT] - Vault description
  • Loading branch information
UrbanWill authored May 14, 2024
2 parents 822121e + 9bedcb0 commit 23bf020
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 16 deletions.
1 change: 1 addition & 0 deletions apps/multisig/src/domains/multisig/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const DUMMY_MULTISIG: Multisig = {
id: DUMMY_MULTISIG_ID,
orgId: 'DUMMY_ORG',
name: 'DUMMY_MULTISIG',
description: 'DUMMY_MULTISIG_DESCRIPTION',
chain: filteredSupportedChains[0] as Chain,
signers: [],
threshold: 0,
Expand Down
1 change: 1 addition & 0 deletions apps/multisig/src/domains/multisig/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface Multisig {
id: string
orgId: string
name: string
description: string
chain: Chain
multisigAddress: Address
proxyAddress: Address
Expand Down
4 changes: 4 additions & 0 deletions apps/multisig/src/domains/offchain-data/organisation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const GET_ORGANISATIONS = gql`
teams {
id
name
description
chain
multisig_config
proxied_address
Expand Down Expand Up @@ -54,6 +55,7 @@ type RawOrgUser = {
export type RawTeam = {
id: string
name: string
description: string
multisig_config: any
proxied_address: string
chain: string
Expand All @@ -68,6 +70,7 @@ type Plan = {
export type Organisation<TeamType = RawTeam, OrgUserType = RawOrgUser> = {
id: string
name: string
description: string
slug: string
teams: TeamType[]
users: OrgUserType[]
Expand Down Expand Up @@ -229,6 +232,7 @@ export const useCreateOrganisation = () => {
{
id: data.createOrgFree.org.id,
name: data.createOrgFree.org.name,
description: data.createOrgFree.org.description,
plan: {
id: data.createOrgFree.org.plan.id,
max_vault: data.createOrgFree.org.plan.max_vault,
Expand Down
3 changes: 3 additions & 0 deletions apps/multisig/src/domains/offchain-data/teams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export class Team {
constructor(
public id: string,
public name: string,
public description: string,
public multisigConfig: {
threshold: number
signers: Address[]
Expand All @@ -44,6 +45,7 @@ export class Team {
id: this.id,
orgId: this.orgId,
name: this.name,
description: this.description,
multisigAddress: toMultisigAddress(this.multisigConfig.signers, this.multisigConfig.threshold),
proxyAddress: this.proxiedAddress,
signers: this.multisigConfig.signers,
Expand Down Expand Up @@ -197,6 +199,7 @@ export const parseTeam = (org: Organisation, rawTeam: RawTeam): { team?: Team; e
team: new Team(
rawTeam.id,
rawTeam.name,
rawTeam.description,
{
threshold: rawTeam.multisig_config.threshold,
signers,
Expand Down
24 changes: 12 additions & 12 deletions apps/multisig/src/layouts/Overview/VaultOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import persist from '@domains/persist'
import { Fragment } from 'react'
import { secondsToDuration } from '@util/misc'
import { cn } from '@util/tailwindcss'
import { clsx } from 'clsx'

const showMemberState = atom<boolean>({
key: 'dashboardShowMemberState',
Expand All @@ -22,19 +23,18 @@ export const VaultOverview: React.FC = () => {
const { contactByAddress } = useKnownAddresses(selectedMultisig.orgId)

return (
<section
css={{
backgroundColor: 'var(--color-grey800)',
borderRadius: 16,
display: 'flex',
flexDirection: 'column',
padding: 24,
}}
>
<section className="flex flex-col p-[24px] rounded-2xl bg-gray-800">
<div className="w-full flex items-center justify-between flex-1 gap-[8px]">
<h2 className="text-[20px] flex-1 w-1 overflow-hidden text-offWhite font-bold whitespace-nowrap text-ellipsis">
{selectedMultisig.name}
</h2>
<div className="text-[20px] flex-1 w-1 text-offWhite font-bold">
<h2 className="truncate">{selectedMultisig.name} </h2>
<p
className={clsx('text-[14px] truncate text-gray-200', {
hidden: !selectedMultisig.description,
})}
>
{selectedMultisig.description}
</p>
</div>
<ChainPill chain={selectedMultisig.chain} identiconSize={24} />
</div>
<div css={{ marginTop: 24 }}>
Expand Down
119 changes: 119 additions & 0 deletions apps/multisig/src/layouts/Settings/DescriptionForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { useCallback, useMemo, useState } from 'react'
import { SettingsInfoRow } from './InfoRow'
import { Button } from '@components/ui/button'
import { Edit, X } from 'lucide-react'
import { Input } from '@components/ui/input'
import Modal from '@components/Modal'
import { useMutation } from '@apollo/client'
import { gql } from 'graphql-tag'
import { useToast } from '@components/ui/use-toast'
import { organisationsState } from '@domains/offchain-data'
import { useSetRecoilState } from 'recoil'
import clsx from 'clsx'

type Props = {
description: string
editable?: boolean
teamId: string
}

const PLACEHOLDER = 'Add a Multisig description'

const UPDATE_VAULT_DESCRIPTION = gql`
mutation UpdateTeamDescription($teamId: uuid!, $description: String!) {
update_team_by_pk(pk_columns: { id: $teamId }, _set: { description: $description }) {
id
description
}
}
`
export const DescriptionForm: React.FC<Props> = ({ editable, description, teamId }) => {
const [isOpen, setIsOpen] = useState(false)
const [newDescription, setNewDescription] = useState(description)
const setOrganisations = useSetRecoilState(organisationsState)
const { toast } = useToast()
const [mutate, { loading }] = useMutation<{ update_team_by_pk: { id: string; description: string } }>(
UPDATE_VAULT_DESCRIPTION,
{
variables: {
teamId,
description: newDescription,
},
onCompleted: data => {
if (data.update_team_by_pk && data.update_team_by_pk.id === teamId) {
toast({ title: 'Multisig description updated' })
setIsOpen(false)
setOrganisations(prev => {
const newOrgs = prev.map(org => {
const teams = org.teams.map(team =>
team.id === teamId ? { ...team, description: newDescription } : team
)
return { ...org, teams }
})
return newOrgs
})
}
},
}
)
const dirty = useMemo(() => description !== newDescription, [description, newDescription])

const handleChange = useCallback(
(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
mutate()
},
[mutate]
)

return (
<SettingsInfoRow label="Multisig Description" className="max-w-[50%] w-fit text-wrap xl:text-nowrap">
<div className="flex items-center gap-[8px]">
<p className={clsx('text-[16px] font-bold mt-[3px] truncate', { 'text-offWhite': description })}>
{description || PLACEHOLDER}
</p>
{editable && (
<Button
size="icon"
variant="ghost"
onClick={() => setIsOpen(true)}
className="!focus-visible:ring-0 !ring-0 focus-visible:ring-transparent outline-none focus-visible:outline-none ring-offset-0 focus-visible:ring-offset-transparent"
>
<Edit size={16} />
</Button>
)}
</div>

<Modal isOpen={isOpen} width="100%" maxWidth={420} contentLabel="Edit Multisig Description">
<form className="grid w-full gap-[16px]" onSubmit={handleChange}>
<div className="flex items-center justify-between">
<h1 className="text-[20px] font-bold">Edit Multisig Description</h1>
<Button onClick={() => setIsOpen(false)} disabled={loading} size="icon" variant="secondary" type="button">
<X size={16} />
</Button>
</div>
<Input
label="Multisig Description"
value={newDescription}
placeholder={PLACEHOLDER}
onChange={e => setNewDescription(e.target.value)}
/>
<div className="grid grid-cols-2 gap-[8px] w-full">
<Button
className="w-full"
variant="outline"
disabled={loading}
type="button"
onClick={() => setIsOpen(false)}
>
Cancel
</Button>
<Button className="w-full" disabled={!dirty || loading} loading={loading} type="submit">
Save
</Button>
</div>
</form>
</Modal>
</SettingsInfoRow>
)
}
4 changes: 3 additions & 1 deletion apps/multisig/src/layouts/Settings/InfoRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ type Props = {
label: string
tooltip?: React.ReactNode
labelClassName?: string
className?: string
}

export const SettingsInfoRow: React.FC<React.PropsWithChildren<Props>> = ({
labelClassName,
className,
label,
tooltip,
children,
}) => (
<div className="flex flex-col gap-[4px] w-full">
<div className={cn('flex flex-col gap-[4px] w-full', className)}>
<div className="flex items-center gap-[8px] text-gray-200">
<p className={cn('text-[14px] mt-[2px] text-gray-200', labelClassName)}>{label}</p>
{tooltip && (
Expand Down
4 changes: 2 additions & 2 deletions apps/multisig/src/layouts/Settings/NameForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ export const NameForm: React.FC<Props> = ({ editable, name, teamId }) => {
)

return (
<SettingsInfoRow label="Multisig Name">
<SettingsInfoRow label="Multisig Name" className="w-[50%]">
<div className="flex items-center justify-start gap-[8px]">
<p className="text-[16px] text-offWhite font-bold mt-[3px]">{name}</p>
<p className="text-[16px] text-offWhite font-bold mt-[3px] truncate">{name}</p>
{editable && (
<Button
size="icon"
Expand Down
6 changes: 5 additions & 1 deletion apps/multisig/src/layouts/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ExternalLink } from 'lucide-react'
import { Button } from '@components/ui/button'
import { useUser } from '@domains/auth'
import { NameForm } from './NameForm'
import { DescriptionForm } from './DescriptionForm'
import { RecoverMultisig } from './RecoverMultisig'

const Settings = () => {
Expand Down Expand Up @@ -65,7 +66,10 @@ const Settings = () => {
</div>
<div className="grid gap-[32px] grid-cols-1 md:grid-cols-2">
{/** first row: Name */}
<NameForm name={multisig.name} editable={isSigner} teamId={multisig.id} />
<div className="flex gap-4 justify-between">
<NameForm name={multisig.name} editable={isSigner} teamId={multisig.id} />
<DescriptionForm description={multisig.description} editable={isSigner} teamId={multisig.id} />
</div>
<div className="hidden md:block" />

{/** second row: Proxied Account | Chain */}
Expand Down

0 comments on commit 23bf020

Please sign in to comment.