This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

chore: remove optimistic card adding flag

+161 -267
+42 -73
src/webapp/features/cards/components/addCardDrawer/AddCardForm.tsx
··· 33 33 import { FaSeedling } from 'react-icons/fa6'; 34 34 import { CardSaveSource } from '@/features/analytics/types'; 35 35 import { usePathname } from 'next/navigation'; 36 - import { useFeatureFlags } from '@/lib/clientFeatureFlags'; 37 36 import { BsCheck, BsExclamation } from 'react-icons/bs'; 38 37 39 38 interface Props { ··· 44 43 45 44 export default function AddCardForm(props: Props) { 46 45 const pathname = usePathname(); 47 - const { data: featureFlags } = useFeatureFlags(); 48 46 const [collectionSelectorOpened, { toggle: toggleCollectionSelector }] = 49 47 useDisclosure(false); 50 48 const initialCollections = props.selectedCollection ··· 90 88 e.preventDefault(); 91 89 track('add new card'); 92 90 93 - const isOptimistic = featureFlags?.optimisticCardAdding ?? false; 94 - 95 91 // Capture values before any state changes 96 92 const cardData = { 97 93 url: form.getValues().url, ··· 99 95 collectionIds: selectedCollections.map((c) => c.id), 100 96 }; 101 97 102 - if (isOptimistic) { 103 - // Show loading toast immediately 104 - const notificationId = `add-card-${Date.now()}`; 105 - notifications.show({ 106 - id: notificationId, 107 - loading: true, 108 - title: 'Adding card...', 109 - message: 'Please wait', 110 - position: 'top-center', 111 - autoClose: false, 112 - withCloseButton: false, 113 - }); 98 + // Show loading toast immediately 99 + const notificationId = `add-card-${Date.now()}`; 100 + notifications.show({ 101 + id: notificationId, 102 + loading: true, 103 + title: 'Adding card...', 104 + message: 'Please wait', 105 + position: 'top-center', 106 + autoClose: false, 107 + withCloseButton: false, 108 + }); 114 109 115 - // Close drawer immediately 116 - props.onClose(); 117 - setSelectedCollections(initialCollections); 118 - window.history.replaceState({}, '', window.location.pathname); 119 - form.reset(); 110 + // Close drawer immediately 111 + props.onClose(); 112 + setSelectedCollections(initialCollections); 113 + form.reset(); 120 114 121 - addCard.mutate(cardData, { 122 - onSuccess: () => { 123 - notifications.update({ 124 - id: notificationId, 125 - color: 'green', 126 - title: 'Success!', 127 - message: 'Card added', 128 - position: 'top-center', 129 - loading: false, 130 - autoClose: 3000, 131 - icon: <BsCheck />, 132 - }); 133 - }, 134 - onError: () => { 135 - notifications.update({ 136 - id: notificationId, 137 - color: 'red', 138 - title: 'Error', 139 - message: 'Could not add card', 140 - position: 'top-center', 141 - loading: false, 142 - autoClose: 5000, 143 - withCloseButton: true, 144 - icon: <BsExclamation />, 145 - }); 146 - }, 147 - }); 148 - } else { 149 - // Original behavior: wait for response 150 - addCard.mutate(cardData, { 151 - onSuccess: () => { 152 - setSelectedCollections(initialCollections); 153 - props.onClose(); 154 - window.history.replaceState({}, '', window.location.pathname); 155 - }, 156 - onError: () => { 157 - notifications.show({ 158 - color: 'red', 159 - title: 'Error', 160 - message: 'Could not add card', 161 - loading: false, 162 - autoClose: 5000, 163 - withCloseButton: true, 164 - position: 'top-center', 165 - icon: <BsExclamation />, 166 - }); 167 - }, 168 - onSettled: () => { 169 - form.reset(); 170 - }, 171 - }); 172 - } 115 + addCard.mutate(cardData, { 116 + onSuccess: () => { 117 + notifications.update({ 118 + id: notificationId, 119 + color: 'green', 120 + title: 'Success!', 121 + message: 'Card added', 122 + position: 'top-center', 123 + loading: false, 124 + autoClose: 3000, 125 + icon: <BsCheck />, 126 + }); 127 + }, 128 + onError: () => { 129 + notifications.update({ 130 + id: notificationId, 131 + color: 'red', 132 + title: 'Error', 133 + message: 'Could not add card', 134 + position: 'top-center', 135 + loading: false, 136 + autoClose: 5000, 137 + withCloseButton: true, 138 + icon: <BsExclamation />, 139 + }); 140 + }, 141 + }); 173 142 }; 174 143 175 144 return (
+76 -120
src/webapp/features/cards/components/addCardToModal/AddCardToModal.tsx
··· 8 8 import { CardSaveAnalyticsContext } from '@/features/analytics/types'; 9 9 import useAddCard from '@/features/cards/lib/mutations/useAddCard'; 10 10 import useUpdateCardAssociations from '@/features/cards/lib/mutations/useUpdateCardAssociations'; 11 - import { useFeatureFlags } from '@/lib/clientFeatureFlags'; 12 11 import { notifications } from '@mantine/notifications'; 13 12 import { track } from '@vercel/analytics'; 14 13 import { BsCheck, BsExclamation } from 'react-icons/bs'; ··· 27 26 } 28 27 29 28 export default function AddCardToModal(props: Props) { 30 - const { data: featureFlags } = useFeatureFlags(); 31 29 const addCard = useAddCard(props.analyticsContext); 32 30 const updateCardAssociations = useUpdateCardAssociations( 33 31 props.analyticsContext, ··· 66 64 }) => { 67 65 track('add or update existing card'); 68 66 69 - const isOptimistic = featureFlags?.optimisticCardAdding ?? false; 70 - 71 67 if (data.isAddingNewCard && data.cardData) { 72 - if (isOptimistic) { 73 - const notificationId = `add-card-${Date.now()}`; 74 - notifications.show({ 75 - id: notificationId, 76 - loading: true, 77 - title: 'Adding card...', 78 - message: 'Please wait', 79 - position: 'top-center', 80 - autoClose: false, 81 - withCloseButton: false, 82 - }); 68 + const notificationId = `add-card-${Date.now()}`; 69 + notifications.show({ 70 + id: notificationId, 71 + loading: true, 72 + title: 'Adding card...', 73 + message: 'Please wait', 74 + position: 'top-center', 75 + autoClose: false, 76 + withCloseButton: false, 77 + }); 83 78 84 - props.onClose(); 79 + props.onClose(); 85 80 86 - addCard.mutate(data.cardData, { 87 - onSuccess: () => { 88 - notifications.update({ 89 - id: notificationId, 90 - color: 'green', 91 - title: 'Success!', 92 - message: 'Card added', 93 - position: 'top-center', 94 - loading: false, 95 - autoClose: 3000, 96 - icon: <BsCheck />, 97 - }); 98 - }, 99 - onError: () => { 100 - notifications.update({ 101 - id: notificationId, 102 - color: 'red', 103 - title: 'Error', 104 - message: 'Could not add card', 105 - loading: false, 106 - autoClose: 5000, 107 - withCloseButton: true, 108 - position: 'top-center', 109 - icon: <BsExclamation />, 110 - }); 111 - }, 112 - }); 113 - } else { 114 - addCard.mutate(data.cardData, { 115 - onError: () => { 116 - notifications.show({ 117 - color: 'red', 118 - title: 'Error', 119 - message: 'Could not add card', 120 - loading: false, 121 - autoClose: 5000, 122 - withCloseButton: true, 123 - position: 'top-center', 124 - icon: <BsExclamation />, 125 - }); 126 - }, 127 - onSettled: () => { 128 - props.onClose(); 129 - }, 130 - }); 131 - } 81 + addCard.mutate(data.cardData, { 82 + onSuccess: () => { 83 + notifications.update({ 84 + id: notificationId, 85 + color: 'green', 86 + title: 'Success!', 87 + message: 'Card added', 88 + position: 'top-center', 89 + loading: false, 90 + autoClose: 3000, 91 + icon: <BsCheck />, 92 + }); 93 + }, 94 + onError: () => { 95 + notifications.update({ 96 + id: notificationId, 97 + color: 'red', 98 + title: 'Error', 99 + message: 'Could not add card', 100 + loading: false, 101 + autoClose: 5000, 102 + withCloseButton: true, 103 + position: 'top-center', 104 + icon: <BsExclamation />, 105 + }); 106 + }, 107 + }); 132 108 } else if (!data.isAddingNewCard && data.updateData) { 133 - if (isOptimistic) { 134 - const notificationId = `update-card-${Date.now()}`; 135 - notifications.show({ 136 - id: notificationId, 137 - loading: true, 138 - title: 'Updating card...', 139 - message: 'Please wait', 140 - position: 'top-center', 141 - autoClose: false, 142 - withCloseButton: false, 143 - }); 109 + const notificationId = `update-card-${Date.now()}`; 110 + notifications.show({ 111 + id: notificationId, 112 + loading: true, 113 + title: 'Updating card...', 114 + message: 'Please wait', 115 + position: 'top-center', 116 + autoClose: false, 117 + withCloseButton: false, 118 + }); 144 119 145 - props.onClose(); 120 + props.onClose(); 146 121 147 - updateCardAssociations.mutate(data.updateData, { 148 - onSuccess: () => { 149 - notifications.update({ 150 - id: notificationId, 151 - color: 'green', 152 - title: 'Success!', 153 - message: 'Card updated', 154 - position: 'top-center', 155 - loading: false, 156 - autoClose: 3000, 157 - icon: <BsCheck />, 158 - }); 159 - }, 160 - onError: () => { 161 - notifications.update({ 162 - id: notificationId, 163 - color: 'red', 164 - title: 'Error', 165 - message: 'Could not update card', 166 - position: 'top-center', 167 - loading: false, 168 - autoClose: false, 169 - withCloseButton: true, 170 - icon: <BsExclamation />, 171 - }); 172 - }, 173 - }); 174 - } else { 175 - updateCardAssociations.mutate(data.updateData, { 176 - onError: () => { 177 - notifications.show({ 178 - color: 'red', 179 - title: 'Error', 180 - message: 'Could not update card', 181 - position: 'top-center', 182 - loading: false, 183 - autoClose: false, 184 - withCloseButton: true, 185 - icon: <BsExclamation />, 186 - }); 187 - }, 188 - onSettled: () => { 189 - props.onClose(); 190 - }, 191 - }); 192 - } 122 + updateCardAssociations.mutate(data.updateData, { 123 + onSuccess: () => { 124 + notifications.update({ 125 + id: notificationId, 126 + color: 'green', 127 + title: 'Success!', 128 + message: 'Card updated', 129 + position: 'top-center', 130 + loading: false, 131 + autoClose: 3000, 132 + icon: <BsCheck />, 133 + }); 134 + }, 135 + onError: () => { 136 + notifications.update({ 137 + id: notificationId, 138 + color: 'red', 139 + title: 'Error', 140 + message: 'Could not update card', 141 + position: 'top-center', 142 + loading: false, 143 + autoClose: false, 144 + withCloseButton: true, 145 + icon: <BsExclamation />, 146 + }); 147 + }, 148 + }); 193 149 } 194 150 }; 195 151
+43 -72
src/webapp/features/composer/components/Composer.tsx
··· 36 36 import { FaSeedling } from 'react-icons/fa6'; 37 37 import { CardSaveSource } from '@/features/analytics/types'; 38 38 import { usePathname } from 'next/navigation'; 39 - import { useFeatureFlags } from '@/lib/clientFeatureFlags'; 40 39 import { BsCheck, BsExclamation } from 'react-icons/bs'; 41 40 42 41 type ComposerMode = 'card' | 'collection'; ··· 54 53 55 54 export default function Composer(props: Props) { 56 55 const pathname = usePathname(); 57 - const { data: featureFlags } = useFeatureFlags(); 58 56 const [mode, setMode] = useState<ComposerMode>(props.initialMode ?? 'card'); 59 57 60 58 // Card form state ··· 129 127 e.preventDefault(); 130 128 track('add new card'); 131 129 132 - const isOptimistic = featureFlags?.optimisticCardAdding ?? false; 133 - 134 130 // Capture values before any state changes 135 131 const cardData = { 136 132 url: cardForm.getValues().url, ··· 138 134 collectionIds: selectedCollections.map((c) => c.id), 139 135 }; 140 136 141 - if (isOptimistic) { 142 - // Show loading toast immediately 143 - const notificationId = `add-card-${Date.now()}`; 144 - notifications.show({ 145 - id: notificationId, 146 - loading: true, 147 - title: 'Adding card...', 148 - message: 'Please wait', 149 - position: 'top-center', 150 - autoClose: false, 151 - withCloseButton: false, 152 - }); 137 + // Show loading toast immediately 138 + const notificationId = `add-card-${Date.now()}`; 139 + notifications.show({ 140 + id: notificationId, 141 + loading: true, 142 + title: 'Adding card...', 143 + message: 'Please wait', 144 + position: 'top-center', 145 + autoClose: false, 146 + withCloseButton: false, 147 + }); 153 148 154 - // Close drawer immediately 155 - props.onClose(); 156 - setSelectedCollections(initialCollections); 157 - window.history.replaceState({}, '', window.location.pathname); 158 - cardForm.reset(); 149 + // Close drawer immediately 150 + props.onClose(); 151 + setSelectedCollections(initialCollections); 152 + window.history.replaceState({}, '', window.location.pathname); 153 + cardForm.reset(); 159 154 160 - addCard.mutate(cardData, { 161 - onSuccess: () => { 162 - notifications.update({ 163 - id: notificationId, 164 - color: 'green', 165 - title: 'Success!', 166 - message: 'Card added', 167 - position: 'top-center', 168 - loading: false, 169 - autoClose: 3000, 170 - icon: <BsCheck />, 171 - }); 172 - }, 173 - onError: () => { 174 - notifications.update({ 175 - id: notificationId, 176 - color: 'red', 177 - title: 'Error', 178 - message: 'Could not add card', 179 - position: 'top-center', 180 - loading: false, 181 - autoClose: 5000, 182 - withCloseButton: true, 183 - icon: <BsExclamation />, 184 - }); 185 - }, 186 - }); 187 - } else { 188 - // Original behavior: wait for response 189 - addCard.mutate(cardData, { 190 - onSuccess: () => { 191 - setSelectedCollections(initialCollections); 192 - props.onClose(); 193 - window.history.replaceState({}, '', window.location.pathname); 194 - }, 195 - onError: () => { 196 - notifications.update({ 197 - color: 'red', 198 - title: 'Error', 199 - message: 'Could not add card', 200 - position: 'top-center', 201 - autoClose: 5000, 202 - withCloseButton: true, 203 - icon: <BsExclamation />, 204 - }); 205 - }, 206 - onSettled: () => { 207 - cardForm.reset(); 208 - }, 209 - }); 210 - } 155 + addCard.mutate(cardData, { 156 + onSuccess: () => { 157 + notifications.update({ 158 + id: notificationId, 159 + color: 'green', 160 + title: 'Success!', 161 + message: 'Card added', 162 + position: 'top-center', 163 + loading: false, 164 + autoClose: 3000, 165 + icon: <BsCheck />, 166 + }); 167 + }, 168 + onError: () => { 169 + notifications.update({ 170 + id: notificationId, 171 + color: 'red', 172 + title: 'Error', 173 + message: 'Could not add card', 174 + position: 'top-center', 175 + loading: false, 176 + autoClose: 5000, 177 + withCloseButton: true, 178 + icon: <BsExclamation />, 179 + }); 180 + }, 181 + }); 211 182 }; 212 183 213 184 const handleCreateCollection = (e: React.FormEvent) => {
-1
src/webapp/lib/clientFeatureFlags.ts
··· 11 11 following: boolean; 12 12 connections: boolean; 13 13 graphView: boolean; 14 - optimisticCardAdding: boolean; 15 14 } 16 15 17 16 async function fetchFeatureFlags(): Promise<FeatureFlags> {
-1
src/webapp/lib/serverFeatureFlags.ts
··· 40 40 following: true, 41 41 connections: show, 42 42 graphView: show, 43 - optimisticCardAdding: showForTeam, 44 43 }; 45 44 }