Skip to content

Commit 60c6770

Browse files
authored
feat(tiles): revoke shareable link (#1237)
<img width="661" height="207" alt="image" src="https://github.com/user-attachments/assets/58200ef4-1bb9-4de3-a7b2-ce8cf11cbe62" />
1 parent acb3968 commit 60c6770

File tree

6 files changed

+72
-12
lines changed

6 files changed

+72
-12
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import TableCollaborator from '@/models/table-collaborators'
2+
import TableMetadata from '@/models/table-metadata'
3+
4+
import type { MutationResolvers } from '../../__generated__/types.generated'
5+
6+
const deleteShareableTableLink: MutationResolvers['deleteShareableTableLink'] =
7+
async (_parent, params, context) => {
8+
const tableId = params.tableId
9+
10+
await TableCollaborator.hasAccess(context.currentUser.id, tableId, 'editor')
11+
12+
const table = await TableMetadata.query()
13+
.findById(tableId)
14+
.throwIfNotFound()
15+
16+
await table.$query().patch({
17+
viewOnlyKey: null,
18+
})
19+
20+
return true
21+
}
22+
23+
export default deleteShareableTableLink

packages/backend/src/graphql/mutations/tiles/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import createShareableTableLink from './create-table-shareable-link'
77
import deleteRows from './delete-rows'
88
import deleteTable from './delete-table'
99
import deleteTableCollaborator from './delete-table-collaborator'
10+
import deleteShareableTableLink from './delete-table-shareable-link'
1011
import updateRow from './update-row'
1112
import updateTable from './update-table'
1213
import upsertTableCollaborator from './upsert-table-collaborator'
@@ -20,6 +21,7 @@ export default {
2021
updateRow,
2122
deleteRows,
2223
createShareableTableLink,
24+
deleteShareableTableLink,
2325
deleteTableCollaborator,
2426
upsertTableCollaborator,
2527
} satisfies MutationResolvers

packages/backend/src/graphql/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ type Mutation {
105105
# Tiles
106106
createTable(input: CreateTableInput!): TableMetadata!
107107
createShareableTableLink(tableId: ID!): String!
108+
deleteShareableTableLink(tableId: ID!): Boolean!
108109
updateTable(input: UpdateTableInput!): TableMetadata!
109110
deleteTable(input: DeleteTableInput!): Boolean!
110111
# Tiles rows

packages/backend/src/models/table-metadata.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class TableMetadata extends Base {
1111
name: string
1212
collaborators!: User[]
1313
columns: TableColumnMetadata[]
14-
viewOnlyKey?: string
14+
viewOnlyKey?: string | null
1515

1616
/**
1717
* for typescript support when creating TableCollaborator row in insertGraph
@@ -27,7 +27,7 @@ class TableMetadata extends Base {
2727
properties: {
2828
id: { type: 'string', format: 'uuid' },
2929
name: { type: 'string' },
30-
viewOnlyKey: { type: 'string' },
30+
viewOnlyKey: { type: ['string', 'null'] },
3131
},
3232
}
3333

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { graphql } from '@/graphql/__generated__'
2+
3+
export const DELETE_SHAREABLE_TABLE_LINK = graphql(`
4+
mutation DeleteShareableTableLink($tableId: ID!) {
5+
deleteShareableTableLink(tableId: $tableId)
6+
}
7+
`)

packages/frontend/src/pages/Tile/components/TableBanner/ShareLink.tsx

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useCallback, useState } from 'react'
2-
import { BiCopy } from 'react-icons/bi'
2+
import { BiCopy, BiTrash } from 'react-icons/bi'
33
import { useMutation } from '@apollo/client'
44
import {
55
Divider,
@@ -20,6 +20,7 @@ import copy from 'clipboard-copy'
2020

2121
import * as URLS from '@/config/urls'
2222
import { CREATE_SHAREABLE_TABLE_LINK } from '@/graphql/mutations/tiles/create-shareable-link'
23+
import { DELETE_SHAREABLE_TABLE_LINK } from '@/graphql/mutations/tiles/delete-shareable-link'
2324
import { GET_TABLE } from '@/graphql/queries/tiles/get-table'
2425

2526
import { useTableContext } from '../../contexts/TableContext'
@@ -42,16 +43,48 @@ const ShareLink = () => {
4243
},
4344
)
4445

46+
const [deleteLink, { loading: isDeleting }] = useMutation(
47+
DELETE_SHAREABLE_TABLE_LINK,
48+
{
49+
variables: { tableId },
50+
refetchQueries: [GET_TABLE],
51+
},
52+
)
53+
4554
const onGenerate = useCallback(async () => {
4655
await createNewLink()
4756
setIsNewLink(true)
4857
}, [createNewLink])
4958

59+
const onDelete = useCallback(async () => {
60+
await deleteLink()
61+
setIsNewLink(false)
62+
}, [deleteLink])
63+
5064
const inputBorderColor = isNewLink ? 'green.400' : 'secondary.200'
5165

5266
if (!viewOnlyKey && !hasEditPermission) {
5367
return null
5468
}
69+
70+
const renderButton = () => {
71+
if (viewOnlyKey) {
72+
return (
73+
<IconButton
74+
variant="outline"
75+
isLoading={isDeleting}
76+
onClick={onDelete}
77+
aria-label={'Revoke'}
78+
icon={<BiTrash />}
79+
/>
80+
)
81+
}
82+
return (
83+
<Button variant="outline" isLoading={loading} onClick={onGenerate}>
84+
Generate new link
85+
</Button>
86+
)
87+
}
5588
return (
5689
<FormControl>
5790
<VStack spacing={2} alignItems="flex-start">
@@ -88,17 +121,11 @@ const ShareLink = () => {
88121
</InputRightAddon>
89122
</InputGroup>
90123
)}
91-
{hasEditPermission && (
92-
<Button variant="outline" isLoading={loading} onClick={onGenerate}>
93-
Generate new link
94-
</Button>
95-
)}
124+
{hasEditPermission && renderButton()}
96125
</Flex>
97-
{viewOnlyKey && hasEditPermission && (
126+
{isNewLink && (
98127
<FormHelperText variant={isNewLink ? 'success' : undefined}>
99-
{isNewLink
100-
? 'New link generated!'
101-
: 'By generating a new link, your previous link will not work anymore.'}
128+
New link generated!
102129
</FormHelperText>
103130
)}
104131
</VStack>

0 commit comments

Comments
 (0)