Skip to content

Commit c83d6cc

Browse files
Merge pull request #123 from daostack/admin/feature/122-common-whitelisting
#122 - Common whitelisting
2 parents f4d19a0 + d0e8843 commit c83d6cc

File tree

9 files changed

+284
-11
lines changed

9 files changed

+284
-11
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import React from 'react';
2+
3+
import { gql } from '@apollo/client';
4+
import { Tooltip, Row, useToasts, Spacer } from '@geist-ui/react';
5+
import { Settings, Award, RefreshCcw, Edit, Trash2 } from '@geist-ui/react-icons';
6+
7+
import { Centered } from '@components/Centered';
8+
import { useWhitelistCommonMutation } from '@graphql';
9+
10+
interface ICommonSettingsProps {
11+
commonId: string;
12+
}
13+
14+
const WhitelistCommonMutation = gql`
15+
mutation whitelistCommon($commonId: ID!) {
16+
whitelistCommon(commonId: $commonId)
17+
}
18+
`;
19+
20+
export const CommonSettings: React.FC<ICommonSettingsProps> = ({ commonId }) => {
21+
const [, setToast] = useToasts();
22+
23+
// - Networking
24+
const [whitelistCommon, { data }] = useWhitelistCommonMutation();
25+
26+
// - Actions
27+
const onCommonWhitelisted = async () => {
28+
await whitelistCommon({
29+
variables: {
30+
commonId
31+
}
32+
});
33+
};
34+
35+
// - Effects
36+
React.useEffect(() => {
37+
if (data?.whitelistCommon) {
38+
setToast({
39+
text: 'Common whitelisted!'
40+
});
41+
}
42+
}, [data]);
43+
44+
return (
45+
<Tooltip
46+
placement="bottomEnd"
47+
trigger="click"
48+
text={(
49+
<div style={{ width: '250px', margin: '.7rem 0' }}>
50+
<Row style={{ cursor: 'pointer' }} onClick={onCommonWhitelisted}>
51+
<Award/>
52+
<Spacer x={.5} />
53+
Whitelist Common
54+
</Row>
55+
56+
<Spacer y={.7} />
57+
58+
<Row style={{ cursor: 'pointer' }}>
59+
<RefreshCcw/>
60+
<Spacer x={.5} />
61+
Refresh Common Members
62+
</Row>
63+
64+
<Spacer y={.7} />
65+
66+
<Row style={{ cursor: 'pointer' }}>
67+
<Edit/>
68+
<Spacer x={.5} />
69+
Edit Common Details
70+
</Row>
71+
72+
<Spacer y={.7} />
73+
74+
<Row style={{ cursor: 'pointer', color: 'red' }}>
75+
<Trash2 />
76+
<Spacer x={.5} />
77+
Delete Common
78+
</Row>
79+
</div>
80+
)}
81+
>
82+
<div style={{ width: 40 }}>
83+
<Centered>
84+
<Settings/>
85+
</Centered>
86+
</div>
87+
</Tooltip>
88+
);
89+
};

packages/admin/src/graphql/index.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,12 +579,25 @@ export type QueryProposalsArgs = {
579579

580580
export type Mutation = {
581581
__typename?: 'Mutation';
582+
whitelistCommon?: Maybe<Scalars['Boolean']>;
583+
/** Refresh the common members from the events. Returns the new common member count */
584+
refreshCommonMembers?: Maybe<Scalars['Int']>;
582585
executePayouts?: Maybe<Payout>;
583586
updatePaymentData?: Maybe<Scalars['Boolean']>;
584587
createIntention?: Maybe<Intention>;
585588
};
586589

587590

591+
export type MutationWhitelistCommonArgs = {
592+
commonId: Scalars['ID'];
593+
};
594+
595+
596+
export type MutationRefreshCommonMembersArgs = {
597+
commonId: Scalars['ID'];
598+
};
599+
600+
588601
export type MutationExecutePayoutsArgs = {
589602
input: ExecutePayoutInput;
590603
};
@@ -600,6 +613,16 @@ export type MutationCreateIntentionArgs = {
600613
input: CreateIntentionInput;
601614
};
602615

616+
export type WhitelistCommonMutationVariables = Exact<{
617+
commonId: Scalars['ID'];
618+
}>;
619+
620+
621+
export type WhitelistCommonMutation = (
622+
{ __typename?: 'Mutation' }
623+
& Pick<Mutation, 'whitelistCommon'>
624+
);
625+
603626
export type GetLatestEventsQueryVariables = Exact<{
604627
last?: Maybe<Scalars['Int']>;
605628
after?: Maybe<Scalars['Int']>;
@@ -1005,6 +1028,36 @@ export type GetUsersHomepageDataQuery = (
10051028
);
10061029

10071030

1031+
export const WhitelistCommonDocument = gql`
1032+
mutation whitelistCommon($commonId: ID!) {
1033+
whitelistCommon(commonId: $commonId)
1034+
}
1035+
`;
1036+
export type WhitelistCommonMutationFn = Apollo.MutationFunction<WhitelistCommonMutation, WhitelistCommonMutationVariables>;
1037+
1038+
/**
1039+
* __useWhitelistCommonMutation__
1040+
*
1041+
* To run a mutation, you first call `useWhitelistCommonMutation` within a React component and pass it any options that fit your needs.
1042+
* When your component renders, `useWhitelistCommonMutation` returns a tuple that includes:
1043+
* - A mutate function that you can call at any time to execute the mutation
1044+
* - An object with fields that represent the current status of the mutation's execution
1045+
*
1046+
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
1047+
*
1048+
* @example
1049+
* const [whitelistCommonMutation, { data, loading, error }] = useWhitelistCommonMutation({
1050+
* variables: {
1051+
* commonId: // value for 'commonId'
1052+
* },
1053+
* });
1054+
*/
1055+
export function useWhitelistCommonMutation(baseOptions?: Apollo.MutationHookOptions<WhitelistCommonMutation, WhitelistCommonMutationVariables>) {
1056+
return Apollo.useMutation<WhitelistCommonMutation, WhitelistCommonMutationVariables>(WhitelistCommonDocument, baseOptions);
1057+
}
1058+
export type WhitelistCommonMutationHookResult = ReturnType<typeof useWhitelistCommonMutation>;
1059+
export type WhitelistCommonMutationResult = Apollo.MutationResult<WhitelistCommonMutation>;
1060+
export type WhitelistCommonMutationOptions = Apollo.BaseMutationOptions<WhitelistCommonMutation, WhitelistCommonMutationVariables>;
10081061
export const GetLatestEventsDocument = gql`
10091062
query GetLatestEvents($last: Int = 10, $after: Int = 0) {
10101063
events(last: $last, after: $after) {

packages/admin/src/graphql/schema.graphql

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,13 @@ type Query {
390390
statistics: Statistics
391391
}
392392
type Mutation {
393+
whitelistCommon(commonId: ID!): Boolean
394+
"""Refresh the common members from the events. Returns the new common member count"""
395+
refreshCommonMembers(
396+
"""The common id to refresh"""
397+
commonId: ID!
398+
): Int
393399
executePayouts(input: ExecutePayoutInput!): Payout
394-
updatePaymentData(id: ID!, trackId: ID = "a06d7a1f-c179-42f8-8279-5c896d231308"): Boolean
400+
updatePaymentData(id: ID!, trackId: ID = "fbb61190-d465-4395-9136-3d643a717033"): Boolean
395401
createIntention(input: CreateIntentionInput!): Intention
396402
}

packages/admin/src/graphql/schema.json

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4001,6 +4001,64 @@
40014001
"name": "Mutation",
40024002
"description": null,
40034003
"fields": [
4004+
{
4005+
"name": "whitelistCommon",
4006+
"description": null,
4007+
"args": [
4008+
{
4009+
"name": "commonId",
4010+
"description": null,
4011+
"type": {
4012+
"kind": "NON_NULL",
4013+
"name": null,
4014+
"ofType": {
4015+
"kind": "SCALAR",
4016+
"name": "ID",
4017+
"ofType": null
4018+
}
4019+
},
4020+
"defaultValue": null,
4021+
"isDeprecated": false,
4022+
"deprecationReason": null
4023+
}
4024+
],
4025+
"type": {
4026+
"kind": "SCALAR",
4027+
"name": "Boolean",
4028+
"ofType": null
4029+
},
4030+
"isDeprecated": false,
4031+
"deprecationReason": null
4032+
},
4033+
{
4034+
"name": "refreshCommonMembers",
4035+
"description": "Refresh the common members from the events. Returns the new common member count",
4036+
"args": [
4037+
{
4038+
"name": "commonId",
4039+
"description": "The common id to refresh",
4040+
"type": {
4041+
"kind": "NON_NULL",
4042+
"name": null,
4043+
"ofType": {
4044+
"kind": "SCALAR",
4045+
"name": "ID",
4046+
"ofType": null
4047+
}
4048+
},
4049+
"defaultValue": null,
4050+
"isDeprecated": false,
4051+
"deprecationReason": null
4052+
}
4053+
],
4054+
"type": {
4055+
"kind": "SCALAR",
4056+
"name": "Int",
4057+
"ofType": null
4058+
},
4059+
"isDeprecated": false,
4060+
"deprecationReason": null
4061+
},
40044062
{
40054063
"name": "executePayouts",
40064064
"description": null,
@@ -4058,7 +4116,7 @@
40584116
"name": "ID",
40594117
"ofType": null
40604118
},
4061-
"defaultValue": "\"dbb29cd9-f299-4027-88a6-3d50deed6932\"",
4119+
"defaultValue": "\"8de250d5-0dd2-4ff3-bb18-2171ae4e49a0\"",
40624120
"isDeprecated": false,
40634121
"deprecationReason": null
40644122
}

packages/admin/src/pages/commons/details/[commonId].tsx

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,31 @@ import { useRouter } from 'next/router';
44
import ErrorPage from 'next/error';
55

66
import { gql } from '@apollo/client';
7-
import { Spacer, Text, Grid, Card, Breadcrumbs, Table, Tag, Pagination, Tooltip, useClipboard, useToasts } from '@geist-ui/react';
8-
import { ChevronLeftCircleFill, ChevronRightCircleFill, ExternalLink, User, Copy, Trash2 as Trash } from '@geist-ui/react-icons';
7+
import {
8+
Spacer,
9+
Text,
10+
Grid,
11+
Card,
12+
Breadcrumbs,
13+
Table,
14+
Tag,
15+
Pagination,
16+
Tooltip,
17+
useClipboard,
18+
useToasts
19+
} from '@geist-ui/react';
20+
import {
21+
ChevronLeftCircleFill,
22+
ChevronRightCircleFill,
23+
ExternalLink,
24+
User,
25+
Copy,
26+
Trash2 as Trash
27+
} from '@geist-ui/react-icons';
928

1029
import { useGetCommonDetailsQuery, GetCommonDetailsQueryResult } from '@graphql';
1130
import { Link } from 'components/Link';
31+
import { CommonSettings } from '@components/CommonSettings';
1232

1333
const GetCommonDetailsQuery = gql`
1434
query getCommonDetails($commonId: ID!, $page: Int!) {
@@ -94,7 +114,7 @@ const CommonDetailsPage: NextPage = () => {
94114
userId: (
95115
<div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
96116
<Tooltip text={member.userId}>
97-
<User />
117+
<User/>
98118
</Tooltip>
99119
</div>
100120
),
@@ -116,7 +136,7 @@ const CommonDetailsPage: NextPage = () => {
116136
<div style={{ width: '100%', display: 'flex', justifyContent: 'space-around' }}>
117137
<Tooltip text={'Copy user ID'} enterDelay={1000}>
118138
<div onClick={copyUserId(member.userId)}>
119-
<Copy />
139+
<Copy/>
120140
</div>
121141
</Tooltip>
122142

@@ -170,9 +190,9 @@ const CommonDetailsPage: NextPage = () => {
170190

171191
setToast({
172192
text: 'Successfully copied the user ID'
173-
})
174-
}
175-
}
193+
});
194+
};
195+
};
176196

177197
return (
178198
<React.Fragment>
@@ -195,6 +215,12 @@ const CommonDetailsPage: NextPage = () => {
195215
<Spacer x={1}/>
196216

197217
<Tag>{data.data.common.metadata.contributionType}</Tag>
218+
219+
<div style={{ marginLeft: 'auto', cursor: 'pointer' }}>
220+
{router.query.commonId && (
221+
<CommonSettings commonId={router.query.commonId as string}/>
222+
)}
223+
</div>
198224
</div>
199225
<Breadcrumbs>
200226
<Breadcrumbs.Item>Home</Breadcrumbs.Item>
@@ -290,7 +316,7 @@ const CommonDetailsPage: NextPage = () => {
290316
<Text h3>Members</Text>
291317

292318
<Table data={transformMembersForTable(data)}>
293-
<Table.Column prop="userId" label="" width={70} />
319+
<Table.Column prop="userId" label="" width={70}/>
294320
<Table.Column prop="name" label="Member Name"/>
295321
<Table.Column prop="joinedAt" label="Joined At"/>
296322
<Table.Column prop="roles" label="Roles"/>
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export { isCommonMember } from './isCommonMember';
22
export { createCommon } from './createCommon';
33
export { updateCommon } from './updateCommon';
4-
export { refreshCommonMembers } from './refreshCommonMembers';
4+
export { refreshCommonMembers } from './refreshCommonMembers';
5+
export { whitelistCommon } from './whitelistCommon';
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { commonDb } from '../database';
2+
3+
/**
4+
* Whitelist common by it's ID. It does not broadcast `CommonWhitelistedEvent` as
5+
* there is trigger listening for this and that would cause double events.
6+
*
7+
* @param commonId - The ID of the common to whitelist
8+
*/
9+
export const whitelistCommon = async (commonId: string): Promise<void> => {
10+
// Find the common
11+
const common = await commonDb.get(commonId);
12+
13+
// Change the state of whitelisting
14+
common.register = 'registered';
15+
16+
// Save the changes
17+
await commonDb.update(common);
18+
}

packages/firebase/functions/src/core/graph/schema/commons/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { CommonOpenFundingRequestsExtension } from './extensions/CommonOpenFundi
1212
import { GetCommonQuery } from './queries/GetCommon.query';
1313
import { GetCommonsQuery } from './queries/GetCommons.query';
1414

15+
import { WhitelistCommonMutation } from './mutations/whitelistCommon.mutation';
1516
import { RefreshCommonMembersMutation } from './mutations/refreshCommonMembers.mutation';
1617

1718
export const CommonTypes = [
@@ -29,5 +30,6 @@ export const CommonTypes = [
2930
GetCommonQuery,
3031
GetCommonsQuery,
3132

33+
WhitelistCommonMutation,
3234
RefreshCommonMembersMutation
3335
]

0 commit comments

Comments
 (0)