Skip to content

Commit

Permalink
Frontend update 623ab16 (#181)
Browse files Browse the repository at this point in the history
* update: frontend from tanega repo commit: #623ab16
https://github.com/tanega/trailwatch-front-kickoff

* feat: frontend ignore public data geometries

* fix: Docker frontend code volume share removed because of building files missing

Because frontend needs frontend build that is done during building docker, mounting volume for dev removes this building
Entrytpoint could be modified to detect that frontend needs to be rebuild but for the moment, removing volume mounting to assure frontend works

* feat: amélioration du docker frontend, Dockerfile séparé

# Conflicts:
#	docker/Dockerfile

* fix: frontend missing map-store

* fix: fix load data to use bloom/tasks (loading positions missing)

# Conflicts:
#	docker-compose-load-data.yaml

* update: frontend from tanega repo commit: #623ab16
https://github.com/tanega/trailwatch-front-kickoff

* fix: Docker frontend code volume share removed because of building files missing

Because frontend needs frontend build that is done during building docker, mounting volume for dev removes this building
Entrytpoint could be modified to detect that frontend needs to be rebuild but for the moment, removing volume mounting to assure frontend works

# Conflicts:
#	docker-compose.yaml

* feat: amélioration du docker frontend, Dockerfile séparé

# Conflicts:
#	docker-compose.yaml

* fix: docker compose files double volumes

---------

Co-authored-by: herve.le-bars <herve.le-bars@aviation-civile.gouv.fr>
  • Loading branch information
rv2931 and herve.le-bars authored Jun 20, 2024
1 parent bb21644 commit 3059bb9
Show file tree
Hide file tree
Showing 283 changed files with 4,251 additions and 179 deletions.
2 changes: 1 addition & 1 deletion docker-compose-load-data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ x-common-infos:
services:
load-data:
container_name: bloom-load-data
image: d4g/bloom:${VERSION:-latest}
image: d4g/bloom-backend:${VERSION:-latest}
entrypoint: /bin/bash
# Nominal start:
command:
Expand Down
35 changes: 23 additions & 12 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ services:
bloom-backend:
container_name: bloom_backend
hostname: bloom-backend
image: d4g/bloom:${VERSION:-latest}
image: d4g/bloom-backend:${VERSION:-latest}
working_dir: /project/backend
command:
- bash
Expand Down Expand Up @@ -59,10 +59,10 @@ services:
<<: *common-env
ports:
- ${POSTGRES_PORT:-5432}:5432
networks:
- bloom_net
volumes:
- bloom-data:/var/lib/postgresql/data
networks:
- bloom_net
healthcheck:
# PostGis database initialization is done with two steps (postgres+postgis)
# This causes healthcheck to be valid before real full initialization
Expand All @@ -83,11 +83,26 @@ services:
bloom-frontend:
container_name: bloom_frontend
hostname: bloom-frontend
image: d4g/bloom:${VERSION:-latest}
command: env node ./node_modules/next/dist/bin/next start --hostname 0.0.0.0
working_dir: /project/frontend
image: d4g/bloom-frontend:${VERSION:-latest}
#command: env node ./node_modules/next/dist/bin/next start --hostname 0.0.0.0
#command: npm run dev
#command: yarn dev
command: sh -c "if [ ! -f node_modules/next/dist/bin/next ]; then npm install && npm run build; fi; npm run dev"
tty: true
stdin_open: true
working_dir: /app
build:
context: .
dockerfile: ./docker/frontend/dev.Dockerfile
args:
APP_DIR: /app

volumes:
- ./:/project/
#- ./frontend:/app
#- ./frontend/node_modules:/app/node_modules
#- ./frontend/.next:/app/.next
- ./data:/app/public/data
# - ./:/project/
- ./data:/project/frontend/public/data
environment:
LOGGING_LEVEL: ${LOGGING_LEVEL:-INFO}
Expand All @@ -102,13 +117,9 @@ services:
bloom-init:
container_name: bloom_init
hostname: bloom-init
image: d4g/bloom:${VERSION:-latest}
image: d4g/bloom-backend:${VERSION:-latest}

# Nominal start:
# As postgres+postgis gt available, then unavialable, then avialable at database init
# it happens that init is launch before second and definitve postgres healthy state
# and fails
# so giving init 3 chances and 15 seconds to init before failing
command: /bin/bash -c "cd backend;alembic upgrade head"
# Debug start:
#command: bash
Expand Down
34 changes: 34 additions & 0 deletions docker/frontend/dev.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
FROM node:18-alpine
ARG APP_DIR=/app

WORKDIR ${APP_DIR}

# Install dependencies based on the preferred package manager
COPY frontend/package.json frontend/yarn.lock* frontend/package-lock.json* frontend/pnpm-lock.yaml* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i; \
# Allow install without lockfile, so example works even without Node.js installed locally
else echo "Warning: Lockfile not found. It is recommended to commit lockfiles to version control." && yarn install; \
fi

COPY frontend/. .
#COPY frontend/app frontend/components frontend/config frontend/lib frontend/styles frontend/types .
#COPY frontend/public public
#COPY frontend/next.config.mjs .
#COPY frontend/tsconfig.json .

# Next.js collects completely anonymous telemetry data about general usage. Learn more here: https://nextjs.org/telemetry
# Uncomment the following line to disable telemetry at run time
# ENV NEXT_TELEMETRY_DISABLED 1

# Note: Don't expose ports here, Compose will handle that for us

# Start Next.js in development mode based on the preferred package manager
CMD \
if [ -f yarn.lock ]; then yarn dev; \
elif [ -f package-lock.json ]; then npm run dev; \
elif [ -f pnpm-lock.yaml ]; then pnpm dev; \
else npm run dev; \
fi
3 changes: 3 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# data
public/data/geometries/

# dependencies
node_modules
.pnp
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function RootLayout({ children }: RootLayoutProps) {
rel="stylesheet"
/>
</head>
<body className="font-unito relative flex h-screen min-h-screen w-full flex-row antialiased">
<body className="relative flex h-screen min-h-screen w-full flex-row font-unito antialiased">
<ThemeProvider attribute="class" defaultTheme="light">
<main className="flex-1 flex-col">{children}</main>
</ThemeProvider>
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/map/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { MapStoreProvider } from "@/components/providers/map-store-provider"

export const metadata: Metadata = {
title: {
default: "Trailwatch Map",
default: "TrawlWatch Map",
template: `%s - ${siteConfig.name}`,
},
description: siteConfig.description,
Expand Down
2 changes: 2 additions & 0 deletions frontend/app/map/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import LeftPanel from "@/components/core/left-panel"
import MapControls from "@/components/core/map-controls"
import DemoMap from "@/components/core/map/main-map"
import PositionPreview from "@/components/core/map/position-preview"

export default function MapPage() {
return (
<>
<LeftPanel />
<DemoMap />
<MapControls />
<PositionPreview />
</>
)
}
130 changes: 130 additions & 0 deletions frontend/components/core/command/vessel-finder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"use client"

import { useState } from "react"
import allVessels from "@/public/data/geometries/all_vessels_with_mmsi.json"
import latestPositions from "@/public/data/geometries/vessels_latest_positions.json"
import { FlyToInterpolator } from "deck.gl"
import { ShipIcon } from "lucide-react"

import { Vessel } from "@/types/vessel"
import {
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/components/ui/command"
import { useMapStore } from "@/components/providers/map-store-provider"

import { VesselPosition } from "../map/main-map"

type Props = {
wideMode: boolean
}

const SEPARATOR = "___"

export function VesselFinderDemo({ wideMode }: Props) {
const [open, setOpen] = useState(false)
const [search, setSearch] = useState<string>("")
const {
addTrackedVesselMMSI,
trackedVesselMMSIs,
setActivePosition,
viewState,
setViewState,
} = useMapStore((state) => state)

const onSelectVessel = (vesselIdentifier: string) => {
const mmsi = parseInt(vesselIdentifier.split(SEPARATOR)[1])
if (mmsi && !trackedVesselMMSIs.includes(mmsi)) {
addTrackedVesselMMSI(mmsi)
}
if (mmsi) {
const selectedVesselLatestPosition = latestPositions.find(
(position) => position.vessel_mmsi === mmsi
)
if (selectedVesselLatestPosition) {
setActivePosition(selectedVesselLatestPosition as VesselPosition)
setViewState({
...viewState,
longitude: selectedVesselLatestPosition.position_longitude,
latitude: selectedVesselLatestPosition.position_latitude,
zoom: 7,
pitch: 40,
transitionInterpolator: new FlyToInterpolator({ speed: 2 }),
transitionDuration: "auto",
})
}
}
setOpen(false)
}

return (
<>
<button
type="button"
className="dark:highlight-white/5 flex items-center rounded-md bg-color-3 py-1.5 pl-2 pr-3 text-sm leading-6 text-slate-400 shadow-sm ring-1 ring-color-2 hover:bg-slate-700 hover:ring-slate-300"
onClick={() => setOpen(true)}
>
<svg
width="24"
height="24"
fill="none"
aria-hidden="true"
className="mr-3 flex-none"
>
<path
d="m19 19-3.5-3.5"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
></path>
<circle
cx="11"
cy="11"
r="6"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
></circle>
</svg>
{wideMode && <>Find vessels...</>}
</button>

<CommandDialog open={open} onOpenChange={setOpen}>
<CommandInput
placeholder="Type MMSI, IMO or vessel name to search..."
value={search}
onValueChange={setSearch}
/>
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Vessels">
{allVessels.map((vessel: Vessel) => {
return (
<CommandItem
key={`${vessel.imo}-${vessel.name}`}
onSelect={(value) => onSelectVessel(value)}
value={`${vessel.name}${SEPARATOR}${vessel.mmsi}${SEPARATOR}${vessel.imo}`} // so we can search by name, mmsi, imo
>
<ShipIcon className="mr-2 size-4" />
<span>{vessel.name}</span>
<span className="ml-2 text-xxxs">
{" "}
MMSI {vessel.mmsi} | IMO {vessel.imo}
</span>
</CommandItem>
)
})}
</CommandGroup>
<CommandSeparator />
</CommandList>
</CommandDialog>
</>
)
}
39 changes: 15 additions & 24 deletions frontend/components/core/left-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@
import { useEffect, useState } from "react"
import Image from "next/image"
import TrawlWatchLogo from "@/public/trawlwatch.svg"
import {
ChartBarIcon,
ChartPieIcon,
DocumentCheckIcon,
MagnifyingGlassIcon,
Square2StackIcon,
UsersIcon,
} from "@heroicons/react/24/outline"
import { AnimatePresence, motion, useAnimationControls } from "framer-motion"
import { Ship as ShipIcon } from "lucide-react"
import { ChartBarIcon } from "@heroicons/react/24/outline"
import { motion, useAnimationControls } from "framer-motion"

import NavigationLink from "@/components/ui/navigation-link"
import { useMapStore } from "@/components/providers/map-store-provider"
import { VesselFinderDemo } from "@/components/core/command/vessel-finder"

import TrackedVesselsPanel from "./tracked-vessels-panel"

const containerVariants = {
close: {
Expand All @@ -31,7 +25,7 @@ const containerVariants = {
transition: {
type: "spring",
damping: 15,
duration: 0.5,
duration: 0.3,
},
},
}
Expand All @@ -47,8 +41,6 @@ const svgVariants = {

const LeftPanel = () => {
const [isOpen, setIsOpen] = useState(false)
const [selectedProject, setSelectedProject] = useState<string | null>(null)

const containerControls = useAnimationControls()
const svgControls = useAnimationControls()

Expand All @@ -64,7 +56,6 @@ const LeftPanel = () => {

const handleOpenClose = () => {
setIsOpen(!isOpen)
setSelectedProject(null)
}

return (
Expand All @@ -73,7 +64,7 @@ const LeftPanel = () => {
variants={containerVariants}
animate={containerControls}
initial="close"
className="absolute left-0 top-0 z-10 flex flex-col gap-3 overflow-auto rounded-br-lg bg-slate-800 shadow shadow-slate-600"
className="absolute left-0 top-0 z-10 flex max-h-screen flex-col gap-3 rounded-br-lg bg-color-3 shadow shadow-color-2"
>
<div className="flex w-full flex-row place-items-center justify-between p-5">
{!!isOpen && (
Expand Down Expand Up @@ -115,15 +106,15 @@ const LeftPanel = () => {
<ChartBarIcon className="w-8 min-w-8 stroke-inherit stroke-[0.75]" />
</NavigationLink>
</div>
<div className="flex flex-col gap-3 bg-slate-800 p-5">
<NavigationLink href="#" name="Find vesssels" wide={isOpen}>
<MagnifyingGlassIcon className="w-8 min-w-8 stroke-inherit stroke-[0.75]" />
</NavigationLink>
<div className="flex flex-col gap-3 bg-color-3 p-5">
<VesselFinderDemo wideMode={isOpen} />
</div>
<div className="flex flex-col gap-3 bg-slate-600 p-5">
<NavigationLink href="#" name="Selected vessel (0)" wide={isOpen}>
<ShipIcon className="w-8 min-w-8 stroke-inherit stroke-[0.75]" />
</NavigationLink>
<div className="flex flex-col gap-3 overflow-auto bg-color-3 p-5">
<TrackedVesselsPanel
wideMode={isOpen}
parentIsOpen={isOpen}
openParent={() => setIsOpen(true)}
/>
</div>
</motion.nav>
</>
Expand Down
Loading

0 comments on commit 3059bb9

Please sign in to comment.