From ce621da26eac77a77dbfdaa350bf6647c46083f5 Mon Sep 17 00:00:00 2001 From: Scott Benton Date: Sun, 2 Jun 2024 19:39:51 -0400 Subject: [PATCH] fix(tracks): Tracks and clocks can now be deleted --- CHANGELOG.MD | 3 +- .../features/ProgressTrack/ProgressTrack.tsx | 37 ++++++++++++++----- .../features/ProgressTrack/ProgressTracks.tsx | 20 ++++++++-- .../charactersAndCampaigns/Clocks/Clock.tsx | 34 ++++++++++++++++- .../charactersAndCampaigns/Clocks/Clocks.tsx | 12 ++++++ .../components/Tabs/TracksTab.tsx | 2 +- .../Tabs/TracksSection/TracksSection.tsx | 10 +++-- .../tracks/campaignTracks.slice.ts | 5 +++ .../tracks/campaignTracks.slice.type.ts | 1 + .../tracks/characterTracks.slice.ts | 6 +++ .../tracks/characterTracks.slice.type.ts | 1 + 11 files changed, 110 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 11269d63..50dae797 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -14,7 +14,8 @@ - The default gold Crew Link theme is now called Eidolon - The teal Crew Link theme is now called Myriad - Clocks now use the "Likely" oracle by default -- Clocks now progress by two ticks when a match is rolled on the oracle die. +- Clocks now progress by two ticks when a match is rolled on the oracle die +- Added a new button to completed clocks and progress tracks that allows users to delete them permanently ### Bug Fixes diff --git a/src/components/features/ProgressTrack/ProgressTrack.tsx b/src/components/features/ProgressTrack/ProgressTrack.tsx index 9e92ea64..4aa133d7 100644 --- a/src/components/features/ProgressTrack/ProgressTrack.tsx +++ b/src/components/features/ProgressTrack/ProgressTrack.tsx @@ -47,6 +47,7 @@ export interface BaseProgressTrackProps { max: number; value: number; onValueChange?: (value: number) => void; + onComplete?: () => void; onDelete?: () => void; onEdit?: () => void; hideDifficultyLabel?: boolean; @@ -111,6 +112,7 @@ export function ProgressTrack(props: ProgressTracksProps) { max, value, onValueChange, + onComplete, onDelete, onEdit, hideDifficultyLabel, @@ -129,15 +131,9 @@ export function ProgressTrack(props: ProgressTracksProps) { const [checks, setChecks] = useState([]); - const handleDelete = () => { - if (onDelete) { - onDelete(); - } - }; - const confirm = useConfirm(); - const handleDeleteClick = () => { + const handleCompleteClick = () => { confirm({ title: "Complete Track", description: "Are you sure you want to complete this track?", @@ -148,7 +144,23 @@ export function ProgressTrack(props: ProgressTracksProps) { }, }) .then(() => { - handleDelete(); + onComplete && onComplete(); + }) + .catch(() => {}); + }; + + const handleDeleteClick = () => { + confirm({ + title: "Complete Track", + description: "Are you sure you want to delete this track?", + confirmationText: "Delete", + confirmationButtonProps: { + variant: "contained", + color: "primary", + }, + }) + .then(() => { + onDelete && onDelete(); }) .catch(() => {}); }; @@ -385,10 +397,10 @@ export function ProgressTrack(props: ProgressTracksProps) { /> )} - {onDelete && ( + {onComplete && ( )} + {onDelete && status === TrackStatus.Completed && ( + + )} ); } diff --git a/src/components/features/ProgressTrack/ProgressTracks.tsx b/src/components/features/ProgressTrack/ProgressTracks.tsx index ccde3c77..2006e204 100644 --- a/src/components/features/ProgressTrack/ProgressTracks.tsx +++ b/src/components/features/ProgressTrack/ProgressTracks.tsx @@ -66,7 +66,7 @@ export function ProgressTracks(props: ProgressTracksProps) { ? updateCampaignProgressTrack : updateCharacterProgressTrack; - const deleteProgressTrack = (trackId: string) => { + const completeProgressTrack = (trackId: string) => { updateProgressTrack(trackId, { status: TrackStatus.Completed }).catch( () => {} ); @@ -83,6 +83,17 @@ export function ProgressTracks(props: ProgressTracksProps) { updateProgressTrack(trackId, { segmentsFilled }).catch(() => {}); }; + const deleteCampaignProgressTrack = useStore( + (store) => store.campaigns.currentCampaign.tracks.deleteTrack + ); + const deleteCharacterProgressTrack = useStore( + (store) => store.characters.currentCharacter.tracks.deleteTrack + ); + + const deleteProgressTrack = isCampaign + ? deleteCampaignProgressTrack + : deleteCharacterProgressTrack; + return ( <> updateProgressTrackValue(trackId, value) } - onDelete={ + onComplete={ readOnly || isCompleted ? undefined - : () => deleteProgressTrack(trackId) + : () => completeProgressTrack(trackId) } onEdit={ readOnly || isCompleted ? undefined : () => setCurrentlyEditingTrackId(trackId) } + onDelete={ + readOnly ? undefined : () => deleteProgressTrack(trackId) + } hideRollButton={readOnly || isCompleted} {...(trackType === TrackTypes.SceneChallenge ? { diff --git a/src/components/features/charactersAndCampaigns/Clocks/Clock.tsx b/src/components/features/charactersAndCampaigns/Clocks/Clock.tsx index e3478855..4b88c24e 100644 --- a/src/components/features/charactersAndCampaigns/Clocks/Clock.tsx +++ b/src/components/features/charactersAndCampaigns/Clocks/Clock.tsx @@ -23,11 +23,18 @@ export interface ClockProps { onValueChange?: (value: number) => void; onSelectedOracleChange?: (oracleKey: AskTheOracle) => void; onComplete?: () => void; + handleDelete?: () => void; } export function Clock(props: ClockProps) { - const { clock, onEdit, onValueChange, onSelectedOracleChange, onComplete } = - props; + const { + clock, + onEdit, + onValueChange, + onSelectedOracleChange, + onComplete, + handleDelete, + } = props; const { askTheOracle } = useSystemOracles(); @@ -53,6 +60,24 @@ export function Clock(props: ClockProps) { } }; + const handleDeleteClick = () => { + if (handleDelete) { + confirm({ + title: "Delete Clock", + description: "Are you sure you want to delete this clock?", + confirmationText: "Delete", + confirmationButtonProps: { + variant: "contained", + color: "primary", + }, + }) + .then(() => { + handleDelete(); + }) + .catch(() => {}); + } + }; + const handleProgressionRoll = () => { if (onValueChange) { const result = rollClockProgression( @@ -182,6 +207,11 @@ export function Clock(props: ClockProps) { Complete Clock )} + {handleDelete && clock.status === TrackStatus.Completed && ( + + )} ); } diff --git a/src/components/features/charactersAndCampaigns/Clocks/Clocks.tsx b/src/components/features/charactersAndCampaigns/Clocks/Clocks.tsx index 9b21ad97..3f6aad59 100644 --- a/src/components/features/charactersAndCampaigns/Clocks/Clocks.tsx +++ b/src/components/features/charactersAndCampaigns/Clocks/Clocks.tsx @@ -51,6 +51,17 @@ export function Clocks(props: ClocksProps) { ? updateCampaignClock : updateCharacterClock; + const deleteCharacterClock = useStore( + (store) => store.characters.currentCharacter.tracks.deleteTrack + ); + const deleteCampaignClock = useStore( + (store) => store.campaigns.currentCampaign.tracks.deleteTrack + ); + + const deleteClock = isCampaignSection + ? deleteCampaignClock + : deleteCharacterClock; + return ( <> {sortedClockIds.length > 0 ? ( @@ -101,6 +112,7 @@ export function Clocks(props: ClocksProps) { ? undefined : (value) => updateClock(clockId, { value }).catch(() => {}) } + handleDelete={() => deleteClock(clockId).catch(() => {})} /> ))} diff --git a/src/pages/Campaign/CampaignPage/components/Tabs/TracksTab.tsx b/src/pages/Campaign/CampaignPage/components/Tabs/TracksTab.tsx index b2a18a6f..740d9f75 100644 --- a/src/pages/Campaign/CampaignPage/components/Tabs/TracksTab.tsx +++ b/src/pages/Campaign/CampaignPage/components/Tabs/TracksTab.tsx @@ -111,7 +111,7 @@ export function TracksTab() { value, }) } - onDelete={() => + onComplete={() => updateCharacterProgressTrack(characterId, trackId, { status: TrackStatus.Completed, }) diff --git a/src/pages/Character/CharacterSheetPage/Tabs/TracksSection/TracksSection.tsx b/src/pages/Character/CharacterSheetPage/Tabs/TracksSection/TracksSection.tsx index 763f4c4e..0d3f650f 100644 --- a/src/pages/Character/CharacterSheetPage/Tabs/TracksSection/TracksSection.tsx +++ b/src/pages/Character/CharacterSheetPage/Tabs/TracksSection/TracksSection.tsx @@ -22,10 +22,12 @@ export function TracksSection() { type={TrackTypes.Journey} typeLabel={isStarforged ? "Expedition" : "Journey"} /> - + {isStarforged && ( + + )} ); diff --git a/src/stores/campaign/currentCampaign/tracks/campaignTracks.slice.ts b/src/stores/campaign/currentCampaign/tracks/campaignTracks.slice.ts index fc4775be..eeb50d74 100644 --- a/src/stores/campaign/currentCampaign/tracks/campaignTracks.slice.ts +++ b/src/stores/campaign/currentCampaign/tracks/campaignTracks.slice.ts @@ -5,6 +5,7 @@ import { listenToProgressTracks } from "api-calls/tracks/listenToProgressTracks" import { TrackStatus } from "types/Track.type"; import { addProgressTrack } from "api-calls/tracks/addProgressTrack"; import { updateProgressTrack } from "api-calls/tracks/updateProgressTrack"; +import { removeProgressTrack } from "api-calls/tracks/removeProgressTrack"; export const createCampaignTracksSlice: CreateSliceType = ( set, @@ -53,6 +54,10 @@ export const createCampaignTracksSlice: CreateSliceType = ( const campaignId = getState().campaigns.currentCampaign.currentCampaignId; return updateProgressTrack({ campaignId, trackId, track }); }, + deleteTrack: (trackId) => { + const campaignId = getState().campaigns.currentCampaign.currentCampaignId; + return removeProgressTrack({ campaignId, id: trackId }); + }, updateCharacterTrack: (characterId, trackId, track) => { return updateProgressTrack({ characterId, trackId, track }); diff --git a/src/stores/campaign/currentCampaign/tracks/campaignTracks.slice.type.ts b/src/stores/campaign/currentCampaign/tracks/campaignTracks.slice.type.ts index a9d0c619..5663edc5 100644 --- a/src/stores/campaign/currentCampaign/tracks/campaignTracks.slice.type.ts +++ b/src/stores/campaign/currentCampaign/tracks/campaignTracks.slice.type.ts @@ -29,6 +29,7 @@ export interface CampaignTracksSliceActions { addTrack: (track: Track) => Promise; updateTrack: (trackId: string, track: Partial) => Promise; + deleteTrack: (trackId: string) => Promise; updateCharacterTrack: ( characterId: string, diff --git a/src/stores/character/currentCharacter/tracks/characterTracks.slice.ts b/src/stores/character/currentCharacter/tracks/characterTracks.slice.ts index b98c9176..aac992fb 100644 --- a/src/stores/character/currentCharacter/tracks/characterTracks.slice.ts +++ b/src/stores/character/currentCharacter/tracks/characterTracks.slice.ts @@ -5,6 +5,7 @@ import { listenToProgressTracks } from "api-calls/tracks/listenToProgressTracks" import { TrackStatus } from "types/Track.type"; import { addProgressTrack } from "api-calls/tracks/addProgressTrack"; import { updateProgressTrack } from "api-calls/tracks/updateProgressTrack"; +import { removeProgressTrack } from "api-calls/tracks/removeProgressTrack"; export const createCharacterTracksSlice: CreateSliceType< CharacterTracksSlice @@ -54,6 +55,11 @@ export const createCharacterTracksSlice: CreateSliceType< getState().characters.currentCharacter.currentCharacterId; return updateProgressTrack({ characterId, trackId, track }); }, + deleteTrack: (trackId) => { + const characterId = + getState().characters.currentCharacter.currentCharacterId; + return removeProgressTrack({ characterId, id: trackId }); + }, setLoadCompletedTracks: () => { set((store) => { diff --git a/src/stores/character/currentCharacter/tracks/characterTracks.slice.type.ts b/src/stores/character/currentCharacter/tracks/characterTracks.slice.type.ts index 3f4f0783..5d9aaa90 100644 --- a/src/stores/character/currentCharacter/tracks/characterTracks.slice.type.ts +++ b/src/stores/character/currentCharacter/tracks/characterTracks.slice.type.ts @@ -29,6 +29,7 @@ export interface CharacterTracksSliceActions { addTrack: (track: Track) => Promise; updateTrack: (trackId: string, track: Partial) => Promise; + deleteTrack: (trackId: string) => Promise; setLoadCompletedTracks: () => void; resetStore: () => void;