Skip to content

Commit

Permalink
feat: allow for submissions to be cancelled
Browse files Browse the repository at this point in the history
refs #210
  • Loading branch information
steveoh committed Jan 19, 2023
1 parent 6aab0df commit b6e472d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 5 deletions.
26 changes: 24 additions & 2 deletions src/components/pageElements/MyContent.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Tab } from '@headlessui/react';
import { ChevronRightIcon } from '@heroicons/react/20/solid';
import { ArrowLeftCircleIcon } from '@heroicons/react/24/outline';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import clsx from 'clsx';
import { httpsCallable } from 'firebase/functions';
import { getDownloadURL, ref } from 'firebase/storage';
Expand Down Expand Up @@ -239,6 +239,27 @@ const Submission = ({ item, dispatch }) => {
const storage = useStorage();
const [url, setUrl] = useState('');

const functions = useFunctions();
const cancelSubmission = httpsCallable(
functions,
'functions-httpsPostCancelCorner'
);

const queryClient = useQueryClient();
const { mutate, status: mutationStatus } = useMutation({
mutationFn: (data) => cancelSubmission(data),
onSuccess: async (response) => {
console.log('success', response);
await queryClient.cancelQueries();

queryClient.invalidateQueries({ queryKey: ['my content'] });
queryClient.removeQueries({ queryKey: ['monument record sheet'] });
},
onError: (error) => {
console.warn('error', error);
},
});

const { label, submitted, id, status, geometry, attributes } = item;
const submission = Date.parse(submitted);

Expand Down Expand Up @@ -290,8 +311,9 @@ const Submission = ({ item, dispatch }) => {
</Button>
<Button
style="secondary"
state={mutationStatus}
buttonGroup={{ right: true }}
onClick={() => dispatch({ type: 'submission/cancel', payload: id })}
onClick={() => mutate({ key: item.key })}
>
Cancel
</Button>
Expand Down
7 changes: 4 additions & 3 deletions src/functions/https/getMyContent.f.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ const getMyContent = https.onCall(async (_, context) => {
}

try {
const filter = db
.collection('submissions')
.where('submitted_by.id', '==', context.auth.uid);
let filter = db
.collectionGroup('submissions')
.where('submitted_by.id', '==', context.auth.uid)
.where('status.user.cancelled', '==', null);

const snapshot = await filter.withConverter(myContentConverter).get();

Expand Down
83 changes: 83 additions & 0 deletions src/functions/https/postCancelCorner.f.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { auth, https, logger } from 'firebase-functions/v1';
import { getFirestore } from 'firebase-admin/firestore';
import { getStorage } from 'firebase-admin/storage';
import setupFirebase from '../firebase.mjs';

const config = setupFirebase();
const db = getFirestore();

const postCancelCorner = https.onCall(async (data, context) => {
if (!context.auth) {
logger.warn('unauthenticated request', { structuredData: true });

throw new auth.HttpsError('unauthenticated', 'You must log in');
}

if (!data) {
logger.warn('cancellation data empty', {
structuredData: true,
});

throw new https.HttpsError(
'invalid-argument',
'The cancellation data is missing'
);
}

logger.info('validating corner cancellation', data, context.auth.uid, {
structuredData: true,
});

if (!data.key) {
throw new auth.HttpsError(
'invalid-argument',
'corner submission data is invalid'
);
}

try {
const reference = db.collection('submissions').doc(data.key);
const snapshot = await reference.get();

logger.debug('cancelling submission', data.key, {
structuredData: true,
});

await reference.set(
{ status: { user: { cancelled: new Date() } } },
{ merge: true }
);
await removeStorage(context.auth.uid, snapshot.data());
} catch (error) {
logger.error('error finding submission', error, {
structuredData: true,
});

throw new auth.HttpsError('internal', 'The submission was not cancelled');
}

return 1;
});

export const removeStorage = async (user, submission) => {
const bucket = getStorage().bucket(config.storageBucket);
const prefix = `submitters/${user}/${submission.type}/${submission.blm_point_id}/`;

logger.debug('deleting submission files', prefix, {
structuredData: true,
});

await bucket.deleteFiles(
{
force: true,
prefix,
},
(error) => {
logger.warn('had trouble deleting file', error, {
structuredData: true,
});
}
);
};

export default postCancelCorner;
3 changes: 3 additions & 0 deletions src/functions/https/postCorner.f.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ export const formatDataForFirestore = (data, user) => {
sgid: {
approved: null,
},
user: {
cancelled: null,
},
},
submitted_by: {
id: user.uid,
Expand Down
3 changes: 3 additions & 0 deletions src/functions/https/postCorner.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ describe('postCorner', () => {
sgid: {
approved: null,
},
user: {
cancelled: null,
},
},
};

Expand Down

0 comments on commit b6e472d

Please sign in to comment.