-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(edit): migrate edit from pages to app router (#1383)
* feat(edit): basic preview * feat(edit): track changes to edit form * feat(edit): tile selector * feat(edit): fix debounced tile selector * feat(edit): form based tile selector * feat(edit): simple TileCard with add/delete functionality * feat(edit): simple action for saving tile * feat(edit): fetch data for tile * feat(edit): wip TileCard * feat(edit): cleanup TileCard * feat(edit): wip form action * chore(edit): linting and typing * feat(edit): fix wrongful graphql query and quay data fetching * feat(edit): working tile update * feat(edit): update tiles in place * feat(edit): close tile on save * feat(edit): added floating action button * feat(meta): added meta to edit * feat(edit): remove unused/deprecated components * revert(#8f79ee0): remove unused/deprecated components This reverts commit 8f79ee0. * feat(general): general deletion/cleanup of deprecated components * chore(lint): linting and formatting
- Loading branch information
1 parent
d4ef2d8
commit aacd957
Showing
74 changed files
with
1,138 additions
and
1,309 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
'use server' | ||
import { firestore } from 'firebase-admin' | ||
import { initializeAdminApp } from 'Admin/utils/firebase' | ||
import { TBoard, TBoardID } from 'types/settings' | ||
import { TTile } from 'types/tile' | ||
|
||
initializeAdminApp() | ||
|
||
export async function getBoard(bid: TBoardID) { | ||
const board = await firestore().collection('boards').doc(bid).get() | ||
return { id: board.id, ...board.data() } as TBoard | ||
} | ||
|
||
export async function addTile(bid: TBoardID, tile: TTile) { | ||
await firestore() | ||
.collection('boards') | ||
.doc(bid) | ||
.update({ | ||
tiles: firestore.FieldValue.arrayUnion(tile), | ||
'meta.dateModified': Date.now(), | ||
}) | ||
} |
13 changes: 13 additions & 0 deletions
13
next-tavla/app/(admin)/edit/[id]/components/MetaSettings/actions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
'use server' | ||
import { initializeAdminApp } from 'Admin/utils/firebase' | ||
import { firestore } from 'firebase-admin' | ||
import { revalidatePath } from 'next/cache' | ||
import { TMeta } from 'types/meta' | ||
import { TBoardID } from 'types/settings' | ||
|
||
initializeAdminApp() | ||
|
||
export async function saveMeta(bid: TBoardID, meta: TMeta) { | ||
await firestore().collection('boards').doc(bid).update({ meta: meta }) | ||
revalidatePath(`/edit/${bid}`) | ||
} |
60 changes: 60 additions & 0 deletions
60
next-tavla/app/(admin)/edit/[id]/components/MetaSettings/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
'use client' | ||
import classes from './styles.module.css' | ||
import { Button } from '@entur/button' | ||
import { ChoiceChip, ChoiceChipGroup } from '@entur/chip' | ||
import { TextField } from '@entur/form' | ||
import { Heading4 } from '@entur/typography' | ||
import { DEFAULT_BOARD_NAME } from 'Admin/utils/constants' | ||
import { useState } from 'react' | ||
import { TFontSize, TMeta } from 'types/meta' | ||
import { saveMeta } from './actions' | ||
import { TBoardID } from 'types/settings' | ||
|
||
function MetaSettings({ bid, meta }: { bid: TBoardID; meta: TMeta }) { | ||
const [font, setFont] = useState('medium') | ||
return ( | ||
<form | ||
action={(data: FormData) => { | ||
const name = data.get('name') as string | ||
const font = data.get('font') as TFontSize | ||
saveMeta(bid, { | ||
...meta, | ||
title: name, | ||
fontSize: font, | ||
dateModified: Date.now(), | ||
}) | ||
}} | ||
className={classes.meta} | ||
> | ||
<div className="flexRow justifyBetween alignCenter p-2"> | ||
<div className="w-100"> | ||
<Heading4>Navn på tavlen</Heading4> | ||
<TextField | ||
name="name" | ||
className="w-30" | ||
defaultValue={meta.title ?? DEFAULT_BOARD_NAME} | ||
label="Navn på tavlen" | ||
/> | ||
</div> | ||
<div className="flexColumn g-1"> | ||
<Heading4>Velg tekststørrelse: </Heading4> | ||
<ChoiceChipGroup | ||
className="flexRow" | ||
name="font" | ||
value={font} | ||
onChange={(e) => setFont(e.target.value)} | ||
> | ||
<ChoiceChip value="small">Liten</ChoiceChip> | ||
<ChoiceChip value="medium">Medium</ChoiceChip> | ||
<ChoiceChip value="large">Stor</ChoiceChip> | ||
</ChoiceChipGroup> | ||
</div> | ||
</div> | ||
<Button className="m-2" variant="secondary" type="submit"> | ||
Lagre navn og tekststørrelse | ||
</Button> | ||
</form> | ||
) | ||
} | ||
|
||
export { MetaSettings } |
5 changes: 5 additions & 0 deletions
5
next-tavla/app/(admin)/edit/[id]/components/MetaSettings/styles.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.meta { | ||
border-radius: 0.5em; | ||
background: var(--secondary-background-color); | ||
padding: 1em; | ||
} |
38 changes: 38 additions & 0 deletions
38
next-tavla/app/(admin)/edit/[id]/components/TileCard/LineCheckbox.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Checkbox } from '@entur/form' | ||
import { TTransportMode } from 'types/graphql-schema' | ||
import { TTile } from 'types/tile' | ||
import classes from './styles.module.css' | ||
import { TLineFragment } from './types' | ||
|
||
function LineCheckbox({ | ||
tile, | ||
line, | ||
transportMode, | ||
}: { | ||
tile: TTile | ||
line: TLineFragment | ||
transportMode: TTransportMode | null | ||
}) { | ||
return ( | ||
<Checkbox | ||
name={`${tile.uuid}-${transportMode}`} | ||
defaultChecked={ | ||
!tile.whitelistedLines || | ||
tile.whitelistedLines.length === 0 || | ||
tile.whitelistedLines.includes(line.id) | ||
} | ||
key={line.id} | ||
value={line.id} | ||
className="pl-3" | ||
> | ||
<div className="flexRow alignCenter g-1"> | ||
<PublicCode publicCode={line.publicCode} /> | ||
{line.name} | ||
</div> | ||
</Checkbox> | ||
) | ||
} | ||
function PublicCode({ publicCode }: { publicCode: string | null }) { | ||
return <div className={classes.publicCode}>{publicCode}</div> | ||
} | ||
export { LineCheckbox } |
45 changes: 45 additions & 0 deletions
45
next-tavla/app/(admin)/edit/[id]/components/TileCard/TransportModeCheckbox.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { TTransportMode } from 'types/graphql-schema' | ||
import { TTile } from 'types/tile' | ||
import { TransportIcon } from 'components/TransportIcon' | ||
import { transportModeNames } from './utils' | ||
import { Checkbox } from '@entur/form' | ||
|
||
function TransportModeCheckbox({ | ||
tile, | ||
transportMode, | ||
}: { | ||
tile: TTile | ||
transportMode: TTransportMode | null | ||
}) { | ||
return ( | ||
<div> | ||
<div className="flexRow g-2 alignCenter justifyStart"> | ||
<TransportIcon | ||
transportMode={transportMode} | ||
className="w-4 h-4" | ||
/> | ||
{transportModeNames(transportMode)} | ||
</div> | ||
<div className="flexRow alignCenter"> | ||
<Checkbox | ||
defaultChecked={ | ||
!tile.whitelistedLines || | ||
tile.whitelistedLines.length === 0 | ||
} | ||
onChange={(e) => { | ||
document | ||
.getElementsByName(`${tile.uuid}-${transportMode}`) | ||
.forEach((input) => { | ||
if (input instanceof HTMLInputElement) | ||
input.checked = e.currentTarget.checked | ||
}) | ||
}} | ||
> | ||
Velg alle | ||
</Checkbox> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
export { TransportModeCheckbox } |
35 changes: 35 additions & 0 deletions
35
next-tavla/app/(admin)/edit/[id]/components/TileCard/actions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
'use server' | ||
import { firestore } from 'firebase-admin' | ||
import { initializeAdminApp } from 'Admin/utils/firebase' | ||
import { TBoard, TBoardID } from 'types/settings' | ||
import { TTile } from 'types/tile' | ||
import { revalidatePath } from 'next/cache' | ||
|
||
initializeAdminApp() | ||
|
||
export async function deleteTile(bid: TBoardID, tile: TTile) { | ||
await firestore() | ||
.collection('boards') | ||
.doc(bid) | ||
.update({ | ||
tiles: firestore.FieldValue.arrayRemove(tile), | ||
'meta.dateModified': Date.now(), | ||
}) | ||
revalidatePath(`/edit/${bid}`) | ||
} | ||
|
||
export async function saveTile(bid: TBoardID, tile: TTile) { | ||
const docRef = firestore().collection('boards').doc(bid) | ||
const doc = (await docRef.get()).data() as TBoard | ||
const oldTile = doc.tiles.find((t) => t.uuid === tile.uuid) | ||
if (!oldTile) | ||
return docRef.update({ | ||
tiles: firestore.FieldValue.arrayUnion(tile), | ||
'meta.dateModified': Date.now(), | ||
}) | ||
const index = doc.tiles.indexOf(oldTile) | ||
doc.tiles[index] = tile | ||
docRef.update({ tiles: doc.tiles, 'meta.dateModified': Date.now() }) | ||
|
||
revalidatePath(`/edit/${bid}`) | ||
} |
144 changes: 144 additions & 0 deletions
144
next-tavla/app/(admin)/edit/[id]/components/TileCard/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
'use client' | ||
import { BaseExpand } from '@entur/expand' | ||
import classes from './styles.module.css' | ||
import { TTile } from 'types/tile' | ||
import { Button, SecondarySquareButton } from '@entur/button' | ||
import { DeleteIcon, EditIcon, CloseIcon } from '@entur/icons' | ||
import { useState } from 'react' | ||
import { TBoardID } from 'types/settings' | ||
import { Heading3, Heading4, SubParagraph } from '@entur/typography' | ||
import { isArray, uniqBy } from 'lodash' | ||
import { TransportIcon } from 'components/TransportIcon' | ||
import { Columns } from 'types/column' | ||
import { FilterChip } from '@entur/chip' | ||
import { TColumn } from 'types/column' | ||
import { useLines } from './useLines' | ||
import { sortLineByPublicCode } from './utils' | ||
import { deleteTile, saveTile } from './actions' | ||
import { TransportModeCheckbox } from './TransportModeCheckbox' | ||
import { LineCheckbox } from './LineCheckbox' | ||
import { HiddenInput } from 'components/Form/HiddenInput' | ||
|
||
function TileCard({ bid, tile }: { bid: TBoardID; tile: TTile }) { | ||
const [isOpen, setIsOpen] = useState(false) | ||
const lines = useLines(tile) | ||
|
||
if (!lines) return <div className={classes.card}>Laster..</div> | ||
|
||
const transportModes = uniqBy(lines, 'transportMode') | ||
.map((l) => l.transportMode) | ||
.sort() | ||
|
||
const linesByModeSorted = transportModes | ||
.map((transportMode) => ({ | ||
transportMode, | ||
lines: lines | ||
.filter((line) => line.transportMode === transportMode) | ||
.sort(sortLineByPublicCode), | ||
})) | ||
.sort((a, b) => b.lines.length - a.lines.length) | ||
|
||
return ( | ||
<div> | ||
<div className={classes.card}> | ||
<div className="flexRow g-2 alignCenter"> | ||
<div className="flexRow g-2 h-4"> | ||
{transportModes.map((tm) => ( | ||
<TransportIcon transportMode={tm} key={tm} /> | ||
))} | ||
</div> | ||
{tile.name} | ||
</div> | ||
<div className="flexRow g-2"> | ||
<SecondarySquareButton | ||
onClick={async () => { | ||
await deleteTile(bid, tile) | ||
}} | ||
> | ||
<DeleteIcon /> | ||
</SecondarySquareButton> | ||
<SecondarySquareButton onClick={() => setIsOpen(!isOpen)}> | ||
{isOpen ? <CloseIcon /> : <EditIcon />} | ||
</SecondarySquareButton> | ||
</div> | ||
</div> | ||
<BaseExpand open={isOpen}> | ||
<form | ||
action={(data: FormData) => { | ||
const columns = data.getAll('columns') as TColumn[] | ||
data.delete('columns') | ||
const count = data.get('count') as number | null | ||
data.delete('count') | ||
|
||
let lines: string[] = [] | ||
for (const line of data.values()) { | ||
lines.push(line as string) | ||
} | ||
// If the length of lines equals all the lines, we don't want to include any | ||
lines = lines.length == count ? [] : lines | ||
|
||
saveTile(bid, { | ||
...tile, | ||
columns: columns, | ||
whitelistedLines: lines, | ||
}) | ||
}} | ||
onSubmit={() => setIsOpen(false)} | ||
> | ||
<Heading3>Rediger stoppested: {tile.name}</Heading3> | ||
<Heading4>Tabellen</Heading4> | ||
<SubParagraph> | ||
Her bestemmer du hvilke kolonner som skal vises i | ||
tavlen. | ||
</SubParagraph> | ||
<div className="flexRow g-2"> | ||
{Object.entries(Columns).map(([key, value]) => { | ||
return ( | ||
<FilterChip | ||
name="columns" | ||
key={key} | ||
value={key} | ||
defaultChecked={ | ||
isArray(tile.columns) | ||
? tile.columns?.includes( | ||
key as TColumn, | ||
) | ||
: false | ||
} | ||
> | ||
{value} | ||
</FilterChip> | ||
) | ||
})} | ||
</div> | ||
<Heading4>Velg transportmidler og linjer</Heading4> | ||
<div className="flexRow g-2"> | ||
{linesByModeSorted.map(({ transportMode, lines }) => ( | ||
<div key={transportMode}> | ||
<TransportModeCheckbox | ||
tile={tile} | ||
transportMode={transportMode} | ||
/> | ||
{lines.map((line) => ( | ||
<LineCheckbox | ||
key={line.id} | ||
tile={tile} | ||
line={line} | ||
transportMode={transportMode} | ||
/> | ||
))} | ||
</div> | ||
))} | ||
</div> | ||
<HiddenInput id="count" value={lines.length.toString()} /> | ||
<div className="flexRow justifyEnd mt-2 mr-2 mb-4"> | ||
<Button variant="primary" type="submit"> | ||
Lagre endringer | ||
</Button> | ||
</div> | ||
</form> | ||
</BaseExpand> | ||
</div> | ||
) | ||
} | ||
export { TileCard } |
14 changes: 14 additions & 0 deletions
14
next-tavla/app/(admin)/edit/[id]/components/TileCard/styles.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.card { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
background: var(--secondary-background-color); | ||
border-radius: 0.5em; | ||
padding: 1em; | ||
} | ||
|
||
.publicCode { | ||
background-color: var(--tertiary-background-color); | ||
padding: 0.35em 0.5em; | ||
border-radius: 0.5em; | ||
} |
File renamed without changes.
Oops, something went wrong.