Skip to content

Commit 2dfd1da

Browse files
committed
feat: add logistics-manager-app and codelab
1 parent 7cc11ef commit 2dfd1da

28 files changed

Lines changed: 2266 additions & 0 deletions

logistics-manager-app/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# LogisticsManagerApp
2+
3+
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.3.
4+
5+
## Development server
6+
7+
To start a local development server, run:
8+
9+
```bash
10+
ng serve
11+
```
12+
13+
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
14+
15+
## Code scaffolding
16+
17+
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
18+
19+
```bash
20+
ng generate component component-name
21+
```
22+
23+
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
24+
25+
```bash
26+
ng generate --help
27+
```
28+
29+
## Building
30+
31+
To build the project run:
32+
33+
```bash
34+
ng build
35+
```
36+
37+
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
38+
39+
## Running unit tests
40+
41+
To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command:
42+
43+
```bash
44+
ng test
45+
```
46+
47+
## Running end-to-end tests
48+
49+
For end-to-end (e2e) testing, run:
50+
51+
```bash
52+
ng e2e
53+
```
54+
55+
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
56+
57+
## Additional Resources
58+
59+
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.

logistics-manager-app/angular.json

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
{
2+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3+
"version": 1,
4+
"cli": {
5+
"packageManager": "npm",
6+
"analytics": "92aff428-663f-4e57-81e2-e48c9a90c907"
7+
},
8+
"newProjectRoot": "projects",
9+
"projects": {
10+
"logistics-manager-app": {
11+
"projectType": "application",
12+
"schematics": {
13+
"@schematics/angular:component": {
14+
"inlineTemplate": true,
15+
"inlineStyle": true,
16+
"skipTests": true
17+
},
18+
"@schematics/angular:class": {
19+
"skipTests": true
20+
},
21+
"@schematics/angular:directive": {
22+
"skipTests": true
23+
},
24+
"@schematics/angular:guard": {
25+
"skipTests": true
26+
},
27+
"@schematics/angular:interceptor": {
28+
"skipTests": true
29+
},
30+
"@schematics/angular:pipe": {
31+
"skipTests": true
32+
},
33+
"@schematics/angular:resolver": {
34+
"skipTests": true
35+
},
36+
"@schematics/angular:service": {
37+
"skipTests": true
38+
}
39+
},
40+
"root": "",
41+
"sourceRoot": "src",
42+
"prefix": "app",
43+
"architect": {
44+
"build": {
45+
"builder": "@angular/build:application",
46+
"options": {
47+
"browser": "src/main.ts",
48+
"tsConfig": "tsconfig.app.json",
49+
"assets": [
50+
{
51+
"glob": "**/*",
52+
"input": "public"
53+
}
54+
],
55+
"styles": [
56+
"src/styles.css"
57+
],
58+
"server": "src/main.server.ts",
59+
"outputMode": "server",
60+
"ssr": {
61+
"entry": "src/server.ts"
62+
}
63+
},
64+
"configurations": {
65+
"production": {
66+
"budgets": [
67+
{
68+
"type": "initial",
69+
"maximumWarning": "500kB",
70+
"maximumError": "1MB"
71+
},
72+
{
73+
"type": "anyComponentStyle",
74+
"maximumWarning": "4kB",
75+
"maximumError": "8kB"
76+
}
77+
],
78+
"outputHashing": "all"
79+
},
80+
"development": {
81+
"optimization": false,
82+
"extractLicenses": false,
83+
"sourceMap": true
84+
}
85+
},
86+
"defaultConfiguration": "production"
87+
},
88+
"serve": {
89+
"builder": "@angular/build:dev-server",
90+
"configurations": {
91+
"production": {
92+
"buildTarget": "logistics-manager-app:build:production"
93+
},
94+
"development": {
95+
"buildTarget": "logistics-manager-app:build:development"
96+
}
97+
},
98+
"defaultConfiguration": "development"
99+
}
100+
}
101+
}
102+
}
103+
}

logistics-manager-app/codelab.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Codelab: Enhancing Obsidian Logistics with AI
2+
3+
Welcome to the Obsidian Logistics AI Codelab! In this guide, you'll learn how to take a modern Angular logistics dashboard and supercharge it with AI capabilities using the Gemini CLI, specialized skills, and the Model Context Protocol (MCP).
4+
5+
---
6+
7+
## Prerequisites
8+
9+
Before you begin, ensure you have the following installed:
10+
- [Node.js](https://nodejs.org/) (v20 or higher)
11+
- [Angular CLI](https://angular.dev/tools/cli) (`npm install -g @angular/cli`)
12+
- [Gemini CLI](https://github.com/google-gemini/gemini-cli)
13+
14+
---
15+
16+
## Step 0: Environment Setup
17+
18+
First, let's prepare your workspace and tools.
19+
20+
### 1. Project Initialization
21+
Navigate to the project root and install the dependencies:
22+
```bash
23+
cd logistics-manager-app
24+
npm install
25+
```
26+
27+
### 2. Install Gemini CLI Skills
28+
Skills provide the agent with specialized knowledge. We'll add the `angular-developer` and `gemini-sdk` skills to help with code generation and API integration.
29+
```bash
30+
# Add Angular expertise
31+
gemini skills install https://github.com/google-gemini/angular-developer --scope project
32+
33+
# Add Gemini SDK expertise
34+
gemini skills install https://github.com/google-gemini/gemini-sdk --scope project
35+
```
36+
37+
### 3. Configure MCP Servers
38+
The Model Context Protocol (MCP) allows your AI tools to interact with your running application and the browser.
39+
40+
#### Angular MCP Server
41+
This server allows the AI to understand your Angular project structure, components, and services.
42+
```bash
43+
gemini mcp add angular npx -y @modelcontextprotocol/server-angular --scope project
44+
```
45+
46+
#### Chrome DevTools MCP Server
47+
This allows the AI to inspect the running application in your browser for debugging and UI analysis.
48+
```bash
49+
gemini mcp add chromedevtools npx -y @modelcontextprotocol/server-chromedevtools --scope project
50+
```
51+
52+
---
53+
54+
## Enhancement 1: AI-Powered Fleet Chat
55+
56+
The `app-chat` component is currently a UI shell. Your task is to implement the backend and frontend logic to allow users to ask natural language questions about the fleet.
57+
58+
### The Goal
59+
A user should be able to type: *"Which units are currently in critical status and have less than 10% battery?"* and receive a concise list.
60+
61+
### Implementation Steps
62+
1. **Service Integration**: Update `FleetService` to include a `queryFleet(prompt: string)` method.
63+
2. **AI Logic**: Use the `gemini-sdk` skill to generate a prompt that sends the current `units()` state to Gemini and asks it to filter the data based on the user's input.
64+
3. **UI Binding**: Connect the chat input and message list in `chat.ts` to the `FleetService`.
65+
66+
---
67+
68+
## Enhancement 2: Intelligent Service Prioritization
69+
70+
Currently, users manually select a priority when creating a service ticket. Let's automate this using AI analysis of the issue description.
71+
72+
### The Goal
73+
When a user describes an issue like *"The vehicle is emitting smoke and the engine has stopped,"* the AI should automatically set the priority to `CRITICAL`.
74+
75+
### Implementation Steps
76+
1. **Form Hook**: In `service-queue.ts`, add a listener to the `issue` field in the `serviceForm`.
77+
2. **AI Analysis**: Create a small utility that sends the issue text to Gemini with a system prompt: *"Analyze this logistics vehicle issue and return one of: LOW, MEDIUM, HIGH, CRITICAL."*
78+
3. **Auto-update**: Use the result to update the `priority` field in the form automatically as the user types or on blur.
79+
80+
---
81+
82+
## Enhancement 3: Predictive Battery Health Diagnostics
83+
84+
Add a "Run Diagnostic" feature to the vehicle detail view that predicts potential failures before they happen.
85+
86+
### The Goal
87+
In the `FleetDetailModal`, provide a "Run AI Diagnostic" button. When clicked, it analyzes the unit's `speed`, `battery`, and `status` history to provide a "Health Score" and a "Recommended Action."
88+
89+
### Implementation Steps
90+
1. **Diagnostic Action**: Add a button to the `FleetDetailModal` template.
91+
2. **Telemetry Payload**: Gather the `FleetUnit` data and any historical trends (if available in `fleet-db.ts`).
92+
3. **AI Insight**: Send this telemetry to Gemini to generate a report.
93+
- Example prompt: *"Analyze this unit: Speed 102km/h, Battery 14% (Declining rapidly), Status: Transit. Predict potential failure points."*
94+
4. **Result Display**: Show the AI's response in a new "Diagnostics" section within the modal.
95+
96+
---
97+
98+
## Running the App
99+
100+
To see your changes in action, start the development server:
101+
```bash
102+
npm run start
103+
```
104+
The app will be available at `http://localhost:4200`.
105+
106+
---
107+
108+
## Summary
109+
By completing these enhancements, you've transformed a static dashboard into an intelligent command center. You've leveraged:
110+
- **Angular Signals** for reactive state management.
111+
- **Gemini CLI Skills** for expert-level coding assistance.
112+
- **MCP Servers** for deep integration between your AI and your workspace.

logistics-manager-app/package.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"name": "logistics-manager-app",
3+
"version": "0.0.0",
4+
"scripts": {
5+
"ng": "ng",
6+
"start": "ng serve",
7+
"build": "ng build",
8+
"watch": "ng build --watch --configuration development",
9+
"serve:ssr:logistics-manager-app": "node dist/logistics-manager-app/server/server.mjs"
10+
},
11+
"prettier": {
12+
"printWidth": 100,
13+
"singleQuote": true,
14+
"overrides": [
15+
{
16+
"files": "*.html",
17+
"options": {
18+
"parser": "angular"
19+
}
20+
}
21+
]
22+
},
23+
"private": true,
24+
"packageManager": "npm@10.9.3",
25+
"dependencies": {
26+
"@angular/aria": "^21.2.5",
27+
"@angular/common": "^21.1.0",
28+
"@angular/compiler": "^21.1.0",
29+
"@angular/core": "^21.1.0",
30+
"@angular/forms": "^21.1.0",
31+
"@angular/platform-browser": "^21.1.0",
32+
"@angular/platform-server": "^21.1.0",
33+
"@angular/router": "^21.1.0",
34+
"@angular/ssr": "^21.1.3",
35+
"express": "^5.1.0",
36+
"leaflet": "^1.9.4",
37+
"rxjs": "~7.8.0",
38+
"tslib": "^2.3.0"
39+
},
40+
"devDependencies": {
41+
"@angular/build": "^21.1.3",
42+
"@angular/cli": "^21.1.3",
43+
"@angular/compiler-cli": "^21.1.0",
44+
"@tailwindcss/postcss": "^4.1.12",
45+
"@types/express": "^5.0.1",
46+
"@types/leaflet": "^1.9.21",
47+
"@types/node": "^20.17.19",
48+
"jsdom": "^27.1.0",
49+
"postcss": "^8.5.3",
50+
"tailwindcss": "^4.1.12",
51+
"typescript": "~5.9.2",
52+
"vitest": "^4.0.8"
53+
}
54+
}
14.7 KB
Binary file not shown.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
2+
import { provideServerRendering, withRoutes } from '@angular/ssr';
3+
import { appConfig } from './app.config';
4+
import { serverRoutes } from './app.routes.server';
5+
6+
const serverConfig: ApplicationConfig = {
7+
providers: [
8+
provideServerRendering(withRoutes(serverRoutes))
9+
]
10+
};
11+
12+
export const config = mergeApplicationConfig(appConfig, serverConfig);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
2+
import { provideRouter } from '@angular/router';
3+
import { provideHttpClient, withFetch } from '@angular/common/http';
4+
5+
import { routes } from './app.routes';
6+
import { provideClientHydration, withEventReplay } from '@angular/platform-browser';
7+
8+
export const appConfig: ApplicationConfig = {
9+
providers: [
10+
provideBrowserGlobalErrorListeners(),
11+
provideRouter(routes),
12+
provideClientHydration(withEventReplay()),
13+
provideHttpClient(withFetch())
14+
]
15+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { RenderMode, ServerRoute } from '@angular/ssr';
2+
3+
export const serverRoutes: ServerRoute[] = [
4+
{
5+
path: '**',
6+
renderMode: RenderMode.Prerender
7+
}
8+
];
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Routes } from '@angular/router';
2+
import { Dashboard } from './components/dashboard/dashboard';
3+
import { FleetList } from './components/fleet-list/fleet-list';
4+
import { ServiceQueue } from './components/service-queue/service-queue';
5+
6+
export const routes: Routes = [
7+
{ path: '', component: Dashboard },
8+
{ path: 'fleet', component: FleetList },
9+
{ path: 'service-queue', component: ServiceQueue }
10+
];
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Component } from '@angular/core';
2+
import { RouterOutlet } from '@angular/router';
3+
import { Header } from './components/header/header';
4+
import { Chat } from './components/chat/chat';
5+
6+
@Component({
7+
selector: 'app-root',
8+
imports: [Header, RouterOutlet, Chat],
9+
host: {
10+
'class': 'flex flex-col h-full w-full relative'
11+
},
12+
template: `
13+
<app-header />
14+
<router-outlet />
15+
<app-chat />
16+
`
17+
})
18+
export class App {}

0 commit comments

Comments
 (0)