Skip to content

Commit

Permalink
refactor(core): Remove Invitation and replace it with InvitationNext …
Browse files Browse the repository at this point in the history
…(renamed) (#1356)

* refactor(core): Remove Invitation and replace it with InvitationNext (renamed)

* refactor(ui, webserver): remove invitationNext

---------

Co-authored-by: liangfung <[email protected]>
  • Loading branch information
boxbeam and liangfung authored Feb 5, 2024
1 parent 9b8856e commit 2fbabbe
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import CreateInvitationForm from './create-invitation-form'

const deleteInvitationMutation = graphql(/* GraphQL */ `
mutation DeleteInvitation($id: ID!) {
deleteInvitationNext(id: $id)
deleteInvitation(id: $id)
}
`)

Expand All @@ -50,8 +50,8 @@ export default function InvitationTable() {
const [fetchingLastPage, setFetchingLastPage] = React.useState(false)

const [currentPage, setCurrentPage] = React.useState(1)
const edges = data?.invitationsNext?.edges
const pageInfo = data?.invitationsNext?.pageInfo
const edges = data?.invitations?.edges
const pageInfo = data?.invitations?.pageInfo
const pageNum = Math.ceil((edges?.length || 0) / PAGE_SIZE)

const currentPageInvits = React.useMemo(() => {
Expand All @@ -72,8 +72,8 @@ export default function InvitationTable() {
cursor?: string
): Promise<number> => {
const res = await fetchInvitations({ first: PAGE_SIZE, after: cursor })
let count = res?.data?.invitationsNext?.edges?.length || 0
const _pageInfo = res?.data?.invitationsNext?.pageInfo
let count = res?.data?.invitations?.edges?.length || 0
const _pageInfo = res?.data?.invitations?.pageInfo
if (_pageInfo?.hasNextPage && _pageInfo?.endCursor) {
// cacheExchange will merge the edges
count = await fetchInvitationsSequentially(_pageInfo.endCursor)
Expand Down Expand Up @@ -121,7 +121,7 @@ export default function InvitationTable() {

fetchInvitations({ first: PAGE_SIZE, after: pageInfo?.endCursor }).then(
data => {
if (data?.data?.invitationsNext?.edges?.length) {
if (data?.data?.invitations?.edges?.length) {
setCurrentPage(p => p + 1)
}
}
Expand All @@ -134,7 +134,7 @@ export default function InvitationTable() {
toast.error(res.error.message)
return
}
if (res?.data?.deleteInvitationNext) {
if (res?.data?.deleteInvitation) {
toast.success(`${node.email} deleted`)
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { toast } from 'sonner'
import { useQuery } from 'urql'

import { graphql } from '@/lib/gql/generates'
import type { ListUsersNextQuery } from '@/lib/gql/generates/graphql'
import type { ListUsersQuery } from '@/lib/gql/generates/graphql'
import { QueryVariables, useMutation } from '@/lib/tabby/gql'
import type { ArrayElementType } from '@/lib/types'
import { Badge } from '@/components/ui/badge'
Expand Down Expand Up @@ -35,13 +35,8 @@ import {
} from '@/components/ui/table'

const listUsers = graphql(/* GraphQL */ `
query ListUsersNext(
$after: String
$before: String
$first: Int
$last: Int
) {
usersNext(after: $after, before: $before, first: $first, last: $last) {
query ListUsers($after: String, $before: String, $first: Int, $last: Int) {
users(after: $after, before: $before, first: $first, last: $last) {
edges {
node {
id
Expand Down Expand Up @@ -77,10 +72,10 @@ export default function UsersTable() {
query: listUsers,
variables: queryVariables
})
const [users, setUsers] = React.useState<ListUsersNextQuery['usersNext']>()
const [users, setUsers] = React.useState<ListUsersQuery['users']>()

React.useEffect(() => {
const _users = data?.usersNext
const _users = data?.users
if (_users?.edges?.length) {
setUsers(_users)
}
Expand All @@ -95,7 +90,7 @@ export default function UsersTable() {
const updateUserActive = useMutation(updateUserActiveMutation)

const onUpdateUserActive = (
node: ArrayElementType<ListUsersNextQuery['usersNext']['edges']>['node'],
node: ArrayElementType<ListUsersQuery['users']['edges']>['node'],
active: boolean
) => {
updateUserActive({ id: node.id, active }).then(response => {
Expand Down
17 changes: 8 additions & 9 deletions ee/tabby-ui/lib/tabby/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,16 @@ const client = new Client({
cacheExchange({
resolvers: {
Query: {
invitationsNext: relayPagination()
invitations: relayPagination()
}
},
updates: {
Mutation: {
deleteInvitationNext(result, args, cache, info) {
if (result.deleteInvitationNext) {
deleteInvitation(result, args, cache, info) {
if (result.deleteInvitation) {
cache
.inspectFields('Query')
.filter(field => field.fieldName === 'invitationsNext')
.filter(field => field.fieldName === 'invitations')
.forEach(field => {
cache.updateQuery(
{
Expand All @@ -113,11 +113,10 @@ const client = new Client({
field.arguments as ListInvitationsQueryVariables
},
data => {
if (data?.invitationsNext?.edges) {
data.invitationsNext.edges =
data.invitationsNext.edges.filter(
e => e.node.id !== args.id
)
if (data?.invitations?.edges) {
data.invitations.edges = data.invitations.edges.filter(
e => e.node.id !== args.id
)
}
return data
}
Expand Down
7 changes: 1 addition & 6 deletions ee/tabby-ui/lib/tabby/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ export const listInvitations = graphql(/* GraphQL */ `
$first: Int
$last: Int
) {
invitationsNext(
after: $after
before: $before
first: $first
last: $last
) {
invitations(after: $after, before: $before, first: $first, last: $last) {
edges {
node {
id
Expand Down
22 changes: 7 additions & 15 deletions ee/tabby-webserver/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ type Mutation {
verifyToken(token: String!): VerifyTokenResponse!
refreshToken(refreshToken: String!): RefreshTokenResponse!
createInvitation(email: String!): ID!
deleteInvitation(id: Int!): Int! @deprecated
createRepository(name: String!, gitUrl: String!): ID!
deleteRepository(id: ID!): Boolean!
updateRepository(id: ID!, name: String!, gitUrl: String!): Boolean!
deleteInvitationNext(id: ID!): ID!
deleteInvitation(id: ID!): ID!
updateOauthCredential(provider: OAuthProvider!, clientId: String!, clientSecret: String!, redirectUri: String): Boolean!
updateEmailSetting(smtpUsername: String!, smtpPassword: String, smtpServer: String!): Boolean!
deleteEmailSetting: Boolean!
Expand Down Expand Up @@ -55,11 +54,9 @@ type Query {
workers: [Worker!]!
registrationToken: String!
isAdminInitialized: Boolean!
invitations: [Invitation!]! @deprecated
me: User!
users: [User!]! @deprecated
usersNext(after: String, before: String, first: Int, last: Int): UserConnection!
invitationsNext(after: String, before: String, first: Int, last: Int): InvitationConnection!
users(after: String, before: String, first: Int, last: Int): UserConnection!
invitations(after: String, before: String, first: Int, last: Int): InvitationConnection!
jobRuns(after: String, before: String, first: Int, last: Int): JobRunConnection!
emailSetting: EmailSetting
repositories(after: String, before: String, first: Int, last: Int): RepositoryConnection!
Expand Down Expand Up @@ -92,13 +89,6 @@ type RepositoryConnection {
pageInfo: PageInfo!
}

type InvitationNext {
id: ID!
email: String!
code: String!
createdAt: String!
}

type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
Expand All @@ -107,6 +97,8 @@ type UserConnection {
type OAuthCredential {
provider: OAuthProvider!
clientId: String!
"Won't be passed to client side."
clientSecret: String
redirectUri: String
createdAt: DateTimeUtc!
updatedAt: DateTimeUtc!
Expand All @@ -117,7 +109,7 @@ type VerifyTokenResponse {
}

type Invitation {
id: Int!
id: ID!
email: String!
code: String!
createdAt: String!
Expand Down Expand Up @@ -154,7 +146,7 @@ type Worker {
}

type InvitationEdge {
node: InvitationNext!
node: Invitation!
cursor: String!
}

Expand Down
27 changes: 3 additions & 24 deletions ee/tabby-webserver/src/schema/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,38 +296,17 @@ impl relay::NodeType for User {
}
}

#[deprecated]
#[derive(Debug, Default, Serialize, Deserialize, GraphQLObject)]
pub struct Invitation {
pub id: i32,
pub email: String,
pub code: String,

pub created_at: String,
}

impl From<InvitationNext> for Invitation {
fn from(value: InvitationNext) -> Self {
Self {
id: value.id.parse::<i32>().unwrap(),
email: value.email,
code: value.code,
created_at: value.created_at,
}
}
}

#[derive(Debug, Serialize, Deserialize, GraphQLObject)]
#[graphql(context = Context)]
pub struct InvitationNext {
pub struct Invitation {
pub id: juniper::ID,
pub email: String,
pub code: String,

pub created_at: String,
}

impl relay::NodeType for InvitationNext {
impl relay::NodeType for Invitation {
type Cursor = String;

fn cursor(&self) -> Self::Cursor {
Expand Down Expand Up @@ -406,7 +385,7 @@ pub trait AuthenticationService: Send + Sync {
before: Option<String>,
first: Option<usize>,
last: Option<usize>,
) -> Result<Vec<InvitationNext>>;
) -> Result<Vec<Invitation>>;

async fn oauth(
&self,
Expand Down
2 changes: 1 addition & 1 deletion ee/tabby-webserver/src/schema/dao.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::schema::{
job,
};

impl From<InvitationDAO> for auth::InvitationNext {
impl From<InvitationDAO> for auth::Invitation {
fn from(val: InvitationDAO) -> Self {
Self {
id: juniper::ID::new(val.id.to_string()),
Expand Down
63 changes: 6 additions & 57 deletions ee/tabby-webserver/src/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ pub mod worker;
use std::{num::ParseIntError, sync::Arc};

use auth::{
validate_jwt, AuthenticationService, Invitation, InvitationNext, RefreshTokenError,
RefreshTokenResponse, RegisterError, RegisterResponse, TokenAuthError, TokenAuthResponse, User,
VerifyTokenResponse,
validate_jwt, AuthenticationService, Invitation, RefreshTokenError, RefreshTokenResponse,
RegisterError, RegisterResponse, TokenAuthError, TokenAuthResponse, User, VerifyTokenResponse,
};
use job::{JobRun, JobService};
use juniper::{
Expand Down Expand Up @@ -118,25 +117,6 @@ impl Query {
Ok(ctx.locator.auth().is_admin_initialized().await?)
}

#[deprecated]
async fn invitations(ctx: &Context) -> Result<Vec<Invitation>> {
if let Some(claims) = &ctx.claims {
if claims.is_admin {
return Ok(ctx
.locator
.auth()
.list_invitations(None, None, None, None)
.await?
.into_iter()
.map(|x| x.into())
.collect());
}
}
Err(CoreError::Unauthorized(
"Only admin is able to query invitations",
))
}

async fn me(ctx: &Context) -> Result<User> {
if let Some(claims) = &ctx.claims {
let user = ctx.locator.auth().get_user_by_email(&claims.sub).await?;
Expand All @@ -146,21 +126,7 @@ impl Query {
}
}

#[deprecated]
async fn users(ctx: &Context) -> Result<Vec<User>> {
if let Some(claims) = &ctx.claims {
if claims.is_admin {
return Ok(ctx
.locator
.auth()
.list_users(None, None, None, None)
.await?);
}
}
Err(CoreError::Unauthorized("Only admin is able to query users"))
}

async fn users_next(
async fn users(
ctx: &Context,
after: Option<String>,
before: Option<String>,
Expand Down Expand Up @@ -194,13 +160,13 @@ impl Query {
)))
}

async fn invitations_next(
async fn invitations(
ctx: &Context,
after: Option<String>,
before: Option<String>,
first: Option<i32>,
last: Option<i32>,
) -> FieldResult<Connection<InvitationNext>> {
) -> FieldResult<Connection<Invitation>> {
if let Some(claims) = &ctx.claims {
if claims.is_admin {
return relay::query_async(
Expand Down Expand Up @@ -397,23 +363,6 @@ impl Mutation {
Ok(ID::new(invitation.id.to_string()))
}

#[deprecated]
async fn delete_invitation(ctx: &Context, id: i32) -> Result<i32> {
if let Some(claims) = &ctx.claims {
if claims.is_admin {
let id = ctx
.locator
.auth()
.delete_invitation(ID::new(id.to_string()))
.await?;
return Ok(id.parse::<i32>().unwrap());
}
}
Err(CoreError::Unauthorized(
"Only admin is able to delete invitation",
))
}

async fn create_repository(
ctx: &Context,
name: String,
Expand Down Expand Up @@ -442,7 +391,7 @@ impl Mutation {
.await?)
}

async fn delete_invitation_next(ctx: &Context, id: ID) -> Result<ID> {
async fn delete_invitation(ctx: &Context, id: ID) -> Result<ID> {
if let Some(claims) = &ctx.claims {
if claims.is_admin {
return Ok(ctx.locator.auth().delete_invitation(id).await?);
Expand Down
Loading

0 comments on commit 2fbabbe

Please sign in to comment.