diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 10f526f..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index e48b940..3aade5b 100644 --- a/.gitignore +++ b/.gitignore @@ -129,5 +129,16 @@ dist .yarn/install-state.gz .pnp.* -# vscode extension file +# vscode extension file *.vsix + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/schema.gql b/schema.gql index 4fee0c0..633ef8a 100644 --- a/schema.gql +++ b/schema.gql @@ -13,6 +13,7 @@ Indicates that an Input Object is a OneOf Input Object (and thus requires directive @oneOf on INPUT_OBJECT enum Action { + ACCEPT_EVENT_INVITE ADD_COMPETITION_MEMBER ADD_EVENT_COMPETITION ADD_EVENT_MEMBER @@ -43,6 +44,7 @@ enum Action { FETCH_WEBSITE_METADATA JOIN_COMPETITION JOIN_EVENT + MANAGE_EVENT_INVITE_CODE PUBLISH_VOTE READ_ACTIVITY_TRACKER READ_COMMENT @@ -75,6 +77,7 @@ enum Action { UPDATE_AGENDA UPDATE_COMMENT UPDATE_COMPETITION + UPDATE_COMPETITION_ACCESS UPDATE_EVENT UPDATE_FORUM UPDATE_ORGANIZATION @@ -150,6 +153,16 @@ enum Badge { PARIS_2024_HACKERS """BIG Quantum Hackathon Sports Edition by QuantX & Aqora, May 2024, Paris (FR)""" PARIS_2024_WINNERS + """Hackathon Trailblazer - 3rd Place Team - Q2B Silicon Valley 2024""" + Q2B2024_BRONZE + """Hackathon Champion - Q2B Silicon Valley 2024""" + Q2B2024_GOLD + """On-Site Participant - Q2B Hackathon 2024""" + Q2B2024_ONSITE + """Global Participant - Q2B Hackathon 2024""" + Q2B2024_REMOTE + """Hackathon Innovator - 2nd Place Team - Q2B Silicon Valley 2024""" + Q2B2024_SILVER """Badge awarded upon first submission""" QUANTUM_PIONEER TEST @@ -196,6 +209,7 @@ type Competition implements ForumOwner & Node { description: String entityRuleAgreements(after: String, before: String, entity: UsernameOrID, first: Int, last: Int, latest: Boolean): CompetitionRuleAgreementConnection! forum: Forum! + grantHostSubmissionAccess: Boolean! hasLeaderboard: Boolean! host: Entity! id: ID! @@ -332,6 +346,7 @@ input CreateCommentInput { input CreateCompetitionInput { banner: Upload description: String + grantHostSubmissionAccess: Boolean hasLeaderboard: Boolean requiresApproval: Boolean shortDescription: String! @@ -494,13 +509,17 @@ type Event implements ForumOwner & Node { forum: Forum! host: Entity! id: ID! + invitations(after: String, before: String, first: Int, last: Int): EventInvitationConnection! + invitationsCount: Int! + invite: EventInvite! isPrivate: Boolean! latestRule: EventRule! - members(after: String, before: String, first: Int, last: Int, userIsOrgMember: ID): EventMembershipConnection! + members(after: String, before: String, first: Int, last: Int): EventMembershipConnection! membership(entity: UsernameOrID): EventMembership rules(after: String, before: String, first: Int, last: Int): EventRuleConnection! shortDescription: String! slug: String! + teams(after: String, before: String, first: Int, last: Int): OrganizationConnection! thumbnail: Url title: String! viewerCan(action: Action!, asEntity: UsernameOrID): Boolean! @@ -548,6 +567,52 @@ type EventEdge { node: Event! } +type EventInvitation implements Node { + email: String! + event: Event! + id: ID! + organization: Organization + registeredAs: User + username: String +} + +type EventInvitationConnection { + """A list of edges.""" + edges: [EventInvitationEdge!]! + """A list of nodes.""" + nodes: [EventInvitation!]! + """Information to aid in pagination.""" + pageInfo: PageInfo! +} + +"""An edge in a connection.""" +type EventInvitationEdge { + """A cursor for use in pagination""" + cursor: String! + """The item at the end of the edge""" + node: EventInvitation! +} + +type EventInvite implements Node { + code: String + event: Event! + id: ID! + latestRuleText: String! + shortDescription: String! + thumbnail: Url + title: String! + viewerCan(action: Action!, asEntity: UsernameOrID): Boolean! +} + +input EventMemberInvite { + """Required email used to find registered members, or send invitation email otherwise.""" + email: String! + """Optional team name used to create teams for the event.""" + team: String + """Optional username used to send invitation email when the member has not registered yet.""" + username: String +} + type EventMembership implements Node { entity: Entity! event: Event! @@ -778,6 +843,7 @@ input LoginUserInput { } type Mutation { + acceptEventInvite(asEntity: UsernameOrID, code: String!, id: ID!): EventInvite! addCompetitionMember(competitionId: ID!, entityId: ID!): CompetitionMembershipEdge! addEventCompetition(competitionId: ID!, eventId: ID!): EventCompetitionEdge! addEventMember(entityId: ID!, eventId: ID!): EventMembershipEdge! @@ -809,7 +875,9 @@ type Mutation { deleteUser(id: ID!): ID! fetchWebsiteMetadata(url: Url!): WebsiteMetadata! finishUploadFile(input: FinishUploadFileInput!): FinishUploadFile! + generateEventInviteCode(id: ID!): EventInvite! initUploadFile(input: InitUploadFileInput!): InitUploadFile! + inviteEventMembers(eventId: ID!, invites: [EventMemberInvite!]!): Event! joinCompetition(asEntity: UsernameOrID, competitionId: ID!): CompetitionMembershipEdge! joinEvent(asEntity: UsernameOrID, eventId: ID!): EventMembershipEdge! loginUser(input: LoginUserInput!): UserEdge! @@ -820,6 +888,7 @@ type Mutation { publishVote(id: ID!, kind: VoteKind!): VotableEdge! removeCompetitionMember(id: ID!): ID! removeEventCompetition(id: ID!): ID! + removeEventInviteCode(id: ID!): EventInvite! removeEventMember(id: ID!): ID! removeOrganizationMember(id: ID!): ID! resetPassword(input: ResetPasswordInput!): Boolean! @@ -868,6 +937,7 @@ enum NotificationKind { CONTENT_MENTIONED CREATE_SUBMISSION CREATE_TOPIC + PROMOTIONAL_NEWSLETTER REPLY_COMMENT REPLY_TOPIC } @@ -932,6 +1002,15 @@ type Organization implements Entity & Node { website: String } +type OrganizationConnection { + """A list of edges.""" + edges: [OrganizationEdge!]! + """A list of nodes.""" + nodes: [Organization!]! + """Information to aid in pagination.""" + pageInfo: PageInfo! +} + """An edge in a connection.""" type OrganizationEdge { """A cursor for use in pagination""" @@ -1157,6 +1236,7 @@ input SignupUserInput { linkedin: String location: String password: String! + subscribePromotionalNewsletter: Boolean username: String! website: Url } @@ -1325,6 +1405,7 @@ input UpdateCommentInput { input UpdateCompetitionInput { banner: Upload description: String + grantHostSubmissionAccess: Boolean hasLeaderboard: Boolean requiresApproval: Boolean rules: String diff --git a/src/graphql/graphql.ts b/src/graphql/graphql.ts index 5416894..3486b3a 100644 --- a/src/graphql/graphql.ts +++ b/src/graphql/graphql.ts @@ -51,6 +51,7 @@ export type Scalars = { }; export type Action = + | 'ACCEPT_EVENT_INVITE' | 'ADD_COMPETITION_MEMBER' | 'ADD_EVENT_COMPETITION' | 'ADD_EVENT_MEMBER' @@ -81,6 +82,7 @@ export type Action = | 'FETCH_WEBSITE_METADATA' | 'JOIN_COMPETITION' | 'JOIN_EVENT' + | 'MANAGE_EVENT_INVITE_CODE' | 'PUBLISH_VOTE' | 'READ_ACTIVITY_TRACKER' | 'READ_COMMENT' @@ -113,6 +115,7 @@ export type Action = | 'UPDATE_AGENDA' | 'UPDATE_COMMENT' | 'UPDATE_COMPETITION' + | 'UPDATE_COMPETITION_ACCESS' | 'UPDATE_EVENT' | 'UPDATE_FORUM' | 'UPDATE_ORGANIZATION' @@ -191,6 +194,16 @@ export type Badge = | 'PARIS_2024_HACKERS' /** BIG Quantum Hackathon Sports Edition by QuantX & Aqora, May 2024, Paris (FR) */ | 'PARIS_2024_WINNERS' + /** Hackathon Trailblazer - 3rd Place Team - Q2B Silicon Valley 2024 */ + | 'Q2B2024_BRONZE' + /** Hackathon Champion - Q2B Silicon Valley 2024 */ + | 'Q2B2024_GOLD' + /** On-Site Participant - Q2B Hackathon 2024 */ + | 'Q2B2024_ONSITE' + /** Global Participant - Q2B Hackathon 2024 */ + | 'Q2B2024_REMOTE' + /** Hackathon Innovator - 2nd Place Team - Q2B Silicon Valley 2024 */ + | 'Q2B2024_SILVER' /** Badge awarded upon first submission */ | 'QUANTUM_PIONEER' | 'TEST' @@ -256,6 +269,7 @@ export type Competition = ForumOwner & Node & { description: Maybe; entityRuleAgreements: CompetitionRuleAgreementConnection; forum: Forum; + grantHostSubmissionAccess: Scalars['Boolean']['output']; hasLeaderboard: Scalars['Boolean']['output']; host: Entity; id: Scalars['ID']['output']; @@ -492,6 +506,7 @@ export type CreateCommentInput = { export type CreateCompetitionInput = { banner: InputMaybe; description: InputMaybe; + grantHostSubmissionAccess: InputMaybe; hasLeaderboard: InputMaybe; requiresApproval: InputMaybe; shortDescription: Scalars['String']['input']; @@ -697,6 +712,9 @@ export type Event = ForumOwner & Node & { forum: Forum; host: Entity; id: Scalars['ID']['output']; + invitations: EventInvitationConnection; + invitationsCount: Scalars['Int']['output']; + invite: EventInvite; isPrivate: Scalars['Boolean']['output']; latestRule: EventRule; members: EventMembershipConnection; @@ -704,6 +722,7 @@ export type Event = ForumOwner & Node & { rules: EventRuleConnection; shortDescription: Scalars['String']['output']; slug: Scalars['String']['output']; + teams: OrganizationConnection; thumbnail: Maybe; title: Scalars['String']['output']; viewerCan: Scalars['Boolean']['output']; @@ -729,12 +748,19 @@ export type EventEntityRuleAgreementsArgs = { }; +export type EventInvitationsArgs = { + after: InputMaybe; + before: InputMaybe; + first: InputMaybe; + last: InputMaybe; +}; + + export type EventMembersArgs = { after: InputMaybe; before: InputMaybe; first: InputMaybe; last: InputMaybe; - userIsOrgMember: InputMaybe; }; @@ -751,6 +777,14 @@ export type EventRulesArgs = { }; +export type EventTeamsArgs = { + after: InputMaybe; + before: InputMaybe; + first: InputMaybe; + last: InputMaybe; +}; + + export type EventViewerCanArgs = { action: Action; asEntity: InputMaybe; @@ -808,6 +842,62 @@ export type EventEdge = { node: Event; }; +export type EventInvitation = Node & { + __typename?: 'EventInvitation'; + email: Scalars['String']['output']; + event: Event; + id: Scalars['ID']['output']; + organization: Maybe; + registeredAs: Maybe; + username: Maybe; +}; + +export type EventInvitationConnection = { + __typename?: 'EventInvitationConnection'; + /** A list of edges. */ + edges: Array; + /** A list of nodes. */ + nodes: Array; + /** Information to aid in pagination. */ + pageInfo: PageInfo; +}; + +/** An edge in a connection. */ +export type EventInvitationEdge = { + __typename?: 'EventInvitationEdge'; + /** A cursor for use in pagination */ + cursor: Scalars['String']['output']; + /** The item at the end of the edge */ + node: EventInvitation; +}; + +export type EventInvite = Node & { + __typename?: 'EventInvite'; + code: Maybe; + event: Event; + id: Scalars['ID']['output']; + latestRuleText: Scalars['String']['output']; + shortDescription: Scalars['String']['output']; + thumbnail: Maybe; + title: Scalars['String']['output']; + viewerCan: Scalars['Boolean']['output']; +}; + + +export type EventInviteViewerCanArgs = { + action: Action; + asEntity: InputMaybe; +}; + +export type EventMemberInvite = { + /** Required email used to find registered members, or send invitation email otherwise. */ + email: Scalars['String']['input']; + /** Optional team name used to create teams for the event. */ + team: InputMaybe; + /** Optional username used to send invitation email when the member has not registered yet. */ + username: InputMaybe; +}; + export type EventMembership = Node & { __typename?: 'EventMembership'; entity: Entity; @@ -1122,6 +1212,7 @@ export type LoginUserInput = { export type Mutation = { __typename?: 'Mutation'; + acceptEventInvite: EventInvite; addCompetitionMember: CompetitionMembershipEdge; addEventCompetition: EventCompetitionEdge; addEventMember: EventMembershipEdge; @@ -1153,7 +1244,9 @@ export type Mutation = { deleteUser: Scalars['ID']['output']; fetchWebsiteMetadata: WebsiteMetadata; finishUploadFile: FinishUploadFile; + generateEventInviteCode: EventInvite; initUploadFile: InitUploadFile; + inviteEventMembers: Event; joinCompetition: CompetitionMembershipEdge; joinEvent: EventMembershipEdge; loginUser: UserEdge; @@ -1164,6 +1257,7 @@ export type Mutation = { publishVote: VotableEdge; removeCompetitionMember: Scalars['ID']['output']; removeEventCompetition: Scalars['ID']['output']; + removeEventInviteCode: EventInvite; removeEventMember: Scalars['ID']['output']; removeOrganizationMember: Scalars['ID']['output']; resetPassword: Scalars['Boolean']['output']; @@ -1193,6 +1287,13 @@ export type Mutation = { }; +export type MutationAcceptEventInviteArgs = { + asEntity: InputMaybe; + code: Scalars['String']['input']; + id: Scalars['ID']['input']; +}; + + export type MutationAddCompetitionMemberArgs = { competitionId: Scalars['ID']['input']; entityId: Scalars['ID']['input']; @@ -1365,11 +1466,22 @@ export type MutationFinishUploadFileArgs = { }; +export type MutationGenerateEventInviteCodeArgs = { + id: Scalars['ID']['input']; +}; + + export type MutationInitUploadFileArgs = { input: InitUploadFileInput; }; +export type MutationInviteEventMembersArgs = { + eventId: Scalars['ID']['input']; + invites: Array; +}; + + export type MutationJoinCompetitionArgs = { asEntity: InputMaybe; competitionId: Scalars['ID']['input']; @@ -1418,6 +1530,11 @@ export type MutationRemoveEventCompetitionArgs = { }; +export type MutationRemoveEventInviteCodeArgs = { + id: Scalars['ID']['input']; +}; + + export type MutationRemoveEventMemberArgs = { id: Scalars['ID']['input']; }; @@ -1567,6 +1684,7 @@ export type NotificationKind = | 'CONTENT_MENTIONED' | 'CREATE_SUBMISSION' | 'CREATE_TOPIC' + | 'PROMOTIONAL_NEWSLETTER' | 'REPLY_COMMENT' | 'REPLY_TOPIC' | '%future added value'; @@ -1689,6 +1807,16 @@ export type OrganizationViewerCanArgs = { asEntity: InputMaybe; }; +export type OrganizationConnection = { + __typename?: 'OrganizationConnection'; + /** A list of edges. */ + edges: Array; + /** A list of nodes. */ + nodes: Array; + /** Information to aid in pagination. */ + pageInfo: PageInfo; +}; + /** An edge in a connection. */ export type OrganizationEdge = { __typename?: 'OrganizationEdge'; @@ -2080,6 +2208,7 @@ export type SignupUserInput = { linkedin: InputMaybe; location: InputMaybe; password: Scalars['String']['input']; + subscribePromotionalNewsletter: InputMaybe; username: Scalars['String']['input']; website: InputMaybe; }; @@ -2345,6 +2474,7 @@ export type UpdateCommentInput = { export type UpdateCompetitionInput = { banner: InputMaybe; description: InputMaybe; + grantHostSubmissionAccess: InputMaybe; hasLeaderboard: InputMaybe; requiresApproval: InputMaybe; rules: InputMaybe; diff --git a/vsc-extension-quickstart.md b/vsc-extension-quickstart.md deleted file mode 100644 index f518bb8..0000000 --- a/vsc-extension-quickstart.md +++ /dev/null @@ -1,48 +0,0 @@ -# Welcome to your VS Code Extension - -## What's in the folder - -* This folder contains all of the files necessary for your extension. -* `package.json` - this is the manifest file in which you declare your extension and command. - * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. -* `src/extension.ts` - this is the main file where you will provide the implementation of your command. - * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. - * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. - -## Setup - -* install the recommended extensions (amodio.tsl-problem-matcher, ms-vscode.extension-test-runner, and dbaeumer.vscode-eslint) - - -## Get up and running straight away - -* Press `F5` to open a new window with your extension loaded. -* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. -* Set breakpoints in your code inside `src/extension.ts` to debug your extension. -* Find output from your extension in the debug console. - -## Make changes - -* You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. -* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. - - -## Explore the API - -* You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. - -## Run tests - -* Install the [Extension Test Runner](https://marketplace.visualstudio.com/items?itemName=ms-vscode.extension-test-runner) -* Run the "watch" task via the **Tasks: Run Task** command. Make sure this is running, or tests might not be discovered. -* Open the Testing view from the activity bar and click the Run Test" button, or use the hotkey `Ctrl/Cmd + ; A` -* See the output of the test result in the Test Results view. -* Make changes to `src/test/extension.test.ts` or create new test files inside the `test` folder. - * The provided test runner will only consider files matching the name pattern `**.test.ts`. - * You can create folders inside the `test` folder to structure your tests any way you want. - -## Go further - -* Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). -* [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace. -* Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).