Skip to content

Commit

Permalink
✨ sort by newest data for proposals list (#523)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpetetot committed Apr 4, 2019
1 parent c038877 commit 3bca5d3
Show file tree
Hide file tree
Showing 10 changed files with 1,475 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -29,6 +29,7 @@ firebase-debug.log*
.firebaserc
.runtimeconfig.json
.firebase/
serviceAccount.json

# docz
.docz/
Expand Down
12 changes: 6 additions & 6 deletions config/firestore.indexes.json
Expand Up @@ -18,14 +18,14 @@
"collectionId": "proposals",
"fields": [
{ "fieldPath": "state", "mode": "ASCENDING" },
{ "fieldPath": "updateTimestamp", "mode": "ASCENDING" }
{ "fieldPath": "createTimestamp", "mode": "ASCENDING" }
]
},
{
"collectionId": "proposals",
"fields": [
{ "fieldPath": "state", "mode": "ASCENDING" },
{ "fieldPath": "updateTimestamp", "mode": "DESCENDING" }
{ "fieldPath": "createTimestamp", "mode": "DESCENDING" }
]
},
{
Expand All @@ -46,14 +46,14 @@
"collectionId": "proposals",
"fields": [
{ "fieldPath": "categories", "mode": "ASCENDING" },
{ "fieldPath": "updateTimestamp", "mode": "ASCENDING" }
{ "fieldPath": "createTimestamp", "mode": "ASCENDING" }
]
},
{
"collectionId": "proposals",
"fields": [
{ "fieldPath": "categories", "mode": "ASCENDING" },
{ "fieldPath": "updateTimestamp", "mode": "DESCENDING" }
{ "fieldPath": "createTimestamp", "mode": "DESCENDING" }
]
},
{
Expand All @@ -74,14 +74,14 @@
"collectionId": "proposals",
"fields": [
{ "fieldPath": "formats", "mode": "ASCENDING" },
{ "fieldPath": "updateTimestamp", "mode": "ASCENDING" }
{ "fieldPath": "createTimestamp", "mode": "ASCENDING" }
]
},
{
"collectionId": "proposals",
"fields": [
{ "fieldPath": "formats", "mode": "ASCENDING" },
{ "fieldPath": "updateTimestamp", "mode": "DESCENDING" }
{ "fieldPath": "createTimestamp", "mode": "DESCENDING" }
]
}
]
Expand Down
2 changes: 1 addition & 1 deletion functions/direct/submission.js
Expand Up @@ -59,7 +59,7 @@ const submitTalk = async ({
)
}

const submittedTalk = omit(talk, ['createTimestamp', 'submissions'])
const submittedTalk = omit(talk, ['createTimestamp', 'updateTimestamp', 'submissions'])

await updateTalk(submittedTalk.id, { [`submissions.${eventId}`]: submittedTalk })

Expand Down
11 changes: 7 additions & 4 deletions functions/firestore/proposal.js
Expand Up @@ -4,6 +4,7 @@ const { omit, toLower, deburr } = require('lodash')

const addProposal = (eventId, proposal) => {
const newProposal = omit(proposal, 'submissions')
const now = firebase.firestore.FieldValue.serverTimestamp()
return firebase
.firestore()
.collection('events')
Expand All @@ -14,19 +15,21 @@ const addProposal = (eventId, proposal) => {
...newProposal,
rating: null,
state: 'submitted',
updateTimestamp: firebase.firestore.FieldValue.serverTimestamp(),
updateTimestamp: now,
createTimestamp: now,
})
}

const updateProposal = (eventId, proposal) => {
const updatedProposal = omit(proposal, 'submissions')
const now = firebase.firestore.FieldValue.serverTimestamp()
return firebase
.firestore()
.collection('events')
.doc(eventId)
.collection('proposals')
.doc(proposal.id)
.update(updatedProposal)
.update({ ...updatedProposal, updateTimestamp: now })
}

const removeProposal = (eventId, proposalId) => firebase
Expand Down Expand Up @@ -63,9 +66,9 @@ const getEventProposals = async (
// add sortOrder
if (sortOrder) {
if (sortOrder === 'newest') {
query = query.orderBy('updateTimestamp', 'desc')
query = query.orderBy('createTimestamp', 'desc')
} else if (sortOrder === 'oldest') {
query = query.orderBy('updateTimestamp', 'asc')
query = query.orderBy('createTimestamp', 'asc')
} else if (sortOrder === 'highestRating') {
query = query.orderBy('rating', 'desc')
} else if (sortOrder === 'lowestRating') {
Expand Down
1 change: 1 addition & 0 deletions scripts/.nvmrc
@@ -0,0 +1 @@
8
118 changes: 118 additions & 0 deletions scripts/index.js
@@ -0,0 +1,118 @@
/* eslint-disable no-underscore-dangle */
const admin = require('firebase-admin')

// ====================================
// Configuration
// ====================================

// service account credentials (need to be downloaded from firebase console)
const serviceAccount = require('./serviceAccount.json')

// initialize app credentials
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
})

// initialize firestore database
const db = admin.firestore()

// ====================================
// Utils
// ====================================

const isTimestamp = date => !!date && date instanceof admin.firestore.Timestamp

// ====================================
// Firebase update functions
// ====================================

const getEvent = async (id) => {
const doc = await db.collection('events').doc(id).get()
return { id: doc.id, data: doc.data() }
}

const getAllEvents = async () => {
const events = await db.collection('events').get()
return events.docs.map(doc => ({ id: doc.id, data: doc.data() }))
}

const getProposals = async (eventId) => {
const eventProposals = await db
.collection('events')
.doc(eventId)
.collection('proposals')
.get()

const proposals = eventProposals.docs.map(doc => doc.data())

return { eventId, proposals }
}

/**
* Function used to update all proposals for all events or by event id
* @param function callback proposal updater
* @param string eventId event id (optional)
*/
const updateProposals = async (callback, eventId) => {
let events = []
if (eventId) {
events = [await getEvent(eventId)]
} else {
events = await getAllEvents()
}
const eventsProposalsList = await Promise.all(events.map(e => getProposals(e.id)))

return Promise.all(
eventsProposalsList.map(async (eventProposals) => {
console.log(`Update proposals for event ${eventProposals.eventId}:`)
console.log(` > ${eventProposals.proposals.length} proposals`)

return Promise.all(
eventProposals.proposals.map((oldProposal) => {
const updatedProposal = callback(oldProposal) || {}
console.log(` - update proposal ${oldProposal.title} (${oldProposal.id})`)
return db
.collection('events')
.doc(eventProposals.eventId)
.collection('proposals')
.doc(oldProposal.id)
.update(updatedProposal)
}),
)
}),
)
}

const main = async () => {
await updateProposals((proposal) => {
let { updateTimestamp } = proposal

if (isTimestamp(updateTimestamp)) {
updateTimestamp = new admin.firestore.Timestamp(
updateTimestamp._seconds,
updateTimestamp._nanoseconds,
)
} else if (updateTimestamp._seconds && updateTimestamp._nanoseconds) {
updateTimestamp = new admin.firestore.Timestamp(
updateTimestamp._seconds,
updateTimestamp._nanoseconds,
)
} else if (updateTimestamp.seconds && updateTimestamp.nanoseconds) {
updateTimestamp = new admin.firestore.Timestamp(
updateTimestamp.seconds,
updateTimestamp.nanoseconds,
)
} else if (!isTimestamp(updateTimestamp) && updateTimestamp instanceof Date) {
updateTimestamp = admin.firestore.Timestamp.fromDate(updateTimestamp)
}

const createTimestamp = updateTimestamp
return {
updateTimestamp,
createTimestamp,
}
})
console.log('🎉 Finished')
}

main()
9 changes: 9 additions & 0 deletions scripts/package.json
@@ -0,0 +1,9 @@
{
"name": "conference-hall-scripts",
"version": "0.1.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"firebase-admin": "^7.1.0"
}
}

0 comments on commit 3bca5d3

Please sign in to comment.