Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(boards): visual overhaul #1551

Merged
merged 10 commits into from
Jun 14, 2024
56 changes: 53 additions & 3 deletions next-tavla/app/(admin)/actions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
'use server'
import { firestore } from 'firebase-admin'
import { TOrganizationID, TOrganization, TBoard } from 'types/settings'
import {
TOrganizationID,
TOrganization,
TBoard,
TBoardID,
} from 'types/settings'
import { getUser, initializeAdminApp } from './utils/firebase'
import { getUserFromSessionCookie } from './utils/server'
import { chunk, concat, isEmpty } from 'lodash'
import { chunk, concat, isEmpty, flattenDeep } from 'lodash'
import { TavlaError } from './utils/types'
import { redirect } from 'next/navigation'
import { FIREBASE_DEV_CONFIG, FIREBASE_PRD_CONFIG } from './utils/constants'
Expand Down Expand Up @@ -75,7 +80,7 @@ export async function getBoardsForOrganization(oid: TOrganizationID) {
.flat()
}

export async function getBoardsForUser() {
export async function getPrivateBoardsForUser() {
const user = await getUser()
if (!user)
throw new TavlaError({
Expand Down Expand Up @@ -104,3 +109,48 @@ export async function getBoardsForUser() {
)
.flat()
}

export async function getBoards(ids?: TBoardID[]) {
if (!ids) return []

const batches = chunk(ids, 20)
const queries = batches.map((batch) =>
firestore()
.collection('boards')
.where(firestore.FieldPath.documentId(), 'in', batch)
.get(),
)

const refs = await Promise.all(queries)
return refs
.map((ref) =>
ref.docs.map((doc) => ({ id: doc.id, ...doc.data() } as TBoard)),
)
.flat()
}

export async function getAllBoardsForUser() {
const user = await getUser()
if (!user) return redirect('/')

const privateBoardIDs = concat(user.owner ?? [], user.editor ?? [])
const privateBoards = (await getBoards(privateBoardIDs)).map((board) => ({
board,
}))

const organizations = await getOrganizationsForUser()

const organizationsBoards = flattenDeep(
await Promise.all(
organizations.map(async (organization) =>
(
await getBoards(organization.boards)
).map((board) => ({
board,
organization,
})),
),
),
)
return [...organizationsBoards, ...privateBoards]
}
80 changes: 0 additions & 80 deletions next-tavla/app/(admin)/boards/[[...id]]/page.tsx

This file was deleted.

12 changes: 8 additions & 4 deletions next-tavla/app/(admin)/boards/components/BoardTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
'use client'
import { TableHeader } from 'app/(admin)/boards/components/TableHeader'
import { TableRows } from 'app/(admin)/boards/components/TableRows'
import { TBoard } from 'types/settings'
import { TBoardWithOrganizaion } from 'types/settings'
import { isEmpty } from 'lodash'
import { useSearchParam } from '../../hooks/useSearchParam'
import { IllustratedInfo } from 'app/(admin)/components/IllustratedInfo'
import { DEFAULT_BOARD_COLUMNS, TBoardsColumn } from 'app/(admin)/utils/types'

function BoardTable({ boards }: { boards: TBoard[] }) {
function BoardTable({
boardsWithOrg,
}: {
boardsWithOrg: TBoardWithOrganizaion[]
}) {
const value = useSearchParam('columns')
const columns = value?.split(',') ?? DEFAULT_BOARD_COLUMNS

if (isEmpty(boards))
if (isEmpty(boardsWithOrg))
return (
<IllustratedInfo
title="Her var det tomt"
Expand All @@ -27,7 +31,7 @@ function BoardTable({ boards }: { boards: TBoard[] }) {
}}
>
<TableHeader columns={columns as TBoardsColumn[]} />
<TableRows boards={boards} />
<TableRows boardsWithOrg={boardsWithOrg} />
</div>
)
}
Expand Down
5 changes: 4 additions & 1 deletion next-tavla/app/(admin)/boards/components/Column/Column.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ function Column({
children: React.ReactNode
}) {
return (
<div id={column} className="min-h-9 flex flex-row items-center">
<div
id={column}
className="pl-2 flex flex-row items-center min-h-16 table-custom-nth-child"
>
{children}
</div>
)
Expand Down
11 changes: 0 additions & 11 deletions next-tavla/app/(admin)/boards/components/Column/Link.tsx

This file was deleted.

13 changes: 11 additions & 2 deletions next-tavla/app/(admin)/boards/components/Column/Name.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { DEFAULT_BOARD_NAME } from 'app/(admin)/utils/constants'
import { Column } from './Column'
import { TBoard } from 'types/settings'
import Link from 'next/link'

function Name({ name = DEFAULT_BOARD_NAME }: { name?: string }) {
return <Column column="name">{name}</Column>
function Name({ board }: { board?: TBoard }) {
if (!board) return <Column column="name">{DEFAULT_BOARD_NAME}</Column>
return (
<Column column="name">
<Link href={`/edit/${board.id}`} className="hover:underline">
{board.meta.title}
</Link>
</Column>
)
}

export { Name }
20 changes: 20 additions & 0 deletions next-tavla/app/(admin)/boards/components/Column/Organization.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Link from 'next/link'
import { Column } from './Column'
import { TOrganization } from 'types/settings'

function Organization({ organization }: { organization?: TOrganization }) {
if (!organization) return <Column column="organization">Privat</Column>

return (
<Column column="organization">
<Link
href={`/organizations/${organization.id}`}
className="hover:underline"
>
{organization.name}
</Link>
</Column>
)
}

export { Organization }
24 changes: 14 additions & 10 deletions next-tavla/app/(admin)/boards/components/Column/index.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
import { TBoard } from 'types/settings'
import { TBoardWithOrganizaion } from 'types/settings'
import { Actions } from './Actions'
import { LastModified } from './LastModified'
import { Name } from './Name'
import { Tags } from './Tags'
import { Link } from './Link'
import { TTag } from 'types/meta'
import { TBoardsColumn } from 'app/(admin)/utils/types'
import { Organization } from './Organization'

function Column({
board,
boardWithOrg,
column,
tags,
}: {
board: TBoard
boardWithOrg: TBoardWithOrganizaion
column: TBoardsColumn
tags: TTag[]
}) {
switch (column) {
case 'name':
return <Name name={board.meta?.title} />
case 'url':
return <Link bid={board.id} />
return <Name board={boardWithOrg.board} />
case 'actions':
return <Actions board={board} />
return <Actions board={boardWithOrg.board} />
case 'lastModified':
return <LastModified timestamp={board.meta?.dateModified} />
return (
<LastModified
timestamp={boardWithOrg.board.meta?.dateModified}
/>
)
case 'organization':
return <Organization organization={boardWithOrg.organization} />
case 'tags':
return <Tags board={board} allTags={tags} />
return <Tags board={boardWithOrg.board} allTags={tags} />
default:
return <div>Ukjent kolonne</div>
}
Expand Down
12 changes: 8 additions & 4 deletions next-tavla/app/(admin)/boards/components/FilterButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ import { TTag } from 'types/meta'
import { FilterChip } from '@entur/chip'
import { uniq, xor } from 'lodash'
import { NotificationBadge } from '@entur/layout'
import { TBoard } from 'types/settings'
import { TBoardWithOrganizaion } from 'types/settings'
import { useSearchParamReplacer } from '../../hooks/useSearchParamReplacer'

function FilterButton({ boards }: { boards: TBoard[] }) {
function FilterButton({
boardsWithOrg,
}: {
boardsWithOrg: TBoardWithOrganizaion[]
}) {
const [value, replace] = useSearchParamReplacer('tags')
const activeTags = value?.split(',') ?? []
const allTags = uniq(
boards.flatMap((board) => {
return board?.meta?.tags ?? []
boardsWithOrg.flatMap((boardWithOrg) => {
return boardWithOrg?.board.meta?.tags ?? []
}),
)

Expand Down
1 change: 0 additions & 1 deletion next-tavla/app/(admin)/boards/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ function Search() {
}, [replace, search])
return (
<TextField
className="w-full md:w-1/2"
label="Søk på navn på tavle"
prepend={<SearchIcon inline aria-hidden="true" />}
value={search}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ function ColumnHeader({ column }: { column: TBoardsColumn }) {
return (
<div
key={column}
className="flex items-center gap-1 border-b-2 border-b-primary mb-2"
className="flex items-center gap-1 bg-grey70 pl-2 h-10"
>
<div
id={BoardsColumns[column]}
className="flex h-12 items-center font-medium py-0 px-0.5"
className="items-center font-medium py-0 px-0.5"
aria-sort={
sort.column === column && sort.type ? sort.type : 'none'
}
Expand Down
Loading