Skip to content

Commit

Permalink
Merge pull request #65 from Daellhin/dev
Browse files Browse the repository at this point in the history
feat: added reordering for announcements
  • Loading branch information
Daellhin authored Oct 2, 2024
2 parents cae3b7c + 68c630b commit 39776c1
Show file tree
Hide file tree
Showing 11 changed files with 642 additions and 705 deletions.
1,094 changes: 514 additions & 580 deletions package-lock.json

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,45 @@
"emulate": "firebase emulators:start"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.2.4",
"@sveltejs/adapter-static": "^3.0.4",
"@sveltejs/kit": "^2.5.24",
"@sveltejs/adapter-auto": "^3.2.5",
"@sveltejs/adapter-static": "^3.0.5",
"@sveltejs/kit": "^2.6.1",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@types/byte-size": "^8.1.2",
"@types/file-saver": "^2.0.7",
"@types/uuid": "^10.0.0",
"autoprefixer": "^10.4.20",
"eslint": "^9.9.1",
"eslint-plugin-svelte": "^2.43.0",
"firebase-tools": "^13.15.4",
"postcss": "^8.4.41",
"eslint": "^9.11.1",
"eslint-plugin-svelte": "^2.44.1",
"firebase-tools": "^13.20.2",
"postcss": "^8.4.47",
"postcss-nesting": "^13.0.0",
"svelte": "^4.2.19",
"svelte-check": "^3.8.6",
"svelte-dnd-action": "^0.9.50",
"svelte-fa": "^4.0.2",
"svelte-preprocess": "^6.0.2",
"svelte-check": "^4.0.4",
"svelte-dnd-action": "^0.9.51",
"svelte-fa": "^4.0.3",
"svelte-preprocess": "^6.0.3",
"svelte-time": "^0.9.0",
"tailwindcss": "^3.4.10",
"tailwindcss": "^3.4.13",
"tslib": "^2.7.0",
"typescript": "^5.5.4",
"typescript-eslint": "^8.2.0",
"vite": "^5.4.2"
"typescript": "^5.6.2",
"typescript-eslint": "^8.8.0",
"vite": "^5.4.8"
},
"type": "module",
"dependencies": {
"@fortawesome/free-brands-svg-icons": "^6.6.0",
"@fortawesome/free-regular-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@popperjs/core": "^2.11.8",
"@zerodevx/svelte-toast": "^0.9.5",
"@zerodevx/svelte-toast": "^0.9.6",
"bigger-picture": "^1.1.17",
"byte-size": "^9.0.0",
"cl-editor": "^2.3.0",
"daisyui": "^4.12.10",
"dayjs": "^1.11.13",
"file-saver": "^2.0.5",
"firebase": "^10.13.0",
"firebase": "^10.14.0",
"jszip": "^3.10.1",
"p-limit": "^6.1.0",
"svelte-collapse": "^0.1.3",
Expand Down
2 changes: 1 addition & 1 deletion src/components/announcements/AnnouncementRow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
export let updateDismissibleHandler: (
announcement: Announcement,
) => Promise<void> | any
export let dragDisabled: boolean
export let dragFullyDisabled = false
Expand All @@ -24,6 +23,7 @@
deleteHandler(announcement)
}
function updateVisibilityWrapper() {
console.log("updateVisibilityWrapper")
updateVisibilityHandler(announcement)
}
function updateDismissibleWrapper() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
import TableHeaderRow from "$components/table/TableHeaderRow.svelte"
import type { Announcement } from "$lib/domain/Announcement"
import { announcementStore } from "$lib/stores/AnnouncementStore"
import { FLIP_DURATION } from "$lib/utils/Constants"
import { handleFirebaseError } from "$lib/utils/Firebase"
import { faSearch } from "@fortawesome/free-solid-svg-icons"
import { dndzone } from "svelte-dnd-action"
import AnnouncementRow from "./AnnouncementRow.svelte"
export let startEdit: (announcement: Announcement) => void
Expand All @@ -22,21 +23,20 @@
let dragDisabled = true
$: dragFullyDisabled = searchString.length > 0
$: dragableAnnouncements = $announcementStore || []
//.map((e) => e.toDragableItem())
$: dragableAnnouncements = $announcementStore.map((e) => e.toDragableItem())
// function handleConsider(event: CustomEvent<DndEvent<any>>) {
// dragableSponsors = event.detail.items
// dragDisabled = true
// }
// async function handleFinalize(event: CustomEvent<DndEvent<any>>) {
// savingNewOrder = true
// dragableSponsors = event.detail.items
// dragDisabled = true
// const newSortedIds = dragableSponsors.map((e) => e.value.id)
// await announcementStore.updateAnnouncementOrder(newSortedIds)
// savingNewOrder = false
// }
function handleConsider(event: CustomEvent<DndEvent<any>>) {
dragableAnnouncements = event.detail.items
dragDisabled = true
}
async function handleFinalize(event: CustomEvent<DndEvent<any>>) {
savingNewOrder = true
dragableAnnouncements = event.detail.items
dragDisabled = true
const newSortedIds = dragableAnnouncements.map((e) => e.value.id)
await announcementStore.updateAnnouncementsOrder(newSortedIds)
savingNewOrder = false
}
// -- Edit articles --
let showModal = false
Expand Down Expand Up @@ -69,12 +69,12 @@
// : dragableAnnouncements
$: filteredDragableAnnouncements = dragableAnnouncements
// function filterAnnouncements(searchString: string) {
// return dragableAnnouncements.filter(
// (announcement) => true,
// //sponsor.value.matchesSearchString(searchString),
// )
// }
// function filterAnnouncements(searchString: string) {
// return dragableAnnouncements.filter(
// (announcement) => true,
// //announcement.value.matchesSearchString(searchString),
// )
// }
// -- Util --
let saving = false
Expand Down Expand Up @@ -125,31 +125,33 @@
]}
/>
</thead>
<!-- <tbody
use:dndzone={{
items: dragableAnnouncements,
dragDisabled: dragDisabled,
flipDurationMs: FLIP_DURATION,
dropTargetStyle: {},
}}
on:consider={handleConsider}
on:finalize={handleFinalize}
> -->
<tbody>
<tbody
use:dndzone={{
items: dragableAnnouncements,
dragDisabled: dragDisabled,
flipDurationMs: FLIP_DURATION,
dropTargetStyle: {},
}}
on:consider={handleConsider}
on:finalize={handleFinalize}
>
{#each filteredDragableAnnouncements as dragable (dragable.id)}
<AnnouncementRow
announcement={dragable}
announcement={dragable.value}
editHandler={startEdit}
deleteHandler={startDelete}
updateVisibilityHandler={updateVisibility}
updateDismissibleHandler={() => {}}
updateDismissibleHandler={() => {console.error("Not implemented")}}
bind:dragDisabled
{dragFullyDisabled}
/>
{/each}
</tbody>
</table>
</div>
{dragDisabled}
{dragFullyDisabled}
{filteredDragableAnnouncements.map(e => e.value.title)}
<TableFooter
filteredLength={filteredDragableAnnouncements.length}
fullLength={dragableAnnouncements.length}
Expand Down
8 changes: 8 additions & 0 deletions src/lib/domain/Announcement.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Timestamp, type FirestoreDataConverter } from "firebase/firestore"
import type { Dayjs } from "dayjs"
import dayjs from "dayjs"
import type { DragableItem } from "$lib/utils/Types"

export interface AnnouncementJson {
// id: string // id comes from the firebase Document ID
Expand Down Expand Up @@ -43,6 +44,13 @@ export class Announcement {
} as AnnouncementJson
}

toDragableItem() {
return {
id: this.id,
value: this
} as DragableItem<Announcement>
}

/**
* Checks if Announcemnt matches a search string
* - if searchString is undefined, matches all
Expand Down
76 changes: 34 additions & 42 deletions src/lib/stores/AnnouncementStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,31 @@ import { browser } from '$app/environment'
import { Announcement, announcementConverter, type AnnouncementJson } from '$lib/domain/Announcement'
import { Collections } from '$lib/firebase/Firebase'
import { convertStringToBool } from '$lib/utils/Utils'
import { writable } from 'svelte/store'
import { get, writable } from 'svelte/store'
import { createMockAnnouncementStore } from './mocks/MockAnnouncementStore'
import type { OrderingJson } from '$lib/domain/Ordering'
import { sortWithOrdering } from '$lib/utils/Stores'

function createAnnouncementStore() {
const store = writable<(Announcement)[]>(undefined, set => {
async function init() {
if (!browser) return

// -- Load Announcement --
// -- Load Announcements --
const { firebaseApp } = await import('$lib/firebase/Firebase')
const { getFirestore, getDocs, collection } = await import('firebase/firestore')
const { getFirestore, getDocs, getDoc, doc, collection } = await import('firebase/firestore')
const firestore = getFirestore(firebaseApp)

const announcementsRef = collection(firestore, Collections.ANNOUNCEMENTS)
const announcementsSnap = await getDocs(announcementsRef)
const announcements = announcementsSnap.docs.map(e => Announcement.fromJson(e.id, e.data() as AnnouncementJson))

// // -- Sort Announcement --
// const orderingRef = doc(firestore, Collections.ORDERINGS, Collections.ANNOUNCEMENTS)
// const orderingSnap = await getDoc(orderingRef)
// const ordering = orderingSnap.data() as OrderingJson | undefined
// if (!ordering) throw new Error(`Sort order ${Collections.ANNOUNCEMENTS} not found`)
// sortAnnouncements(announcements, ordering.ids)
// // -- Sort announcements --
const orderingRef = doc(firestore, Collections.ORDERINGS, Collections.ANNOUNCEMENTS)
const orderingSnap = await getDoc(orderingRef)
const ordering = orderingSnap.data() as OrderingJson | undefined
if (!ordering) throw new Error(`Sort order ${Collections.ANNOUNCEMENTS} not found`)
sortWithOrdering(announcements, ordering.ids)

// -- Set store --
set(announcements)
Expand All @@ -34,7 +36,7 @@ function createAnnouncementStore() {
const { subscribe, update } = store

async function createAnnouncement(announcement: Announcement) {
// -- Upload announcement --
// -- Upload document --
const { getFirestore, collection, doc, setDoc } = await import('firebase/firestore')
const { firebaseApp } = await import('$lib/firebase/Firebase')
const firestore = getFirestore(firebaseApp)
Expand All @@ -44,15 +46,15 @@ function createAnnouncementStore() {
announcement.id = newDocRef.id

// -- Update ordering --
// const existingSortedIds = get(store).map((e) => e.id)
// await updateAnnouncementOrder([...existingSortedIds, newDocRef.id])
const existingSortedIds = get(store).map((e) => e.id)
await updateAnnouncementsOrder([...existingSortedIds, newDocRef.id])

// -- Update store(new item last) --
update((anouncements) => ([...anouncements, announcement]))
}

async function updateAnnouncement(newTitle: string, newContent: string, newVisible: boolean, newDismissable: boolean, announcement: Announcement) {
// -- Update Announcement --
// -- Update document --
const { getFirestore, doc, updateDoc } = await import('firebase/firestore')
const { firebaseApp } = await import('$lib/firebase/Firebase')
const firestore = getFirestore(firebaseApp)
Expand All @@ -76,39 +78,40 @@ function createAnnouncementStore() {
}

async function deleteAnnouncement(announcement: Announcement) {
// -- Remove announcement --
// -- Delete document --
const { getFirestore, doc, deleteDoc } = await import('firebase/firestore')
const { firebaseApp } = await import('$lib/firebase/Firebase')
const firestore = getFirestore(firebaseApp)

const docRef = doc(firestore, Collections.ANNOUNCEMENTS, announcement.id)
await deleteDoc(docRef)

// -- Remove from store --
// -- Delete from store --
update((announcements) => announcements.filter((e) => e.id !== announcement.id))

// -- Update ordering --
//const existingSortedIds = get(store).map((e) => e.id)
//await updateAnnouncementOrder(existingSortedIds)
const existingSortedIds = get(store).map((e) => e.id)
await updateAnnouncementsOrder(existingSortedIds)
}

// async function updateAnnouncementOrder(newSortedIds: string[]) {
// // -- Update ordering --
// const { firebaseApp } = await import('$lib/firebase/Firebase')
// const { getFirestore, doc, updateDoc } = await import('firebase/firestore')
// const firestore = getFirestore(firebaseApp)
async function updateAnnouncementsOrder(newSortedIds: string[]) {
// -- Update document --
const { firebaseApp } = await import('$lib/firebase/Firebase')
const { getFirestore, doc, updateDoc } = await import('firebase/firestore')
const firestore = getFirestore(firebaseApp)

// const docRef = doc(firestore, Collections.ORDERINGS, Collections.ANNOUNCEMENTS)
// await updateDoc(docRef, {
// ids: newSortedIds,
// })
const docRef = doc(firestore, Collections.ORDERINGS, Collections.ANNOUNCEMENTS)
await updateDoc(docRef, {
ids: newSortedIds,
})

// // -- Update store --
// update((announcements) => [...announcements])
// }
// -- Update store --
sortWithOrdering(get(store), newSortedIds)
update((announcements) => [...announcements])
}

async function updateAnnouncementVisibility(announcement: Announcement) {
// -- Update announcement --
// -- Update document --
const { getFirestore, doc, updateDoc } = await import('firebase/firestore')
const { firebaseApp } = await import('$lib/firebase/Firebase')
const firestore = getFirestore(firebaseApp)
Expand All @@ -123,23 +126,12 @@ function createAnnouncementStore() {
update((announcements) => [...announcements])
}

// function sortAnnouncements(announcements: Announcement[], sortedIds: string[]) {
// const sortMap = new Map(sortedIds.map((e, i) => [e, i] as [string, number]))
// announcements.sort((a, b) => {
// const first = sortMap.get(a.id)
// if (first === undefined) throw new Error(`Announcement ${a.id} not found in sort map`)
// const second = sortMap.get(b.id)
// if (second === undefined) throw new Error(`Announcement ${b.id} not found in sort map`)
// return first - second
// })
// }

return {
subscribe,
createAnnouncement,
updateAnnouncement,
deleteAnnouncement,
// updateAnnouncementOrder,
updateAnnouncementsOrder,
updateAnnouncementVisibility
}
}
Expand Down
Loading

0 comments on commit 39776c1

Please sign in to comment.