diff --git a/packages/web/components/templates/settings/SettingsTable.tsx b/packages/web/components/templates/settings/SettingsTable.tsx
index 91b367e14..a71e290d1 100644
--- a/packages/web/components/templates/settings/SettingsTable.tsx
+++ b/packages/web/components/templates/settings/SettingsTable.tsx
@@ -1,4 +1,4 @@
-import { Trash } from 'phosphor-react'
+import { Pencil, Trash } from 'phosphor-react'
import { Toaster } from 'react-hot-toast'
import { Button } from '../../elements/Button'
import { Dropdown, DropdownOption } from '../../elements/DropdownElements'
@@ -26,7 +26,7 @@ type CreateButtonProps = {
}
type SettingsTableRowProps = {
- title: string
+ title: string | JSX.Element
isLast: boolean
onClick?: () => void
@@ -39,12 +39,17 @@ type SettingsTableRowProps = {
onDelete?: () => void
dropdownItems?: JSX.Element
+
+ editTitle?: string
+ onEdit?: () => void
}
type MoreOptionsProps = {
- title?: string
+ deleteTitle?: string
onDelete?: () => void
dropdownItems?: JSX.Element
+ editTitle?: string
+ onEdit?: () => void
}
const MoreOptions = (props: MoreOptionsProps) => (
@@ -66,7 +71,33 @@ const MoreOptions = (props: MoreOptionsProps) => (
}
>
- {props.onDelete && props.title && (
+ {props.onEdit && props.editTitle && (
+ {
+ props.onEdit && props.onEdit()
+ }}
+ >
+
+
+
+ {props.editTitle}
+
+
+
+ )}
+
+ {props.onDelete && props.deleteTitle && (
{
props.onDelete && props.onDelete()
@@ -86,7 +117,7 @@ const MoreOptions = (props: MoreOptionsProps) => (
},
}}
>
- {props.title}
+ {props.deleteTitle}
@@ -192,9 +223,11 @@ export const SettingsTableRow = (props: SettingsTableRowProps): JSX.Element => {
}}
>
@@ -211,9 +244,11 @@ export const SettingsTableRow = (props: SettingsTableRowProps): JSX.Element => {
}}
>
diff --git a/packages/web/lib/networking/mutations/updateSubscriptionMutation.ts b/packages/web/lib/networking/mutations/updateSubscriptionMutation.ts
new file mode 100644
index 000000000..a3f4e20e6
--- /dev/null
+++ b/packages/web/lib/networking/mutations/updateSubscriptionMutation.ts
@@ -0,0 +1,51 @@
+import { gql } from 'graphql-request'
+import { gqlFetcher } from '../networkHelpers'
+import { Subscription } from '../queries/useGetSubscriptionsQuery'
+
+interface UpdateSubscriptionResult {
+ updateSubscription: UpdateSubscription
+}
+
+interface UpdateSubscription {
+ subscription: Subscription
+ errorCodes?: unknown[]
+}
+
+interface UpdateSubscriptionInput {
+ id: string
+ lastFetchedAt?: Date
+ name?: string
+ description?: string
+}
+
+export async function updateSubscriptionMutation(
+ input: UpdateSubscriptionInput
+): Promise {
+ const mutation = gql`
+ mutation UpdateSubscription($input: UpdateSubscriptionInput!) {
+ updateSubscription(input: $input) {
+ ... on UpdateSubscriptionSuccess {
+ subscription {
+ id
+ lastFetchedAt
+ }
+ }
+ ... on UpdateSubscriptionError {
+ errorCodes
+ }
+ }
+ }
+ `
+
+ try {
+ const data = (await gqlFetcher(mutation, {
+ input,
+ })) as UpdateSubscriptionResult
+ return data.updateSubscription.errorCodes
+ ? undefined
+ : data.updateSubscription.subscription.id
+ } catch (error) {
+ console.log('updateSubscriptionMutation error', error)
+ return undefined
+ }
+}
diff --git a/packages/web/pages/settings/rss/index.tsx b/packages/web/pages/settings/rss/index.tsx
index c7113f2c4..17ddb78d9 100644
--- a/packages/web/pages/settings/rss/index.tsx
+++ b/packages/web/pages/settings/rss/index.tsx
@@ -1,5 +1,8 @@
import { useRouter } from 'next/router'
+import { FloppyDisk, Pencil, XCircle } from 'phosphor-react'
import { useState } from 'react'
+import { FormInput } from '../../../components/elements/FormElements'
+import { HStack } from '../../../components/elements/LayoutPrimitives'
import { StyledText } from '../../../components/elements/StyledText'
import { ConfirmationModal } from '../../../components/patterns/ConfirmationModal'
import {
@@ -7,8 +10,10 @@ import {
SettingsTable,
SettingsTableRow,
} from '../../../components/templates/settings/SettingsTable'
+import { theme } from '../../../components/tokens/stitches.config'
import { formattedShortTime } from '../../../lib/dateFormatting'
import { unsubscribeMutation } from '../../../lib/networking/mutations/unsubscribeMutation'
+import { updateSubscriptionMutation } from '../../../lib/networking/mutations/updateSubscriptionMutation'
import {
SubscriptionType,
useGetSubscriptionsQuery,
@@ -22,6 +27,22 @@ export default function Rss(): JSX.Element {
SubscriptionType.RSS
)
const [onDeleteId, setOnDeleteId] = useState('')
+ const [onEditId, setOnEditId] = useState('')
+ const [name, setName] = useState('')
+
+ async function updateSubscription(): Promise {
+ const result = await updateSubscriptionMutation({
+ id: onEditId,
+ name,
+ })
+ if (result) {
+ showSuccessToast('RSS feed updated', { position: 'bottom-right' })
+ } else {
+ showErrorToast('Failed to update', { position: 'bottom-right' })
+ }
+
+ revalidate()
+ }
async function onDelete(id: string): Promise {
const result = await unsubscribeMutation('', id)
@@ -54,7 +75,56 @@ export default function Rss(): JSX.Element {
return (
+ e.stopPropagation()}
+ onChange={(e) => setName(e.target.value)}
+ placeholder="Description"
+ disabled={!onEditId}
+ />
+ {onEditId ? (
+
+ {
+ e.stopPropagation()
+ await updateSubscription()
+ setOnEditId('')
+ }}
+ >
+ Save
+
+ {
+ e.stopPropagation()
+ setOnEditId('')
+ }}
+ >
+ Cancel
+
+
+ ) : (
+ {
+ e.stopPropagation()
+ setName(subscription.name)
+ setOnEditId(subscription.id)
+ }}
+ />
+ )}
+
+ }
isLast={i === subscriptions.length - 1}
onDelete={() => {
console.log('onDelete triggered: ', subscription.id)
@@ -64,11 +134,8 @@ export default function Rss(): JSX.Element {
sublineElement={
{`URL: ${subscription.url}, `}
@@ -79,6 +146,9 @@ export default function Rss(): JSX.Element {
}`}
}
+ onClick={() => {
+ router.push(`/home?q=rss:"${subscription.url}"`)
+ }}
/>
)
})