Compare commits
No commits in common. "684b89b8fca55b07d86b3820cead5b38fb733f1e" and "b005193dbc387c63e0a608772bc470adf44f6281" have entirely different histories.
684b89b8fc
...
b005193dbc
|
|
@ -1,236 +0,0 @@
|
||||||
# Session Summary: Duimstok PWA MVP Build
|
|
||||||
|
|
||||||
**Date:** 2026-04-16
|
|
||||||
**Project:** ProRail Duimstok-inspecties Bovenbouw
|
|
||||||
**Repo:** https://git.en-masse.nl/randy/duimstok.prorail.nl.git
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 1: Monolithic HTML Refactor
|
|
||||||
|
|
||||||
**Goal:** Split a single-file app (`duimstok-wissel-gw-sw.html`, 1566 lines) into a layered DDD structure.
|
|
||||||
|
|
||||||
**What was done:**
|
|
||||||
- Created `src/Domain/`, `src/Application/`, `src/Infrastructure/` layers
|
|
||||||
- Converted ES modules to classic IIFE scripts attaching to `window.App.*` namespace
|
|
||||||
- Embedded CSV seed data as a string constant in `seedOrders.js` (no `fetch()` needed)
|
|
||||||
- Removed all inline styles (`style=""`) and inline event handlers (`onclick`, `oninput`, etc.)
|
|
||||||
- Replaced inline styles with CSS classes (`.flex-spacer`, `.cap-arrow.lg`, `.section-sub.sm`, `.fotonummers-cell`)
|
|
||||||
- Wired all event listeners via `addEventListener` in `main.js` and service modules
|
|
||||||
|
|
||||||
**Result:** 30 files, ~2163 lines. Runs by double-clicking `public/index.html` -- no server needed.
|
|
||||||
|
|
||||||
**File structure:**
|
|
||||||
|
|
||||||
```
|
|
||||||
01_Applicatie/
|
|
||||||
├── public/
|
|
||||||
│ ├── index.html
|
|
||||||
│ ├── css/ base.css, overview.css, form.css, modals.css, responsive.css
|
|
||||||
│ └── js/ namespace.js, main.js
|
|
||||||
└── src/
|
|
||||||
├── Domain/ sectionMap.js, scoring.js, orderParser.js
|
|
||||||
├── Application/ state.js, persistence.js, screens.js, photoService.js,
|
|
||||||
│ inspectionForm.js, orderOverview.js, xmlImport.js, exportService.js
|
|
||||||
└── Infrastructure/ utils.js, geolocation.js, db.js, seedOrders.js, csvLoader.js
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 2: PWA Research & Planning
|
|
||||||
|
|
||||||
**Prompt used:** "what are the next steps create a PWA version of this MVP, ideally with offline photo upload functionality which sync when back online. Whats the current supported state of PWA regarding these offline functionalities atm"
|
|
||||||
|
|
||||||
**Key findings:**
|
|
||||||
- Service Worker, Cache API, IndexedDB, Manifest, installability all work cross-browser (Chromium, Firefox, Safari/iOS 16.4+)
|
|
||||||
- Background Sync (`sync` event) only works on Chromium -- not Firefox, not Safari/iOS
|
|
||||||
- Periodic Background Sync: Chromium only (engagement-gated)
|
|
||||||
- Background Fetch: Chromium only
|
|
||||||
- Push notifications: universal for installed PWAs (iOS 16.4+)
|
|
||||||
- Persistent storage: universal, but Safari historically aggressive on eviction
|
|
||||||
|
|
||||||
**Key constraint:** iOS has no true background sync. Design around draining the queue when the user reopens the app and when the `online` event fires.
|
|
||||||
|
|
||||||
**6-step incremental plan identified:**
|
|
||||||
1. Installable shell (manifest + service worker cache)
|
|
||||||
2. Switch photo storage from data URLs to Blobs
|
|
||||||
3. Sync queue in IndexedDB
|
|
||||||
4. Trigger drain on every available signal (online event, app open, SW sync, manual button)
|
|
||||||
5. Persistent storage + install hint
|
|
||||||
6. Backend stub (Symfony controller for POST /api/inspections)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 3: PWA Scaffold Implementation
|
|
||||||
|
|
||||||
**Prompt used:** "Goal is still conversion later on to Symfony, but for now we do want the PWA functionality (add an additional installation and instruction screen for the PWA installation)"
|
|
||||||
|
|
||||||
**Constraint flagged:** PWA features require HTTPS or localhost -- they cannot work from `file://`.
|
|
||||||
|
|
||||||
**Resolution:** Dual-mode codebase:
|
|
||||||
- `file://` mode: app works exactly as before; PWA init gated by `location.protocol !== 'file:'` and quietly skipped
|
|
||||||
- `http://localhost` or deployed mode: service worker registers, app becomes installable, install screen shows platform-specific instructions
|
|
||||||
|
|
||||||
**Files created:**
|
|
||||||
- `public/manifest.webmanifest` -- app manifest with icons, standalone display, ProRail blue theme
|
|
||||||
- `public/sw.js` -- service worker with app shell precaching (cache-first for statics, network-first for API)
|
|
||||||
- `public/icons/icon.svg` -- SVG app icon (ProRail blue with white ruler lines)
|
|
||||||
- `public/css/install.css` -- styles for the install instruction screen
|
|
||||||
- `src/Application/pwa.js` -- service worker registration, `beforeinstallprompt` capture, standalone detection
|
|
||||||
- `src/Application/installScreen.js` -- platform-specific install instructions (Chrome/Edge, iOS Safari, Firefox, generic)
|
|
||||||
|
|
||||||
**HTML changes:**
|
|
||||||
- Added PWA meta tags (`theme-color`, `apple-mobile-web-app-capable`, manifest link, apple-touch-icon)
|
|
||||||
- Added "Installeren" button to overview toolbar
|
|
||||||
- Added `screen-install` section with back button and dynamic body
|
|
||||||
- Added `<link>` for `install.css`
|
|
||||||
- Added `<script>` tags for `pwa.js` and `installScreen.js`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 4: Git Repository Setup
|
|
||||||
|
|
||||||
**Prompt used:** "ini git repo and commit and push, add files and folders, repo https://git.en-masse.nl/randy/duimstok.prorail.nl.git" + "to the develop branch"
|
|
||||||
|
|
||||||
**Decisions made:**
|
|
||||||
- Repo root: `01_Applicatie/` (app code only; ProRail reference PDFs/photos stay outside)
|
|
||||||
- Deleted old monolithic files: `duimstok-wissel-gw-sw.html` and backup copy
|
|
||||||
- Created `.gitignore` (DS_Store, Thumbs.db, editors, node_modules, env files)
|
|
||||||
- Created `README.md` with project structure documentation
|
|
||||||
- Created `_docs/.gitkeep`
|
|
||||||
|
|
||||||
**Git Flow applied:**
|
|
||||||
1. Initialized repo with `develop` branch -- baseline commit (README, .gitignore, _docs/)
|
|
||||||
2. Created `feature/initial-pwa-scaffold` branch off develop
|
|
||||||
3. Committed all app code (30 files, 2163 insertions)
|
|
||||||
4. Pushed `develop` (baseline only, no staging deploy triggered)
|
|
||||||
5. Pushed `feature/initial-pwa-scaffold` (feature branch, no deploy implications)
|
|
||||||
6. Suggested PR creation on Forgejo before merging to develop
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 5: Photo Blob Storage Refactor
|
|
||||||
|
|
||||||
**Branch:** `feature/photo-blob-storage` (off `feature/initial-pwa-scaffold`)
|
|
||||||
|
|
||||||
**What changed:**
|
|
||||||
- Photos now stored as native `Blob` objects instead of base64 data URLs (~33% smaller)
|
|
||||||
- `photoSrc()` helper uses `URL.createObjectURL(blob)` for rendering thumbnails
|
|
||||||
- `URL.revokeObjectURL()` called on lightbox close and when replacing images (memory cleanup)
|
|
||||||
- Removed `readFileAsDataUrl()` from `utils.js` (no longer needed)
|
|
||||||
- Removed `dataUrlToBlob()` from `utils.js` (no longer needed)
|
|
||||||
- `db.js`: removed `JSON.parse(JSON.stringify(formData))` deep-clone -- IndexedDB handles Blobs natively
|
|
||||||
- `exportService.js`: downloads `p.blob` directly instead of converting from data URL
|
|
||||||
|
|
||||||
**Files changed:** `photoService.js`, `exportService.js`, `db.js`, `utils.js`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 6: CSV Upload Persistence
|
|
||||||
|
|
||||||
**Branch:** `feature/csv-upload-persistence`
|
|
||||||
|
|
||||||
**What changed:**
|
|
||||||
- New IndexedDB object store `ordersCsv` (DB version bumped 3 -> 4)
|
|
||||||
- `db.js`: added `saveOrdersCsv(csvText)` and `loadOrdersCsv()` functions
|
|
||||||
- `csvLoader.js`: `loadOrdersFromUpload()` now returns `{ text, orders }` so raw CSV text gets persisted
|
|
||||||
- `main.js` init: loads stored CSV from IndexedDB, falls back to embedded seed data if none stored
|
|
||||||
- `main.js` upload handler: saves CSV text to IndexedDB after parsing
|
|
||||||
|
|
||||||
**Files changed:** `db.js`, `csvLoader.js`, `main.js`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 7: Persistent Storage Request
|
|
||||||
|
|
||||||
**Branch:** `feature/persistent-storage-request`
|
|
||||||
|
|
||||||
**What changed:**
|
|
||||||
- New file `src/Infrastructure/persistentStorage.js` with `isPersisted()` and `requestPersistence()`
|
|
||||||
- Calls `navigator.storage.persist()` after the first successful save (reduces iOS eviction risk)
|
|
||||||
- One-time flag `persistenceRequested` prevents repeated calls
|
|
||||||
- Updated SW cache version to `duimstok-v2`
|
|
||||||
- Added `persistentStorage.js` to both `index.html` script tags and SW precache list
|
|
||||||
|
|
||||||
**Files changed/created:** `persistentStorage.js` (new), `persistence.js`, `sw.js`, `index.html`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 8: Multi-Inspection Type Scoping (Not Yet Implemented)
|
|
||||||
|
|
||||||
**Prompt used:** "continue with question 1: spoor en overweg in map C:\...\04_Gegenereerd door SAP_incl WW_xslx_xlm\XML"
|
|
||||||
|
|
||||||
**Research done:**
|
|
||||||
- Read `_docs/switch-inspection-diagram.md` -- confirms existing wissel_GW photo layout
|
|
||||||
- Read SAP XML templates for Spoor and Overwegbevloering from reference folders
|
|
||||||
- Identified 3 inspection types: Wissel, Overwegbevloering, Spoor
|
|
||||||
|
|
||||||
**Proposed scope for `feature/inspection-type-routing`:**
|
|
||||||
1. Routing layer that derives type from `order.objectsoort`
|
|
||||||
2. Three form panels in `index.html`, shown based on type
|
|
||||||
3. Wissel: no visual change (existing 10-slot layout)
|
|
||||||
4. Overwegbevloering: stub form with photos section, no wissel diagram
|
|
||||||
5. Spoor: stub form emphasizing start/end-KM fields from CSV
|
|
||||||
6. Export works for all three types
|
|
||||||
|
|
||||||
**Status:** Scoped, awaiting answers to 3 questions before implementation.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Global Rules Established
|
|
||||||
|
|
||||||
These rules were added to `~/.claude/CLAUDE.md` during the session:
|
|
||||||
|
|
||||||
| Rule | Context |
|
|
||||||
|------|---------|
|
|
||||||
| **No backwards compatibility in MVPs** | User corrected fallback code for old photo data format |
|
|
||||||
| **No `Co-Authored-By: Claude` in commits** | User interrupted a commit that included the attribution line |
|
|
||||||
| **Git Flow workflow** | User requested: develop = staging, master = production, feature branches for all work |
|
|
||||||
| **`_docs/` for project documentation** | User requested: all docs in project root `_docs/` folder |
|
|
||||||
| **`file://` runnable MVPs** | User requested: must work by opening `public/index.html` directly |
|
|
||||||
| **Vanilla HTML/JS/CSS, no frameworks** | Pre-existing rule (maps to eventual Symfony/Twig conversion) |
|
|
||||||
| **DDD folder structure** | Pre-existing rule (Domain/Application/Infrastructure layers) |
|
|
||||||
| **Forgejo at git.en-masse.nl** | User specified as default remote host |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Shortcuts & Commands Used
|
|
||||||
|
|
||||||
| Command/Action | Purpose | Times Used |
|
|
||||||
|----------------|---------|------------|
|
|
||||||
| `/usage` | Check token consumption | 2x |
|
|
||||||
| `continue` | Resume after idle or interruption | Multiple |
|
|
||||||
| `merge` | Trigger merge-to-develop flow | Multiple |
|
|
||||||
| `yes` / `1` / `3` | Quick selection from numbered options | Multiple |
|
|
||||||
| Interrupted commits | Added global rules mid-flow (no co-author, no backwards compat) | 3x |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Git History (Linear on develop)
|
|
||||||
|
|
||||||
```
|
|
||||||
b005193 Request persistent storage after first save
|
|
||||||
92ad6a9 Persist uploaded order CSVs across app restarts
|
|
||||||
e86aa5b Store photos as native Blobs instead of base64 data URLs
|
|
||||||
776bd63 Add PWA-ready MVP: split HTML/CSS/JS + DDD layering + service worker
|
|
||||||
367bbca Initial repo scaffold on develop
|
|
||||||
```
|
|
||||||
|
|
||||||
**Branch lifecycle:**
|
|
||||||
- All feature branches created off `develop` (or stacked off previous feature branch when develop was behind)
|
|
||||||
- All merged via fast-forward (`--ff-only`)
|
|
||||||
- All deleted (local + remote) after merge
|
|
||||||
- Only `develop` remains as active branch
|
|
||||||
- `master` not yet created (awaiting production readiness)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Open Items
|
|
||||||
|
|
||||||
- [ ] Manual verify: capture photo, render thumbnail, reload, check thumbnail persists, export produces valid JPG
|
|
||||||
- [ ] Manual verify: upload CSV, hard-reload, confirm modified orders still appear
|
|
||||||
- [ ] Implement `feature/inspection-type-routing` (Wissel/Overwegbevloering/Spoor forms)
|
|
||||||
- [ ] Create `master` branch when ready for production deployment
|
|
||||||
- [ ] Set up CI on Forgejo
|
|
||||||
- [ ] Backend stub (Symfony POST /api/inspections) to enable sync queue testing
|
|
||||||
- [ ] Authentication for inspectors (currently free-text name -- needs SSO/token discussion with ProRail)
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
# Switch Inspection Diagram (wissel_GW)
|
|
||||||
|
|
||||||
## Source
|
|
||||||
|
|
||||||
`06_Figuren_plaatjes/PDF/Plaatje wissel_GW.pdf`
|
|
||||||
|
|
||||||
A reference diagram used by the Duimstok inspection app to guide the user through photographing a railway switch (Dutch: *wissel*). The `GW` suffix refers to the switch type.
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
The diagram acts as an **interactive photo-capture template**. During an inspection, the user is expected to supply a photograph for each labeled camera position. The blue underlined labels in the PDF are hyperlinks — in the app they map to photo-upload slots.
|
|
||||||
|
|
||||||
## Layout
|
|
||||||
|
|
||||||
Top-down schematic of a single switch, split lengthwise into three color-coded zones:
|
|
||||||
|
|
||||||
| Zone | Color | Dutch label | Description |
|
|
||||||
|------|-------|-------------|-------------|
|
|
||||||
| 1 | Green | Puntstukgedeelte | Frog / crossing section — where the two rails converge |
|
|
||||||
| 2 | Turquoise | Middengedeelte | Middle section — closure rails between frog and points |
|
|
||||||
| 3 | Red | Tongbeweging | Switch-blade / point-motor section — contains the actuator mechanism |
|
|
||||||
|
|
||||||
## Camera positions
|
|
||||||
|
|
||||||
Eight eye/camera icons surround the switch, each tied to a photo slot:
|
|
||||||
|
|
||||||
- **Longitudinal (4×)** — "Overzichtsfoto" (overview photo) at the top-left, top-right, bottom-left, and bottom-right, taken along the track direction.
|
|
||||||
- **Transverse (6×)** — "Foto" (detail photo) on the left and right of each of the three zones, taken perpendicular to the track.
|
|
||||||
|
|
||||||
Total: **10 photo slots per switch inspection** (4 overviews + 6 details).
|
|
||||||
|
|
||||||
## Usage in the app
|
|
||||||
|
|
||||||
- Render the diagram as the visual index on the switch-inspection screen.
|
|
||||||
- Each hyperlink label corresponds to a photo slot in the inspection record.
|
|
||||||
- Slot identifiers should encode both **position** (top/bottom/left/right) and **zone** (frog/middle/blade) so the stored photos can be reassembled into the correct diagram positions in the report.
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- The diagram is language-dependent (Dutch labels). Any translation must preserve the zone semantics, not just the words.
|
|
||||||
- The actuator (two cylindrical elements at the bottom of the red zone) is drawn in place — detail photos of the *Tongbeweging* zone should capture this mechanism.
|
|
||||||
|
|
@ -78,78 +78,6 @@
|
||||||
.header-grid .label { background: var(--header-bg); font-weight: 600; color: #333; }
|
.header-grid .label { background: var(--header-bg); font-weight: 600; color: #333; }
|
||||||
.header-grid .value { background: #fff; color: #000; }
|
.header-grid .value { background: #fff; color: #000; }
|
||||||
|
|
||||||
/* Type-based visibility: hide type-specific sections by default */
|
|
||||||
.header-grid.wissel-only,
|
|
||||||
.header-grid.overweg-only,
|
|
||||||
.header-grid.spoor-only { display: none; }
|
|
||||||
body.type-wissel .header-grid.wissel-only,
|
|
||||||
body.type-engelsman .header-grid.wissel-only,
|
|
||||||
body.type-kruising .header-grid.wissel-only { display: grid; }
|
|
||||||
body.type-overweg .header-grid.overweg-only { display: grid; }
|
|
||||||
body.type-spoor .header-grid.spoor-only { display: grid; }
|
|
||||||
|
|
||||||
.wissel-overview,
|
|
||||||
.engelsman-overview,
|
|
||||||
.kruising-overview { display: none; }
|
|
||||||
body.type-wissel .wissel-overview { display: grid; }
|
|
||||||
body.type-engelsman .engelsman-overview { display: grid; }
|
|
||||||
body.type-kruising .kruising-overview { display: grid; }
|
|
||||||
|
|
||||||
.overweg-overview { display: none; }
|
|
||||||
body.type-overweg .overweg-overview { display: block; }
|
|
||||||
|
|
||||||
.spoor-overview { display: none; }
|
|
||||||
body.type-spoor .spoor-overview { display: block; }
|
|
||||||
|
|
||||||
.instruction-box.wissel-only,
|
|
||||||
.instruction-box.overweg-only,
|
|
||||||
.instruction-box.spoor-only,
|
|
||||||
.instruction-box.engelsman-only,
|
|
||||||
.instruction-box.kruising-only { display: none; }
|
|
||||||
body.type-wissel .instruction-box.wissel-only { display: block; }
|
|
||||||
body.type-overweg .instruction-box.overweg-only { display: block; }
|
|
||||||
body.type-spoor .instruction-box.spoor-only { display: block; }
|
|
||||||
body.type-engelsman .instruction-box.engelsman-only { display: block; }
|
|
||||||
body.type-kruising .instruction-box.kruising-only { display: block; }
|
|
||||||
|
|
||||||
.svg-link-row { display: none; }
|
|
||||||
body.type-wissel .svg-link-row { display: block; }
|
|
||||||
|
|
||||||
/* Overwegbevloering spatial diagram */
|
|
||||||
.ow-special-row {
|
|
||||||
display: flex; justify-content: center; gap: 24px; padding: 12px 0;
|
|
||||||
border-bottom: 1px solid #ddd; margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
.ow-diagram {
|
|
||||||
display: grid; grid-template-columns: 100px 1fr 100px;
|
|
||||||
gap: 0; max-width: 700px; margin: 0 auto; min-height: 320px;
|
|
||||||
}
|
|
||||||
.ow-side {
|
|
||||||
display: flex; flex-direction: column; align-items: center;
|
|
||||||
justify-content: space-around; padding: 4px 0;
|
|
||||||
}
|
|
||||||
.ow-km-label {
|
|
||||||
font-size: 10px; font-weight: 700; color: var(--prorail-blue);
|
|
||||||
writing-mode: vertical-rl; text-orientation: mixed;
|
|
||||||
letter-spacing: 0.5px; margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
.ow-center {
|
|
||||||
position: relative; display: flex; align-items: center; justify-content: center;
|
|
||||||
}
|
|
||||||
.ow-crossing-svg { width: 100%; height: 100%; max-height: 360px; }
|
|
||||||
.ow-weg-label {
|
|
||||||
position: absolute; font-size: 11px; font-weight: 700; color: #666;
|
|
||||||
left: 50%; transform: translateX(-50%);
|
|
||||||
}
|
|
||||||
.ow-weg-top { top: 4px; }
|
|
||||||
.ow-weg-bottom { bottom: 4px; }
|
|
||||||
|
|
||||||
/* Generic photo grid for spoor overview */
|
|
||||||
.ov-photo-grid {
|
|
||||||
display: flex; justify-content: center; gap: 24px; padding: 16px 0;
|
|
||||||
}
|
|
||||||
.ov-photo-grid .capture-label { padding: 12px 8px; }
|
|
||||||
|
|
||||||
.task-section {
|
.task-section {
|
||||||
display: grid; grid-template-columns: 180px 1fr;
|
display: grid; grid-template-columns: 180px 1fr;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
|
|
@ -279,21 +207,9 @@ body.type-wissel .svg-link-row { display: block; }
|
||||||
position: relative; border: 1px solid #aaa; display: flex; flex-direction: column;
|
position: relative; border: 1px solid #aaa; display: flex; flex-direction: column;
|
||||||
justify-content: center; align-items: center; min-height: 140px; overflow: hidden;
|
justify-content: center; align-items: center; min-height: 140px; overflow: hidden;
|
||||||
}
|
}
|
||||||
.section-strip.puntstuk { background: var(--section-punt); }
|
.section-strip.puntstuk { background: var(--section-punt); border-radius: 4px 4px 0 0; }
|
||||||
.section-strip.midden { background: var(--section-midden); }
|
.section-strip.midden { background: var(--section-midden); }
|
||||||
.section-strip.tong { background: var(--section-tong); }
|
.section-strip.tong { background: var(--section-tong); border-radius: 0 0 4px 4px; }
|
||||||
.section-strip.kruisstuk { background: #80deea; }
|
|
||||||
|
|
||||||
.eng-nr-label {
|
|
||||||
font-size: 11px; font-weight: 700; color: var(--prorail-blue);
|
|
||||||
text-align: center; align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.engelsman-overview, .kruising-overview {
|
|
||||||
grid-template-columns: 110px 1fr 110px;
|
|
||||||
grid-template-rows: auto;
|
|
||||||
gap: 0; max-width: 700px; margin: 0 auto 16px auto; align-items: stretch;
|
|
||||||
}
|
|
||||||
.section-strip .section-name {
|
.section-strip .section-name {
|
||||||
font-size: 13px; font-weight: 700; color: var(--prorail-blue);
|
font-size: 13px; font-weight: 700; color: var(--prorail-blue);
|
||||||
text-align: center; z-index: 1; text-shadow: 0 0 4px rgba(255,255,255,0.8);
|
text-align: center; z-index: 1; text-shadow: 0 0 4px rgba(255,255,255,0.8);
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,6 @@
|
||||||
<div class="filter-btns">
|
<div class="filter-btns">
|
||||||
<button class="filter-btn active" data-filter="alle">Alle</button>
|
<button class="filter-btn active" data-filter="alle">Alle</button>
|
||||||
<button class="filter-btn" data-filter="Wissel">Wissels</button>
|
<button class="filter-btn" data-filter="Wissel">Wissels</button>
|
||||||
<button class="filter-btn" data-filter="Engelsman">Engelsman</button>
|
|
||||||
<button class="filter-btn" data-filter="Kruising">Kruising</button>
|
|
||||||
<button class="filter-btn" data-filter="Overwegbevloering">Overwegen</button>
|
<button class="filter-btn" data-filter="Overwegbevloering">Overwegen</button>
|
||||||
<button class="filter-btn" data-filter="Spoor">Spoor</button>
|
<button class="filter-btn" data-filter="Spoor">Spoor</button>
|
||||||
<button class="filter-btn" data-filter="open">Nog open</button>
|
<button class="filter-btn" data-filter="open">Nog open</button>
|
||||||
|
|
@ -127,42 +125,32 @@
|
||||||
|
|
||||||
<div class="tab-panel active" id="panel-inspectie">
|
<div class="tab-panel active" id="panel-inspectie">
|
||||||
<div class="form-container" id="formContainer">
|
<div class="form-container" id="formContainer">
|
||||||
<div class="form-title" id="formTitle">Duimstokformulier</div>
|
<div class="form-title">Duimstokformulier Gewoon of Symmetrisch wissel</div>
|
||||||
<div class="header-grid">
|
<div class="header-grid">
|
||||||
<div class="cell label">Geocode</div><div class="cell value" id="hdr_geo"></div>
|
<div class="cell label">Geocode</div><div class="cell value" id="hdr_geo"></div>
|
||||||
<div class="cell label">Geocode omschrijving</div><div class="cell value" id="hdr_geotxt"></div>
|
|
||||||
<div class="cell label">Equipmentnummer</div><div class="cell value" id="hdr_equnr"></div>
|
|
||||||
<div class="cell label">Objectsoort</div><div class="cell value" id="hdr_eqart"></div>
|
|
||||||
<div class="cell label">Startpunt</div><div class="cell value" id="hdr_startpoint"></div>
|
|
||||||
<div class="cell label">Eindpunt</div><div class="cell value" id="hdr_endpoint"></div>
|
|
||||||
<div class="cell label">Omschrijving</div><div class="cell value" id="hdr_omschrijving"></div>
|
|
||||||
<div class="cell label">Order-operatie</div><div class="cell value" id="hdr_orderoperatie"></div>
|
|
||||||
<div class="cell label">Afschrijvingsgroep</div><div class="cell value" id="hdr_afschr"></div>
|
|
||||||
<div class="cell label">Plaatsingsdatum</div><div class="cell value" id="hdr_plaatsingsdatum"></div>
|
|
||||||
<div class="cell label">Hoofdspoor/Zijspoor</div><div class="cell value" id="hdr_spoor"></div>
|
|
||||||
</div>
|
|
||||||
<div class="header-grid wissel-only">
|
|
||||||
<div class="cell label">Wisselnummer</div><div class="cell value" id="hdr_wisselnr"></div>
|
|
||||||
<div class="cell label">Wisselsoort</div><div class="cell value" id="hdr_soort"></div>
|
|
||||||
<div class="cell label">Hoekverhouding</div><div class="cell value" id="hdr_hoekverhouding"></div>
|
|
||||||
<div class="cell label">Profiel</div><div class="cell value" id="hdr_profiel"></div>
|
|
||||||
<div class="cell label">Wisselligger soort</div><div class="cell value" id="hdr_dwarsligger"></div>
|
|
||||||
<div class="cell label">Achterkant afwijking</div><div class="cell value" id="hdr_afwijking"></div>
|
|
||||||
<div class="cell label">Hergebruikt object?</div><div class="cell value" id="hdr_hergebruikt"></div>
|
|
||||||
<div class="cell label">Aangesloten wisselverwarming</div><div class="cell value" id="hdr_wisselverw"></div>
|
|
||||||
<div class="cell label">Generatie</div><div class="cell value" id="hdr_generatie"></div>
|
<div class="cell label">Generatie</div><div class="cell value" id="hdr_generatie"></div>
|
||||||
|
<div class="cell label">Geocode omschrijving</div><div class="cell value" id="hdr_geotxt"></div>
|
||||||
|
<div class="cell label">Profiel</div><div class="cell value" id="hdr_profiel"></div>
|
||||||
|
<div class="cell label">Equipmentnummer</div><div class="cell value" id="hdr_equnr"></div>
|
||||||
|
<div class="cell label">Wisselligger soort</div><div class="cell value" id="hdr_dwarsligger"></div>
|
||||||
|
<div class="cell label">Wisselnummer</div><div class="cell value" id="hdr_wisselnr"></div>
|
||||||
|
<div class="cell label">Achterkant afwijking</div><div class="cell value" id="hdr_afwijking"></div>
|
||||||
|
<div class="cell label">Objectsoort</div><div class="cell value" id="hdr_eqart"></div>
|
||||||
|
<div class="cell label">Hergebruikt object?</div><div class="cell value" id="hdr_hergebruikt"></div>
|
||||||
|
<div class="cell label">Wisselsoort</div><div class="cell value" id="hdr_soort"></div>
|
||||||
|
<div class="cell label">Aangesloten wisselverwarming</div><div class="cell value" id="hdr_wisselverw"></div>
|
||||||
|
<div class="cell label">Startpunt</div><div class="cell value" id="hdr_startpoint"></div>
|
||||||
|
<div class="cell label">Hoofdspoor/Zijspoor</div><div class="cell value" id="hdr_spoor"></div>
|
||||||
|
<div class="cell label">Eindpunt</div><div class="cell value" id="hdr_endpoint"></div>
|
||||||
|
<div class="cell label">Afschrijvingsgroep</div><div class="cell value" id="hdr_afschr"></div>
|
||||||
<div class="cell label">Mee-/tegengebogen wissel</div><div class="cell value" id="hdr_meetegengebogen"></div>
|
<div class="cell label">Mee-/tegengebogen wissel</div><div class="cell value" id="hdr_meetegengebogen"></div>
|
||||||
<div class="cell label">Wissel classificatie</div><div class="cell value" id="hdr_classificatie"></div>
|
<div class="cell label">Wissel classificatie</div><div class="cell value" id="hdr_classificatie"></div>
|
||||||
<div class="cell label">Voegloos</div><div class="cell value" id="hdr_voegloos"></div>
|
<div class="cell label">Voegloos</div><div class="cell value" id="hdr_voegloos"></div>
|
||||||
|
<div class="cell label">Plaatsingsdatum</div><div class="cell value" id="hdr_plaatsingsdatum"></div>
|
||||||
|
<div class="cell label">Hoekverhouding</div><div class="cell value" id="hdr_hoekverhouding"></div>
|
||||||
<div class="cell label">Aanschafdatum</div><div class="cell value" id="hdr_aanschafdatum"></div>
|
<div class="cell label">Aanschafdatum</div><div class="cell value" id="hdr_aanschafdatum"></div>
|
||||||
</div>
|
<div class="cell label">Omschrijving</div><div class="cell value" id="hdr_omschrijving"></div>
|
||||||
<div class="header-grid overweg-only">
|
<div class="cell label">Order-operatie</div><div class="cell value" id="hdr_orderoperatie"></div>
|
||||||
<div class="cell label">Type bevloering</div><div class="cell value" id="hdr_overwegtype"></div>
|
|
||||||
<div class="cell label">Bovenliggende overweg</div><div class="cell value" id="hdr_overwegbasis"></div>
|
|
||||||
</div>
|
|
||||||
<div class="header-grid spoor-only">
|
|
||||||
<div class="cell label">Type spoor</div><div class="cell value" id="hdr_spoortype"></div>
|
|
||||||
<div class="cell label">BVS Code</div><div class="cell value" id="hdr_bvscode"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="task-section">
|
<div class="task-section">
|
||||||
<div class="label">Taak omschrijving</div><div class="value" id="hdr_taakomschrijving"></div>
|
<div class="label">Taak omschrijving</div><div class="value" id="hdr_taakomschrijving"></div>
|
||||||
|
|
@ -188,7 +176,7 @@
|
||||||
<div class="cell label">Fotonummers</div><div class="cell fotonummers-cell" id="totaal_fotonummers"></div>
|
<div class="cell label">Fotonummers</div><div class="cell fotonummers-cell" id="totaal_fotonummers"></div>
|
||||||
</div>
|
</div>
|
||||||
<table class="assessment-table" id="assessmentTable">
|
<table class="assessment-table" id="assessmentTable">
|
||||||
<thead id="assessmentHead"><tr>
|
<thead><tr>
|
||||||
<th class="nr-col">Nr</th><th class="loc-col">Locatie in wissel</th>
|
<th class="nr-col">Nr</th><th class="loc-col">Locatie in wissel</th>
|
||||||
<th class="score-col">DWL Score</th><th class="score-col">BAL Score</th>
|
<th class="score-col">DWL Score</th><th class="score-col">BAL Score</th>
|
||||||
<th class="foto-col">Foto's</th><th class="opm-col">Opmerkingen / bijzonderheden</th>
|
<th class="foto-col">Foto's</th><th class="opm-col">Opmerkingen / bijzonderheden</th>
|
||||||
|
|
@ -210,36 +198,12 @@
|
||||||
<div class="tab-panel" id="panel-overzicht">
|
<div class="tab-panel" id="panel-overzicht">
|
||||||
<div class="overview-container">
|
<div class="overview-container">
|
||||||
<div class="overview-title" id="overzichtTitle">Gewoon of Symmetrisch wissel</div>
|
<div class="overview-title" id="overzichtTitle">Gewoon of Symmetrisch wissel</div>
|
||||||
<div class="instruction-box wissel-only">
|
<div class="instruction-box">
|
||||||
<strong>Instructie:</strong> Eerste foto bevat het bordje met het wisselnummer.
|
<strong>Instructie:</strong> Eerste foto bevat het bordje met het wisselnummer.
|
||||||
Daarna dienen de foto's buitenom of rechtsom in volgorde te worden gemaakt.
|
Daarna dienen de foto's buitenom of rechtsom in volgorde te worden gemaakt.
|
||||||
Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden
|
Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden
|
||||||
in combinatie met het fotonummer.
|
in combinatie met het fotonummer.
|
||||||
</div>
|
</div>
|
||||||
<div class="instruction-box overweg-only">
|
|
||||||
<strong>Instructie:</strong> Maak overzichtsfoto's vanuit beide richtingen.
|
|
||||||
Maak per beoordelingslocatie minimaal een foto van de situatie.
|
|
||||||
Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden
|
|
||||||
in combinatie met het fotonummer.
|
|
||||||
</div>
|
|
||||||
<div class="instruction-box engelsman-only">
|
|
||||||
<strong>Instructie:</strong> Eerste foto bevat het bordje met het wisselnummer.
|
|
||||||
Daarna dienen de foto's buitenom of rechtsom in volgorde te worden gemaakt.
|
|
||||||
Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden
|
|
||||||
in combinatie met het fotonummer.
|
|
||||||
</div>
|
|
||||||
<div class="instruction-box kruising-only">
|
|
||||||
<strong>Instructie:</strong> Eerste foto bevat het bordje met het wisselnummer.
|
|
||||||
Daarna dienen de foto's links of rechtsom in volgorde te worden gemaakt.
|
|
||||||
Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden
|
|
||||||
in combinatie met het fotonummer.
|
|
||||||
</div>
|
|
||||||
<div class="instruction-box spoor-only">
|
|
||||||
<strong>Instructie:</strong> Maak overzichtsfoto's vanuit beide richtingen van het spoorvak.
|
|
||||||
Maak per beoordeeld segment minimaal een foto via de beoordelingstabel.
|
|
||||||
Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden
|
|
||||||
in combinatie met het fotonummer.
|
|
||||||
</div>
|
|
||||||
<div class="wissel-overview">
|
<div class="wissel-overview">
|
||||||
<div class="ovz-row">
|
<div class="ovz-row">
|
||||||
<label class="capture-label" data-pos="ovz_tl">
|
<label class="capture-label" data-pos="ovz_tl">
|
||||||
|
|
@ -289,121 +253,6 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="engelsman-overview">
|
|
||||||
<div class="ovz-row">
|
|
||||||
<label class="capture-label" data-pos="ovz_eng_tl"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_eng_tl"></span></div><span class="cap-text">Overzichtsfoto</span><span class="cap-arrow lg">↘</span><input type="file" accept="image/*" capture="environment" data-pos="ovz_eng_tl"></label>
|
|
||||||
<div class="flex-spacer"></div>
|
|
||||||
<span class="eng-nr-label">Hoogste wisselnummer</span>
|
|
||||||
<div class="flex-spacer"></div>
|
|
||||||
<label class="capture-label" data-pos="ovz_eng_tr"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_eng_tr"></span></div><span class="cap-text">Overzichtsfoto</span><span class="cap-arrow lg">↙</span><input type="file" accept="image/*" capture="environment" data-pos="ovz_eng_tr"></label>
|
|
||||||
</div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_eng_s5_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s5_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s5_l"></label></div>
|
|
||||||
<div class="section-strip puntstuk"><div class="section-name">Puntstuk</div><div class="section-sub">gedeelte</div><div class="section-sub sm">Sectie 5</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_eng_s5_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s5_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s5_r"></label></div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_eng_s4_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s4_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s4_l"></label></div>
|
|
||||||
<div class="section-strip kruisstuk"><div class="section-name">Kruisstuk</div><div class="section-sub">gedeelte</div><div class="section-sub sm">Sectie 4</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_eng_s4_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s4_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s4_r"></label></div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_eng_s3_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s3_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s3_l"></label></div>
|
|
||||||
<div class="section-strip midden"><div class="section-name">Midden-</div><div class="section-name">gedeelte</div><div class="section-sub sm">Sectie 3</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_eng_s3_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s3_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s3_r"></label></div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_eng_s2_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s2_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s2_l"></label></div>
|
|
||||||
<div class="section-strip tong"><div class="section-name">Tong-</div><div class="section-name">beweging</div><div class="section-sub sm">Sectie 2</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_eng_s2_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s2_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s2_r"></label></div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_eng_s1_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s1_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s1_l"></label></div>
|
|
||||||
<div class="section-strip puntstuk"><div class="section-name">Puntstuk</div><div class="section-sub">gedeelte</div><div class="section-sub sm">Sectie 1</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_eng_s1_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_eng_s1_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_eng_s1_r"></label></div>
|
|
||||||
<div class="ovz-row">
|
|
||||||
<label class="capture-label" data-pos="ovz_eng_bl"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_eng_bl"></span></div><span class="cap-text">Overzichtsfoto</span><span class="cap-arrow lg">↗</span><input type="file" accept="image/*" capture="environment" data-pos="ovz_eng_bl"></label>
|
|
||||||
<div class="flex-spacer"></div>
|
|
||||||
<span class="eng-nr-label">Laagste wisselnummer</span>
|
|
||||||
<div class="flex-spacer"></div>
|
|
||||||
<label class="capture-label" data-pos="ovz_eng_br"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_eng_br"></span></div><span class="cap-text">Overzichtsfoto</span><span class="cap-arrow lg">↖</span><input type="file" accept="image/*" capture="environment" data-pos="ovz_eng_br"></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="kruising-overview">
|
|
||||||
<div class="ovz-row">
|
|
||||||
<label class="capture-label" data-pos="ovz_kr_tl"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_kr_tl"></span></div><span class="cap-text">Overzichtsfoto</span><span class="cap-arrow lg">↘</span><input type="file" accept="image/*" capture="environment" data-pos="ovz_kr_tl"></label>
|
|
||||||
<div class="flex-spacer"></div>
|
|
||||||
<span class="eng-nr-label">Laagste wisselnummer</span>
|
|
||||||
<div class="flex-spacer"></div>
|
|
||||||
<label class="capture-label" data-pos="ovz_kr_tr"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_kr_tr"></span></div><span class="cap-text">Overzichtsfoto</span><span class="cap-arrow lg">↙</span><input type="file" accept="image/*" capture="environment" data-pos="ovz_kr_tr"></label>
|
|
||||||
</div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_kr_s4_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_kr_s4_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_kr_s4_l"></label></div>
|
|
||||||
<div class="section-strip puntstuk"><div class="section-name">Puntstuk</div><div class="section-sub">gedeelte</div><div class="section-sub sm">Sectie 4</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_kr_s4_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_kr_s4_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_kr_s4_r"></label></div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_kr_s3_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_kr_s3_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_kr_s3_l"></label></div>
|
|
||||||
<div class="section-strip kruisstuk"><div class="section-name">Kruisstuk</div><div class="section-sub">gedeelte</div><div class="section-sub sm">Sectie 3</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_kr_s3_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_kr_s3_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_kr_s3_r"></label></div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_kr_s2_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_kr_s2_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_kr_s2_l"></label></div>
|
|
||||||
<div class="section-strip midden"><div class="section-name">Midden-</div><div class="section-name">gedeelte</div><div class="section-sub sm">Sectie 2</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_kr_s2_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_kr_s2_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_kr_s2_r"></label></div>
|
|
||||||
<div class="side-labels left"><label class="capture-label" data-pos="foto_kr_s1_l"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_kr_s1_l"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_kr_s1_l"></label></div>
|
|
||||||
<div class="section-strip puntstuk"><div class="section-name">Puntstuk</div><div class="section-sub">gedeelte</div><div class="section-sub sm">Sectie 1</div></div>
|
|
||||||
<div class="side-labels right"><label class="capture-label" data-pos="foto_kr_s1_r"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_kr_s1_r"></span></div><span class="cap-text">Foto</span><span class="cap-arrow"></span><input type="file" accept="image/*" capture="environment" data-pos="foto_kr_s1_r"></label></div>
|
|
||||||
<div class="ovz-row">
|
|
||||||
<label class="capture-label" data-pos="ovz_kr_bl"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_kr_bl"></span></div><span class="cap-text">Overzichtsfoto</span><span class="cap-arrow lg">↗</span><input type="file" accept="image/*" capture="environment" data-pos="ovz_kr_bl"></label>
|
|
||||||
<div class="flex-spacer"></div>
|
|
||||||
<span class="eng-nr-label">Laagste wisselnummer + kruisnummerbord</span>
|
|
||||||
<div class="flex-spacer"></div>
|
|
||||||
<label class="capture-label" data-pos="ovz_kr_br"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_kr_br"></span></div><span class="cap-text">Overzichtsfoto</span><span class="cap-arrow lg">↖</span><input type="file" accept="image/*" capture="environment" data-pos="ovz_kr_br"></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overweg-overview">
|
|
||||||
<div class="ow-special-row">
|
|
||||||
<label class="capture-label" data-pos="foto_ow_sticker"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_sticker"></span></div><span class="cap-text">Foto 1: Sticker<br>overwegpaal</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_sticker"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_spoorbord"><div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_spoorbord"></span></div><span class="cap-text">Foto 2: Spoor-<br>naambordje</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_spoorbord"></label>
|
|
||||||
</div>
|
|
||||||
<div class="ow-diagram">
|
|
||||||
<div class="ow-side">
|
|
||||||
<span class="ow-km-label">Lage kilometrering</span>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_lk_1"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_lk_1"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_lk_1"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_lk_2"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_lk_2"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_lk_2"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_lk_3"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_lk_3"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_lk_3"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_lk_4"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_lk_4"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_lk_4"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_lk_5"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_lk_5"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_lk_5"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_lk_6"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_lk_6"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_lk_6"></label>
|
|
||||||
</div>
|
|
||||||
<div class="ow-center">
|
|
||||||
<svg class="ow-crossing-svg" viewBox="0 0 200 400" preserveAspectRatio="xMidYMid meet">
|
|
||||||
<line x1="0" y1="180" x2="200" y2="180" stroke="#555" stroke-width="3"/>
|
|
||||||
<line x1="0" y1="220" x2="200" y2="220" stroke="#555" stroke-width="3"/>
|
|
||||||
<line x1="0" y1="160" x2="200" y2="160" stroke="#8B7355" stroke-width="2" opacity="0.4"/>
|
|
||||||
<line x1="0" y1="170" x2="200" y2="170" stroke="#8B7355" stroke-width="2" opacity="0.4"/>
|
|
||||||
<line x1="0" y1="230" x2="200" y2="230" stroke="#8B7355" stroke-width="2" opacity="0.4"/>
|
|
||||||
<line x1="0" y1="240" x2="200" y2="240" stroke="#8B7355" stroke-width="2" opacity="0.4"/>
|
|
||||||
<line x1="90" y1="0" x2="90" y2="400" stroke="#999" stroke-width="1.5" stroke-dasharray="6,4"/>
|
|
||||||
<line x1="110" y1="0" x2="110" y2="400" stroke="#999" stroke-width="1.5" stroke-dasharray="6,4"/>
|
|
||||||
<rect x="70" y="160" width="60" height="80" rx="4" fill="rgba(100,180,255,0.3)" stroke="#4a9fd9" stroke-width="1.5"/>
|
|
||||||
<text x="100" y="204" text-anchor="middle" font-size="11" fill="#555" font-weight="600">Overweg</text>
|
|
||||||
</svg>
|
|
||||||
<span class="ow-weg-label ow-weg-top">Weg</span>
|
|
||||||
<span class="ow-weg-label ow-weg-bottom">Weg</span>
|
|
||||||
</div>
|
|
||||||
<div class="ow-side">
|
|
||||||
<span class="ow-km-label">Hoge kilometrering</span>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_hk_1"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_hk_1"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_hk_1"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_hk_2"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_hk_2"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_hk_2"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_hk_3"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_hk_3"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_hk_3"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_hk_4"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_hk_4"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_hk_4"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_hk_5"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_hk_5"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_hk_5"></label>
|
|
||||||
<label class="capture-label" data-pos="foto_ow_hk_6"><div class="cap-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_foto_ow_hk_6"></span></div><span class="cap-text">Foto</span><input type="file" accept="image/*" capture="environment" data-pos="foto_ow_hk_6"></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="spoor-overview">
|
|
||||||
<div class="ov-photo-grid">
|
|
||||||
<label class="capture-label" data-pos="ovz_sp_1">
|
|
||||||
<div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_sp_1"></span></div>
|
|
||||||
<span class="cap-text">Overzichtsfoto begin</span>
|
|
||||||
<input type="file" accept="image/*" capture="environment" data-pos="ovz_sp_1">
|
|
||||||
</label>
|
|
||||||
<label class="capture-label" data-pos="ovz_sp_2">
|
|
||||||
<div class="cap-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg><span class="cap-badge" id="cbadge_ovz_sp_2"></span></div>
|
|
||||||
<span class="cap-text">Overzichtsfoto einde</span>
|
|
||||||
<input type="file" accept="image/*" capture="environment" data-pos="ovz_sp_2">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overview-thumbs" id="overviewThumbs">
|
<div class="overview-thumbs" id="overviewThumbs">
|
||||||
<h4>Vastgelegde foto's</h4>
|
<h4>Vastgelegde foto's</h4>
|
||||||
<div class="thumb-grid" id="overviewThumbGrid">
|
<div class="thumb-grid" id="overviewThumbGrid">
|
||||||
|
|
@ -450,7 +299,6 @@
|
||||||
<script src="js/namespace.js"></script>
|
<script src="js/namespace.js"></script>
|
||||||
<script src="../src/Domain/sectionMap.js"></script>
|
<script src="../src/Domain/sectionMap.js"></script>
|
||||||
<script src="../src/Domain/scoring.js"></script>
|
<script src="../src/Domain/scoring.js"></script>
|
||||||
<script src="../src/Domain/inspectionTypes.js"></script>
|
|
||||||
<script src="../src/Domain/orderParser.js"></script>
|
<script src="../src/Domain/orderParser.js"></script>
|
||||||
<script src="../src/Infrastructure/utils.js"></script>
|
<script src="../src/Infrastructure/utils.js"></script>
|
||||||
<script src="../src/Infrastructure/geolocation.js"></script>
|
<script src="../src/Infrastructure/geolocation.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const CACHE_VERSION = 'duimstok-v3';
|
const CACHE_VERSION = 'duimstok-v2';
|
||||||
|
|
||||||
const APP_SHELL = [
|
const APP_SHELL = [
|
||||||
'./',
|
'./',
|
||||||
|
|
@ -15,7 +15,6 @@ const APP_SHELL = [
|
||||||
'./js/main.js',
|
'./js/main.js',
|
||||||
'../src/Domain/sectionMap.js',
|
'../src/Domain/sectionMap.js',
|
||||||
'../src/Domain/scoring.js',
|
'../src/Domain/scoring.js',
|
||||||
'../src/Domain/inspectionTypes.js',
|
|
||||||
'../src/Domain/orderParser.js',
|
'../src/Domain/orderParser.js',
|
||||||
'../src/Infrastructure/utils.js',
|
'../src/Infrastructure/utils.js',
|
||||||
'../src/Infrastructure/geolocation.js',
|
'../src/Infrastructure/geolocation.js',
|
||||||
|
|
|
||||||
|
|
@ -1,57 +1,40 @@
|
||||||
(function (A, D, I) {
|
(function (A, I) {
|
||||||
function exportScores(fd, x) {
|
|
||||||
var type = fd.type;
|
|
||||||
x.push('<BEOORDELINGEN>');
|
|
||||||
for (var [nr, data] of Object.entries(fd.scores)) {
|
|
||||||
var fNrs = (fd.photos[nr] || []).map(function (_, i) { return fd.orderNr + '_loc' + nr + '_foto' + (i + 1); }).join('; ');
|
|
||||||
if (D.usesDwlBal(type)) {
|
|
||||||
x.push('<WISSEL_SCORE><NR>' + nr + '</NR><DWL_SCORE>' + I.esc(data.dwl || '') + '</DWL_SCORE><BAL_SCORE>' + I.esc(data.bal || '') + '</BAL_SCORE><FOTO_NR>' + I.esc(fNrs) + '</FOTO_NR><OPMERKING>' + I.esc(data.opm || '') + '</OPMERKING></WISSEL_SCORE>');
|
|
||||||
} else if (type === D.TYPE_OVERWEG) {
|
|
||||||
x.push('<OVERWEG_SCORE><LOCATIE>' + I.esc(data.locatie || '') + '</LOCATIE><SCORE>' + I.esc(data.score || '') + '</SCORE></OVERWEG_SCORE>');
|
|
||||||
} else if (type === D.TYPE_SPOOR) {
|
|
||||||
x.push('<SPOOR_STUK><NR>' + nr + '</NR><KM_VAN>' + I.esc(data.kmVan || '') + '</KM_VAN><KM_TOT>' + I.esc(data.kmTot || '') + '</KM_TOT><LENGTE>' + I.esc(data.lengte || '') + '</LENGTE><TECH_JAAR>' + I.esc(data.techJaar || '') + '</TECH_JAAR><INSP_JAAR>' + I.esc(data.inspJaar || '') + '</INSP_JAAR><SCORE>' + I.esc(data.score || '') + '</SCORE><FOTO_NR>' + I.esc(fNrs) + '</FOTO_NR></SPOOR_STUK>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x.push('</BEOORDELINGEN>');
|
|
||||||
}
|
|
||||||
|
|
||||||
A.exportFormData = async function () {
|
A.exportFormData = async function () {
|
||||||
await A.saveCurrentForm();
|
await A.saveCurrentForm();
|
||||||
var fd = A.state.formData;
|
const fd = A.state.formData;
|
||||||
var x = ['<?xml version="1.0" encoding="utf-8"?>', '<FORM>'];
|
const x = ['<?xml version="1.0" encoding="utf-8"?>', '<FORM>'];
|
||||||
x.push('<AUFNR_VORNR>' + I.esc(fd.orderNr) + '</AUFNR_VORNR>');
|
x.push(`<AUFNR_VORNR>${I.esc(fd.orderNr)}</AUFNR_VORNR>`);
|
||||||
x.push('<INSPECTEUR>' + I.esc(document.getElementById('inp_inspecteur').value) + '</INSPECTEUR>');
|
x.push(`<INSPECTEUR>${I.esc(document.getElementById('inp_inspecteur').value)}</INSPECTEUR>`);
|
||||||
x.push('<INSP_DATUM>' + I.esc(document.getElementById('inp_inspectiedatum').value) + '</INSP_DATUM>');
|
x.push(`<INSP_DATUM>${I.esc(document.getElementById('inp_inspectiedatum').value)}</INSP_DATUM>`);
|
||||||
x.push('<TECH_JAAR>' + I.esc(document.getElementById('inp_techjaar').value) + '</TECH_JAAR>');
|
x.push(`<TECH_JAAR>${I.esc(document.getElementById('inp_techjaar').value)}</TECH_JAAR>`);
|
||||||
x.push('<INSP_JAAR>' + I.esc(document.getElementById('inp_inspjaar').value) + '</INSP_JAAR>');
|
x.push(`<INSP_JAAR>${I.esc(document.getElementById('inp_inspjaar').value)}</INSP_JAAR>`);
|
||||||
x.push('<OPMERKING>' + I.esc(document.getElementById('inp_opmerkingen').value) + '</OPMERKING>');
|
x.push(`<OPMERKING>${I.esc(document.getElementById('inp_opmerkingen').value)}</OPMERKING>`);
|
||||||
var hasOvPhotos = Object.values(fd.overviewPhotos).some(function (p) { return p.length > 0; });
|
x.push('<OVERZICHTFOTOS>');
|
||||||
if (hasOvPhotos) {
|
for (const [pos, photos] of Object.entries(fd.overviewPhotos)) {
|
||||||
x.push('<OVERZICHTFOTOS>');
|
photos.forEach((_, i) => x.push(`<FOTO><POSITIE>${I.esc(pos)}</POSITIE><NAAM>${I.esc(fd.orderNr.replace('/', '-'))}_${pos}_foto${i + 1}</NAAM></FOTO>`));
|
||||||
for (var [pos, photos] of Object.entries(fd.overviewPhotos)) {
|
|
||||||
photos.forEach(function (_, i) {
|
|
||||||
x.push('<FOTO><POSITIE>' + I.esc(pos) + '</POSITIE><NAAM>' + I.esc(fd.orderNr.replace('/', '-')) + '_' + pos + '_foto' + (i + 1) + '</NAAM></FOTO>');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
x.push('</OVERZICHTFOTOS>');
|
|
||||||
}
|
}
|
||||||
exportScores(fd, x);
|
x.push('</OVERZICHTFOTOS>');
|
||||||
x.push('</FORM>');
|
x.push('<BEOORDELINGEN>');
|
||||||
|
for (const [nr, data] of Object.entries(fd.scores)) {
|
||||||
|
const fNrs = (fd.photos[nr] || []).map((_, i) => `${fd.orderNr}_loc${nr}_foto${i + 1}`).join('; ');
|
||||||
|
x.push(`<WISSEL_SCORE><NR>${nr}</NR><DWL_SCORE>${I.esc(data.dwl || '')}</DWL_SCORE><BAL_SCORE>${I.esc(data.bal || '')}</BAL_SCORE><FOTO_NR>${I.esc(fNrs)}</FOTO_NR><OPMERKING>${I.esc(data.opm || '')}</OPMERKING></WISSEL_SCORE>`);
|
||||||
|
}
|
||||||
|
x.push('</BEOORDELINGEN>', '</FORM>');
|
||||||
I.downloadBlob(new Blob([x.join('\n')], { type: 'application/xml' }),
|
I.downloadBlob(new Blob([x.join('\n')], { type: 'application/xml' }),
|
||||||
fd.orderNr.replace('/', '-') + '_inspectie_' + new Date().toISOString().slice(0, 10) + '.xml');
|
`${fd.orderNr.replace('/', '-')}_inspectie_${new Date().toISOString().slice(0, 10)}.xml`);
|
||||||
var pc = 0;
|
let pc = 0;
|
||||||
for (var [nr, phs] of Object.entries(fd.photos)) {
|
for (const [nr, photos] of Object.entries(fd.photos)) {
|
||||||
phs.forEach(function (p, i) {
|
photos.forEach((p, i) => {
|
||||||
pc++;
|
pc++;
|
||||||
I.downloadBlob(p.blob, fd.orderNr.replace('/', '-') + '_loc' + nr + '_foto' + (i + 1) + '.jpg');
|
I.downloadBlob(p.blob, `${fd.orderNr.replace('/', '-')}_loc${nr}_foto${i + 1}.jpg`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (var [pos2, phs2] of Object.entries(fd.overviewPhotos)) {
|
for (const [pos, photos] of Object.entries(fd.overviewPhotos)) {
|
||||||
phs2.forEach(function (p, i) {
|
photos.forEach((p, i) => {
|
||||||
pc++;
|
pc++;
|
||||||
I.downloadBlob(p.blob, fd.orderNr.replace('/', '-') + '_' + pos2 + '_foto' + (i + 1) + '.jpg');
|
I.downloadBlob(p.blob, `${fd.orderNr.replace('/', '-')}_${pos}_foto${i + 1}.jpg`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
alert('Opgeslagen!\n- 1 XML-bestand\n- ' + pc + ' foto(\'s)');
|
alert(`Opgeslagen!\n- 1 XML-bestand\n- ${pc} foto('s)`);
|
||||||
};
|
};
|
||||||
})(window.App.Application, window.App.Domain, window.App.Infrastructure);
|
})(window.App.Application, window.App.Infrastructure);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
(function (A, D, I) {
|
(function (A, D, I) {
|
||||||
var CAMERA_SVG = '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>';
|
|
||||||
|
|
||||||
A.switchTab = function (tabId) {
|
A.switchTab = function (tabId) {
|
||||||
document.querySelectorAll('.tab-btn').forEach(btn =>
|
document.querySelectorAll('.tab-btn').forEach(btn =>
|
||||||
btn.classList.toggle('active', btn.dataset.tab === tabId));
|
btn.classList.toggle('active', btn.dataset.tab === tabId));
|
||||||
|
|
@ -8,33 +6,8 @@
|
||||||
panel.classList.toggle('active', panel.id === 'panel-' + tabId));
|
panel.classList.toggle('active', panel.id === 'panel-' + tabId));
|
||||||
};
|
};
|
||||||
|
|
||||||
A.applyFormType = function (type) {
|
|
||||||
A.state.formData.type = type;
|
|
||||||
var body = document.body;
|
|
||||||
body.classList.remove('type-wissel', 'type-overweg', 'type-spoor', 'type-engelsman', 'type-kruising');
|
|
||||||
body.classList.add('type-' + type);
|
|
||||||
|
|
||||||
var thead = document.getElementById('assessmentHead');
|
|
||||||
var titles = {};
|
|
||||||
titles[D.TYPE_WISSEL] = 'Duimstokformulier Gewoon of Symmetrisch wissel';
|
|
||||||
titles[D.TYPE_ENGELSMAN] = 'Duimstokformulier Half of Heel Engelsman';
|
|
||||||
titles[D.TYPE_KRUISING] = 'Duimstokformulier Kruising';
|
|
||||||
titles[D.TYPE_OVERWEG] = 'Duimstokformulier Overwegbevloering';
|
|
||||||
titles[D.TYPE_SPOOR] = 'Duimstokformulier Spoor';
|
|
||||||
|
|
||||||
if (D.usesDwlBal(type)) {
|
|
||||||
thead.innerHTML = '<tr><th class="nr-col">Nr</th><th class="loc-col">Locatie</th><th class="score-col">DWL Score</th><th class="score-col">BAL Score</th><th class="foto-col">Foto\'s</th><th class="opm-col">Opmerkingen</th></tr>';
|
|
||||||
} else if (type === D.TYPE_OVERWEG) {
|
|
||||||
thead.innerHTML = '<tr><th class="loc-col">Locatie</th><th class="score-col">Score</th><th class="foto-col">Foto\'s</th><th class="opm-col">Opmerkingen</th></tr>';
|
|
||||||
} else if (type === D.TYPE_SPOOR) {
|
|
||||||
thead.innerHTML = '<tr><th class="nr-col">Nr</th><th>KM van</th><th>KM tot</th><th>Lengte</th><th class="score-col">Score</th><th class="foto-col">Foto\'s</th><th class="opm-col">Opmerkingen</th></tr>';
|
|
||||||
}
|
|
||||||
document.getElementById('formTitle').textContent = titles[type] || 'Duimstokformulier';
|
|
||||||
};
|
|
||||||
|
|
||||||
A.resetForm = function () {
|
A.resetForm = function () {
|
||||||
A.state.formData = A.emptyFormData();
|
A.state.formData = A.emptyFormData();
|
||||||
document.body.classList.remove('type-wissel', 'type-overweg', 'type-spoor', 'type-engelsman', 'type-kruising');
|
|
||||||
document.querySelectorAll('.header-grid .value').forEach(el => el.textContent = '');
|
document.querySelectorAll('.header-grid .value').forEach(el => el.textContent = '');
|
||||||
document.querySelectorAll('#hdr_taakomschrijving, #hdr_aanleiding').forEach(el => el.textContent = '');
|
document.querySelectorAll('#hdr_taakomschrijving, #hdr_aanleiding').forEach(el => el.textContent = '');
|
||||||
document.getElementById('inp_inspecteur').value = '';
|
document.getElementById('inp_inspecteur').value = '';
|
||||||
|
|
@ -43,7 +16,7 @@
|
||||||
document.getElementById('inp_inspjaar').value = '';
|
document.getElementById('inp_inspjaar').value = '';
|
||||||
document.getElementById('inp_opmerkingen').value = '';
|
document.getElementById('inp_opmerkingen').value = '';
|
||||||
document.getElementById('assessmentBody').innerHTML = '';
|
document.getElementById('assessmentBody').innerHTML = '';
|
||||||
var totaal = document.getElementById('totaalscore');
|
const totaal = document.getElementById('totaalscore');
|
||||||
totaal.textContent = '-';
|
totaal.textContent = '-';
|
||||||
totaal.className = 'cell score-cell';
|
totaal.className = 'cell score-cell';
|
||||||
document.getElementById('totaal_fotonummers').textContent = '';
|
document.getElementById('totaal_fotonummers').textContent = '';
|
||||||
|
|
@ -56,8 +29,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
A.prefillFromOrder = function (order) {
|
A.prefillFromOrder = function (order) {
|
||||||
var type = D.typeFromObjectsoort(order.objectsoort);
|
|
||||||
A.applyFormType(type);
|
|
||||||
A.state.formData.orderNr = order.orderKey;
|
A.state.formData.orderNr = order.orderKey;
|
||||||
document.getElementById('hdr_omschrijving').textContent = order.omschrijving;
|
document.getElementById('hdr_omschrijving').textContent = order.omschrijving;
|
||||||
document.getElementById('hdr_eqart').textContent = order.objectsoort;
|
document.getElementById('hdr_eqart').textContent = order.objectsoort;
|
||||||
|
|
@ -74,168 +45,77 @@
|
||||||
D.SCORE_VALUES.map(v => `<option value="${v}" ${selected === v ? 'selected' : ''}>${v}</option>`).join('');
|
D.SCORE_VALUES.map(v => `<option value="${v}" ${selected === v ? 'selected' : ''}>${v}</option>`).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function photoButton(nr, locatie) {
|
A.buildAssessmentTable = function (scoreElements) {
|
||||||
return `<button class="foto-btn" data-action="open-photo" data-nr="${nr}" data-loc="${locatie.replace(/"/g, '"')}">${CAMERA_SVG}Foto's<span class="badge" id="badge_${nr}"></span></button>`;
|
const tbody = document.getElementById('assessmentBody');
|
||||||
}
|
|
||||||
|
|
||||||
function wireAssessmentEvents() {
|
|
||||||
var tbody = document.getElementById('assessmentBody');
|
|
||||||
tbody.querySelectorAll('select[data-nr]').forEach(sel => sel.addEventListener('change', () => onScoreChange(sel)));
|
|
||||||
tbody.querySelectorAll('input[data-field="opm"]').forEach(inp => inp.addEventListener('input', () => onOpmChange(inp)));
|
|
||||||
tbody.querySelectorAll('input[data-field="techJaar"], input[data-field="inspJaar"]').forEach(inp =>
|
|
||||||
inp.addEventListener('input', () => onSpoorFieldChange(inp)));
|
|
||||||
tbody.querySelectorAll('button[data-action="open-photo"]').forEach(btn =>
|
|
||||||
btn.addEventListener('click', () => A.openPhotoModal(+btn.dataset.nr, btn.dataset.loc)));
|
|
||||||
}
|
|
||||||
|
|
||||||
A.buildWisselAssessment = function (scoreElements, type) {
|
|
||||||
var tbody = document.getElementById('assessmentBody');
|
|
||||||
tbody.innerHTML = '';
|
tbody.innerHTML = '';
|
||||||
var currentSection = '';
|
let currentSection = '';
|
||||||
var assessType = type || A.state.formData.type;
|
|
||||||
scoreElements.forEach(el => {
|
scoreElements.forEach(el => {
|
||||||
var nr = parseInt(el.querySelector('NR').textContent.trim());
|
const nr = parseInt(el.querySelector('NR').textContent.trim());
|
||||||
var locatie = el.querySelector('LOCATIE').textContent.trim();
|
const locatie = el.querySelector('LOCATIE').textContent.trim();
|
||||||
var dwlScore = el.querySelector('DWL_SCORE').textContent.trim();
|
const dwlScore = el.querySelector('DWL_SCORE').textContent.trim();
|
||||||
var balScore = el.querySelector('BAL_SCORE').textContent.trim();
|
const balScore = el.querySelector('BAL_SCORE').textContent.trim();
|
||||||
var section = D.getSectionForNr(nr, assessType);
|
const section = D.getSectionForNr(nr);
|
||||||
if (section && section !== currentSection) {
|
if (section && section !== currentSection) {
|
||||||
currentSection = section;
|
currentSection = section;
|
||||||
var sr = document.createElement('tr');
|
const sr = document.createElement('tr');
|
||||||
sr.className = 'section-row';
|
sr.className = 'section-row';
|
||||||
sr.innerHTML = '<td colspan="6">' + section + '</td>';
|
sr.innerHTML = `<td colspan="6">${section}</td>`;
|
||||||
tbody.appendChild(sr);
|
tbody.appendChild(sr);
|
||||||
}
|
}
|
||||||
var tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
tr.dataset.nr = nr;
|
tr.dataset.nr = nr;
|
||||||
tr.innerHTML =
|
tr.innerHTML = `
|
||||||
'<td class="nr-col">' + nr + '</td>' +
|
<td class="nr-col">${nr}</td>
|
||||||
'<td class="loc-col">' + locatie + '</td>' +
|
<td class="loc-col">${locatie}</td>
|
||||||
'<td class="score-col editable-cell"><select data-nr="' + nr + '" data-type="dwl">' + buildScoreOptions(dwlScore) + '</select></td>' +
|
<td class="score-col editable-cell"><select data-nr="${nr}" data-type="dwl">${buildScoreOptions(dwlScore)}</select></td>
|
||||||
'<td class="score-col editable-cell"><select data-nr="' + nr + '" data-type="bal">' + buildScoreOptions(balScore) + '</select></td>' +
|
<td class="score-col editable-cell"><select data-nr="${nr}" data-type="bal">${buildScoreOptions(balScore)}</select></td>
|
||||||
'<td class="foto-col">' + photoButton(nr, locatie) + '</td>' +
|
<td class="foto-col"><button class="foto-btn" data-action="open-photo" data-nr="${nr}" data-loc="${locatie.replace(/"/g, '"')}"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>Foto's<span class="badge" id="badge_${nr}"></span></button></td>
|
||||||
'<td class="opm-col editable-cell"><input type="text" data-nr="' + nr + '" data-field="opm" placeholder=""></td>';
|
<td class="opm-col editable-cell"><input type="text" data-nr="${nr}" data-field="opm" placeholder=""></td>`;
|
||||||
tbody.appendChild(tr);
|
tbody.appendChild(tr);
|
||||||
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = { dwl: dwlScore, bal: balScore, opm: '' };
|
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = { dwl: dwlScore, bal: balScore, opm: '' };
|
||||||
if (!A.state.formData.photos[nr]) A.state.formData.photos[nr] = [];
|
if (!A.state.formData.photos[nr]) A.state.formData.photos[nr] = [];
|
||||||
var dwlSel = tr.querySelector('select[data-type="dwl"]');
|
|
||||||
|
const dwlSel = tr.querySelector('select[data-type="dwl"]');
|
||||||
if (dwlScore) dwlSel.className = D.scoreClass(dwlScore);
|
if (dwlScore) dwlSel.className = D.scoreClass(dwlScore);
|
||||||
var balSel = tr.querySelector('select[data-type="bal"]');
|
const balSel = tr.querySelector('select[data-type="bal"]');
|
||||||
if (balScore) balSel.className = D.scoreClass(balScore);
|
if (balScore) balSel.className = D.scoreClass(balScore);
|
||||||
});
|
});
|
||||||
wireAssessmentEvents();
|
|
||||||
};
|
|
||||||
|
|
||||||
A.buildOverwegAssessment = function (scoreElements) {
|
tbody.querySelectorAll('select[data-nr]').forEach(sel => sel.addEventListener('change', () => onScoreChange(sel)));
|
||||||
var tbody = document.getElementById('assessmentBody');
|
tbody.querySelectorAll('input[data-field="opm"]').forEach(inp => inp.addEventListener('input', () => onOpmChange(inp)));
|
||||||
tbody.innerHTML = '';
|
tbody.querySelectorAll('button[data-action="open-photo"]').forEach(btn =>
|
||||||
scoreElements.forEach((el, idx) => {
|
btn.addEventListener('click', () => A.openPhotoModal(+btn.dataset.nr, btn.dataset.loc)));
|
||||||
var nr = idx + 1;
|
|
||||||
var locatie = el.querySelector('LOCATIE').textContent.trim();
|
|
||||||
var score = el.querySelector('SCORE').textContent.trim();
|
|
||||||
var tr = document.createElement('tr');
|
|
||||||
tr.dataset.nr = nr;
|
|
||||||
tr.innerHTML =
|
|
||||||
'<td class="loc-col">' + locatie + '</td>' +
|
|
||||||
'<td class="score-col editable-cell"><select data-nr="' + nr + '" data-type="score">' + buildScoreOptions(score) + '</select></td>' +
|
|
||||||
'<td class="foto-col">' + photoButton(nr, locatie) + '</td>' +
|
|
||||||
'<td class="opm-col editable-cell"><input type="text" data-nr="' + nr + '" data-field="opm" placeholder=""></td>';
|
|
||||||
tbody.appendChild(tr);
|
|
||||||
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = { score: score, opm: '' };
|
|
||||||
if (!A.state.formData.photos[nr]) A.state.formData.photos[nr] = [];
|
|
||||||
var sel = tr.querySelector('select[data-type="score"]');
|
|
||||||
if (score) sel.className = D.scoreClass(score);
|
|
||||||
});
|
|
||||||
wireAssessmentEvents();
|
|
||||||
};
|
|
||||||
|
|
||||||
A.buildSpoorAssessment = function (scoreElements) {
|
|
||||||
var tbody = document.getElementById('assessmentBody');
|
|
||||||
tbody.innerHTML = '';
|
|
||||||
scoreElements.forEach(el => {
|
|
||||||
var nr = parseInt(el.querySelector('NR').textContent.trim());
|
|
||||||
var kmVan = el.querySelector('KM_VAN').textContent.trim();
|
|
||||||
var kmTot = el.querySelector('KM_TOT').textContent.trim();
|
|
||||||
var lengte = el.querySelector('LENGTE').textContent.trim();
|
|
||||||
var score = el.querySelector('SCORE').textContent.trim();
|
|
||||||
var techJaar = el.querySelector('TECH_JAAR') ? el.querySelector('TECH_JAAR').textContent.trim() : '';
|
|
||||||
var inspJaar = el.querySelector('INSP_JAAR') ? el.querySelector('INSP_JAAR').textContent.trim() : '';
|
|
||||||
var tr = document.createElement('tr');
|
|
||||||
tr.dataset.nr = nr;
|
|
||||||
tr.innerHTML =
|
|
||||||
'<td class="nr-col">' + nr + '</td>' +
|
|
||||||
'<td class="editable-cell">' + kmVan + '</td>' +
|
|
||||||
'<td class="editable-cell">' + kmTot + '</td>' +
|
|
||||||
'<td class="editable-cell">' + lengte + ' m</td>' +
|
|
||||||
'<td class="score-col editable-cell"><select data-nr="' + nr + '" data-type="score">' + buildScoreOptions(score) + '</select></td>' +
|
|
||||||
'<td class="foto-col">' + photoButton(nr, 'Segment ' + nr) + '</td>' +
|
|
||||||
'<td class="opm-col editable-cell"><input type="text" data-nr="' + nr + '" data-field="opm" placeholder=""></td>';
|
|
||||||
tbody.appendChild(tr);
|
|
||||||
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = { score: score, kmVan: kmVan, kmTot: kmTot, lengte: lengte, techJaar: techJaar, inspJaar: inspJaar, opm: '' };
|
|
||||||
if (!A.state.formData.photos[nr]) A.state.formData.photos[nr] = [];
|
|
||||||
var sel = tr.querySelector('select[data-type="score"]');
|
|
||||||
if (score) sel.className = D.scoreClass(score);
|
|
||||||
});
|
|
||||||
wireAssessmentEvents();
|
|
||||||
};
|
|
||||||
|
|
||||||
A.buildAssessmentForType = function (type, scoreElements) {
|
|
||||||
if (D.usesDwlBal(type)) A.buildWisselAssessment(scoreElements, type);
|
|
||||||
else if (type === D.TYPE_OVERWEG) A.buildOverwegAssessment(scoreElements);
|
|
||||||
else if (type === D.TYPE_SPOOR) A.buildSpoorAssessment(scoreElements);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function onScoreChange(sel) {
|
function onScoreChange(sel) {
|
||||||
var nr = parseInt(sel.dataset.nr);
|
const nr = parseInt(sel.dataset.nr);
|
||||||
var field = sel.dataset.type;
|
const type = sel.dataset.type;
|
||||||
var val = sel.value;
|
const val = sel.value;
|
||||||
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = {};
|
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = { dwl: '', bal: '', opm: '' };
|
||||||
A.state.formData.scores[nr][field] = val;
|
A.state.formData.scores[nr][type] = val;
|
||||||
sel.className = D.scoreClass(val);
|
sel.className = D.scoreClass(val);
|
||||||
A.updateTotaalscore();
|
A.updateTotaalscore();
|
||||||
A.autoSave();
|
A.autoSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onOpmChange(inp) {
|
function onOpmChange(inp) {
|
||||||
var nr = parseInt(inp.dataset.nr);
|
const nr = parseInt(inp.dataset.nr);
|
||||||
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = {};
|
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = { dwl: '', bal: '', opm: '' };
|
||||||
A.state.formData.scores[nr].opm = inp.value;
|
A.state.formData.scores[nr].opm = inp.value;
|
||||||
A.autoSave();
|
A.autoSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSpoorFieldChange(inp) {
|
|
||||||
var nr = parseInt(inp.dataset.nr);
|
|
||||||
var field = inp.dataset.field;
|
|
||||||
if (!A.state.formData.scores[nr]) A.state.formData.scores[nr] = {};
|
|
||||||
A.state.formData.scores[nr][field] = inp.value;
|
|
||||||
A.autoSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
A.updateTotaalscore = function () {
|
A.updateTotaalscore = function () {
|
||||||
var type = A.state.formData.type;
|
const worst = D.computeWorstScore(A.state.formData.scores);
|
||||||
var worst;
|
const el = document.getElementById('totaalscore');
|
||||||
if (D.usesDwlBal(type)) {
|
|
||||||
worst = D.computeWorstScore(A.state.formData.scores);
|
|
||||||
} else {
|
|
||||||
var order = ['', ...D.SCORE_VALUES];
|
|
||||||
var wIdx = 0; var wScore = '';
|
|
||||||
for (var data of Object.values(A.state.formData.scores)) {
|
|
||||||
var s = data.score || '';
|
|
||||||
var m = order.indexOf(s);
|
|
||||||
if (m > wIdx) { wIdx = m; wScore = order[m]; }
|
|
||||||
}
|
|
||||||
worst = wScore;
|
|
||||||
}
|
|
||||||
var el = document.getElementById('totaalscore');
|
|
||||||
el.textContent = worst || '-';
|
el.textContent = worst || '-';
|
||||||
el.className = 'cell score-cell';
|
el.className = 'cell score-cell';
|
||||||
if (worst) el.classList.add(D.scoreClass(worst));
|
if (worst) el.classList.add(D.scoreClass(worst));
|
||||||
};
|
};
|
||||||
|
|
||||||
A.loadSavedData = async function (orderNr) {
|
A.loadSavedData = async function (orderNr) {
|
||||||
var saved = await I.loadInspection(orderNr);
|
const saved = await I.loadInspection(orderNr);
|
||||||
if (!saved) return;
|
if (!saved) return;
|
||||||
if (saved.type) A.applyFormType(saved.type);
|
|
||||||
if (saved.inspecteur) document.getElementById('inp_inspecteur').value = saved.inspecteur;
|
if (saved.inspecteur) document.getElementById('inp_inspecteur').value = saved.inspecteur;
|
||||||
if (saved.inspectiedatum) document.getElementById('inp_inspectiedatum').value = saved.inspectiedatum;
|
if (saved.inspectiedatum) document.getElementById('inp_inspectiedatum').value = saved.inspectiedatum;
|
||||||
if (saved.techJaar) document.getElementById('inp_techjaar').value = saved.techJaar;
|
if (saved.techJaar) document.getElementById('inp_techjaar').value = saved.techJaar;
|
||||||
|
|
@ -243,14 +123,12 @@
|
||||||
if (saved.opmerkingen) document.getElementById('inp_opmerkingen').value = saved.opmerkingen;
|
if (saved.opmerkingen) document.getElementById('inp_opmerkingen').value = saved.opmerkingen;
|
||||||
if (saved.scores) {
|
if (saved.scores) {
|
||||||
A.state.formData.scores = saved.scores;
|
A.state.formData.scores = saved.scores;
|
||||||
for (var [nr, data] of Object.entries(saved.scores)) {
|
for (const [nr, data] of Object.entries(saved.scores)) {
|
||||||
var dS = document.querySelector('select[data-nr="' + nr + '"][data-type="dwl"]');
|
const dS = document.querySelector(`select[data-nr="${nr}"][data-type="dwl"]`);
|
||||||
var bS = document.querySelector('select[data-nr="' + nr + '"][data-type="bal"]');
|
const bS = document.querySelector(`select[data-nr="${nr}"][data-type="bal"]`);
|
||||||
var sS = document.querySelector('select[data-nr="' + nr + '"][data-type="score"]');
|
const oI = document.querySelector(`input[data-nr="${nr}"][data-field="opm"]`);
|
||||||
var oI = document.querySelector('input[data-nr="' + nr + '"][data-field="opm"]');
|
|
||||||
if (dS && data.dwl) { dS.value = data.dwl; dS.className = D.scoreClass(data.dwl); }
|
if (dS && data.dwl) { dS.value = data.dwl; dS.className = D.scoreClass(data.dwl); }
|
||||||
if (bS && data.bal) { bS.value = data.bal; bS.className = D.scoreClass(data.bal); }
|
if (bS && data.bal) { bS.value = data.bal; bS.className = D.scoreClass(data.bal); }
|
||||||
if (sS && data.score) { sS.value = data.score; sS.className = D.scoreClass(data.score); }
|
|
||||||
if (oI && data.opm) oI.value = data.opm;
|
if (oI && data.opm) oI.value = data.opm;
|
||||||
}
|
}
|
||||||
A.updateTotaalscore();
|
A.updateTotaalscore();
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
function emptyFormData() {
|
function emptyFormData() {
|
||||||
return {
|
return {
|
||||||
orderNr: '', type: 'wissel', inspecteur: '', inspectiedatum: '', techJaar: '', inspJaar: '',
|
orderNr: '', inspecteur: '', inspectiedatum: '', techJaar: '', inspJaar: '',
|
||||||
opmerkingen: '', scores: {}, photos: {}, overviewPhotos: {}
|
opmerkingen: '', scores: {}, photos: {}, overviewPhotos: {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,67 +1,42 @@
|
||||||
(function (A, D, I) {
|
(function (A, I) {
|
||||||
function setIfExists(id, value) {
|
|
||||||
var el = document.getElementById(id);
|
|
||||||
if (el && value) el.textContent = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
A.parseAndLoadXML = function (xmlText) {
|
A.parseAndLoadXML = function (xmlText) {
|
||||||
var parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
var xml = parser.parseFromString(xmlText, 'text/xml');
|
const xml = parser.parseFromString(xmlText, 'text/xml');
|
||||||
var getText = function (tag) { var el = xml.querySelector(tag); return el ? el.textContent.trim() : ''; };
|
const getText = (tag) => { const el = xml.querySelector(tag); return el ? el.textContent.trim() : ''; };
|
||||||
|
|
||||||
var eqart = getText('EQART');
|
const orderNr = getText('AUFNR_VORNR');
|
||||||
var type = D.typeFromEqart(eqart);
|
|
||||||
if (type === D.TYPE_WISSEL) {
|
|
||||||
type = D.typeFromWisselSoort(getText('SOORT'));
|
|
||||||
}
|
|
||||||
A.applyFormType(type);
|
|
||||||
|
|
||||||
var orderNr = getText('AUFNR_VORNR');
|
|
||||||
A.state.formData.orderNr = orderNr;
|
A.state.formData.orderNr = orderNr;
|
||||||
A.state.currentOrderKey = orderNr;
|
A.state.currentOrderKey = orderNr;
|
||||||
|
|
||||||
setIfExists('hdr_geo', getText('GEO'));
|
document.getElementById('hdr_geo').textContent = getText('GEO');
|
||||||
setIfExists('hdr_geotxt', getText('GEOTXT'));
|
document.getElementById('hdr_geotxt').textContent = getText('GEOTXT');
|
||||||
setIfExists('hdr_equnr', getText('EQUNR'));
|
document.getElementById('hdr_equnr').textContent = getText('EQUNR');
|
||||||
setIfExists('hdr_eqart', eqart);
|
document.getElementById('hdr_wisselnr').textContent = getText('WISSELNR') || getText('EQFNR_EQUI');
|
||||||
setIfExists('hdr_startpoint', getText('START_POINT'));
|
document.getElementById('hdr_eqart').textContent = getText('EQART');
|
||||||
setIfExists('hdr_endpoint', getText('END_POINT'));
|
document.getElementById('hdr_soort').textContent = getText('SOORT');
|
||||||
setIfExists('hdr_omschrijving', getText('EQKTX'));
|
document.getElementById('hdr_startpoint').textContent = getText('START_POINT');
|
||||||
setIfExists('hdr_orderoperatie', getText('AUFNR_VORNR'));
|
document.getElementById('hdr_endpoint').textContent = getText('END_POINT');
|
||||||
setIfExists('hdr_spoor', getText('SPOOR'));
|
document.getElementById('hdr_hoekverhouding').textContent = getText('HOEKVERHOUDING');
|
||||||
setIfExists('hdr_afschr', getText('ZAFSCHR_GRP_CODE'));
|
document.getElementById('hdr_omschrijving').textContent = getText('EQKTX');
|
||||||
setIfExists('hdr_plaatsingsdatum', I.formatDate(getText('DATUM_START')));
|
document.getElementById('hdr_orderoperatie').textContent = getText('AUFNR_VORNR');
|
||||||
setIfExists('hdr_taakomschrijving', getText('LTXA1'));
|
document.getElementById('hdr_profiel').textContent = getText('PROFIEL');
|
||||||
setIfExists('hdr_aanleiding', getText('KURZTEXT'));
|
document.getElementById('hdr_dwarsligger').textContent = getText('DWARSLIGGER') || '-';
|
||||||
|
document.getElementById('hdr_afwijking').textContent = getText('AFWIJKING') || '-';
|
||||||
|
document.getElementById('hdr_hergebruikt').textContent = '-';
|
||||||
|
document.getElementById('hdr_wisselverw').textContent = '-';
|
||||||
|
document.getElementById('hdr_spoor').textContent = getText('SPOOR');
|
||||||
|
document.getElementById('hdr_afschr').textContent = getText('ZAFSCHR_GRP_CODE');
|
||||||
|
document.getElementById('hdr_meetegengebogen').textContent = '-';
|
||||||
|
document.getElementById('hdr_classificatie').textContent = '-';
|
||||||
|
document.getElementById('hdr_voegloos').textContent = '-';
|
||||||
|
document.getElementById('hdr_plaatsingsdatum').textContent = I.formatDate(getText('DATUM_START'));
|
||||||
|
document.getElementById('hdr_aanschafdatum').textContent = '-';
|
||||||
|
document.getElementById('hdr_generatie').textContent = '-';
|
||||||
|
document.getElementById('hdr_taakomschrijving').textContent = getText('LTXA1');
|
||||||
|
document.getElementById('hdr_aanleiding').textContent = getText('KURZTEXT');
|
||||||
|
|
||||||
if (D.usesDwlBal(type)) {
|
const eqktx = getText('EQKTX');
|
||||||
setIfExists('hdr_wisselnr', getText('WISSELNR') || getText('EQFNR_EQUI'));
|
if (eqktx) document.getElementById('overzichtTitle').textContent = eqktx;
|
||||||
setIfExists('hdr_soort', getText('SOORT'));
|
|
||||||
setIfExists('hdr_hoekverhouding', getText('HOEKVERHOUDING'));
|
|
||||||
setIfExists('hdr_profiel', getText('PROFIEL'));
|
|
||||||
setIfExists('hdr_dwarsligger', getText('DWARSLIGGER') || '-');
|
|
||||||
setIfExists('hdr_afwijking', getText('AFWIJKING') || '-');
|
|
||||||
setIfExists('hdr_hergebruikt', '-');
|
|
||||||
setIfExists('hdr_wisselverw', '-');
|
|
||||||
setIfExists('hdr_meetegengebogen', '-');
|
|
||||||
setIfExists('hdr_classificatie', '-');
|
|
||||||
setIfExists('hdr_voegloos', '-');
|
|
||||||
setIfExists('hdr_aanschafdatum', '-');
|
|
||||||
setIfExists('hdr_generatie', '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === D.TYPE_OVERWEG) {
|
|
||||||
setIfExists('hdr_overwegtype', getText('TYPE'));
|
|
||||||
setIfExists('hdr_overwegbasis', getText('EQUKTX_BASIS'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === D.TYPE_SPOOR) {
|
|
||||||
setIfExists('hdr_spoortype', getText('TYPE'));
|
|
||||||
setIfExists('hdr_bvscode', getText('BVS_CODE'));
|
|
||||||
}
|
|
||||||
|
|
||||||
var eqktx = getText('EQKTX');
|
|
||||||
if (eqktx) setIfExists('overzichtTitle', eqktx);
|
|
||||||
document.getElementById('formToolbarTitle').textContent = eqktx || orderNr;
|
document.getElementById('formToolbarTitle').textContent = eqktx || orderNr;
|
||||||
|
|
||||||
if (getText('INSPECTEUR')) document.getElementById('inp_inspecteur').value = getText('INSPECTEUR');
|
if (getText('INSPECTEUR')) document.getElementById('inp_inspecteur').value = getText('INSPECTEUR');
|
||||||
|
|
@ -70,11 +45,8 @@
|
||||||
if (getText('INSP_JAAR')) document.getElementById('inp_inspjaar').value = getText('INSP_JAAR');
|
if (getText('INSP_JAAR')) document.getElementById('inp_inspjaar').value = getText('INSP_JAAR');
|
||||||
if (getText('OPMERKING')) document.getElementById('inp_opmerkingen').value = getText('OPMERKING');
|
if (getText('OPMERKING')) document.getElementById('inp_opmerkingen').value = getText('OPMERKING');
|
||||||
|
|
||||||
if (D.usesDwlBal(type)) A.buildWisselAssessment(xml.querySelectorAll('WISSEL_SCORE'), type);
|
A.buildAssessmentTable(xml.querySelectorAll('WISSEL_SCORE'));
|
||||||
else if (type === D.TYPE_OVERWEG) A.buildOverwegAssessment(xml.querySelectorAll('OVERWEG_SCORE'));
|
|
||||||
else if (type === D.TYPE_SPOOR) A.buildSpoorAssessment(xml.querySelectorAll('SPOOR_STUK'));
|
|
||||||
|
|
||||||
document.getElementById('statusOrder').textContent = 'Order: ' + orderNr + ' | ' + eqktx;
|
document.getElementById('statusOrder').textContent = 'Order: ' + orderNr + ' | ' + eqktx;
|
||||||
A.loadSavedData(orderNr);
|
A.loadSavedData(orderNr);
|
||||||
};
|
};
|
||||||
})(window.App.Application, window.App.Domain, window.App.Infrastructure);
|
})(window.App.Application, window.App.Infrastructure);
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
(function (D) {
|
|
||||||
D.TYPE_WISSEL = 'wissel';
|
|
||||||
D.TYPE_OVERWEG = 'overweg';
|
|
||||||
D.TYPE_SPOOR = 'spoor';
|
|
||||||
D.TYPE_ENGELSMAN = 'engelsman';
|
|
||||||
D.TYPE_KRUISING = 'kruising';
|
|
||||||
|
|
||||||
D.EQART_TO_TYPE = {
|
|
||||||
'WISSEL': D.TYPE_WISSEL,
|
|
||||||
'OVERWBEVL': D.TYPE_OVERWEG,
|
|
||||||
'SPOORDWL': D.TYPE_SPOOR,
|
|
||||||
'ENGELSMAN': D.TYPE_ENGELSMAN,
|
|
||||||
'KRUISING': D.TYPE_KRUISING
|
|
||||||
};
|
|
||||||
|
|
||||||
D.OBJECTSOORT_TO_TYPE = {
|
|
||||||
'Wissel': D.TYPE_WISSEL,
|
|
||||||
'Overwegbevloering': D.TYPE_OVERWEG,
|
|
||||||
'Spoor': D.TYPE_SPOOR,
|
|
||||||
'Engelsman': D.TYPE_ENGELSMAN,
|
|
||||||
'Half Engelsman': D.TYPE_ENGELSMAN,
|
|
||||||
'Heel Engelsman': D.TYPE_ENGELSMAN,
|
|
||||||
'Kruising': D.TYPE_KRUISING,
|
|
||||||
'Ingesloten kruising': D.TYPE_KRUISING
|
|
||||||
};
|
|
||||||
|
|
||||||
D.typeFromEqart = function (eqart) {
|
|
||||||
return D.EQART_TO_TYPE[eqart] || D.TYPE_WISSEL;
|
|
||||||
};
|
|
||||||
|
|
||||||
D.typeFromObjectsoort = function (objectsoort) {
|
|
||||||
return D.OBJECTSOORT_TO_TYPE[objectsoort] || D.TYPE_WISSEL;
|
|
||||||
};
|
|
||||||
|
|
||||||
D.typeFromWisselSoort = function (soort) {
|
|
||||||
soort = (soort || '').toLowerCase();
|
|
||||||
if (soort.indexOf('engelsman') >= 0) return D.TYPE_ENGELSMAN;
|
|
||||||
if (soort.indexOf('kruising') >= 0) return D.TYPE_KRUISING;
|
|
||||||
return D.TYPE_WISSEL;
|
|
||||||
};
|
|
||||||
|
|
||||||
D.OVERWEG_LOCATIONS = [
|
|
||||||
'Ligging spoor',
|
|
||||||
'Ligging bevloering',
|
|
||||||
'Constructieve kwaliteit',
|
|
||||||
'Wegverharding'
|
|
||||||
];
|
|
||||||
|
|
||||||
D.usesDwlBal = function (type) {
|
|
||||||
return type === D.TYPE_WISSEL || type === D.TYPE_ENGELSMAN || type === D.TYPE_KRUISING;
|
|
||||||
};
|
|
||||||
})(window.App.Domain);
|
|
||||||
|
|
@ -1,34 +1,12 @@
|
||||||
(function (D) {
|
(function (D) {
|
||||||
D.wisselSectionMap = {
|
D.sectionMap = {
|
||||||
'Sectie 1: Tongbeweging': [1, 2, 3, 4],
|
'Sectie 1: Tongbeweging': [1, 2, 3, 4],
|
||||||
'Sectie 2: Middengedeelte': [5, 6, 7, 8, 9, 10],
|
'Sectie 2: Middengedeelte': [5, 6, 7, 8, 9, 10],
|
||||||
'Sectie 3: Puntstuk gedeelte': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
|
'Sectie 3: Puntstuk gedeelte': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
|
||||||
};
|
};
|
||||||
|
|
||||||
D.engelsmanSectionMap = {
|
D.getSectionForNr = function (nr) {
|
||||||
'Sectie 1: Puntstuk gedeelte (boven)': [1, 2, 3, 4, 5],
|
for (const [section, nrs] of Object.entries(D.sectionMap)) {
|
||||||
'Sectie 2: Kruisstuk gedeelte': [6, 7, 8, 9, 10],
|
|
||||||
'Sectie 3: Middengedeelte': [11, 12, 13, 14, 15, 16],
|
|
||||||
'Sectie 4: Tongbeweging': [17, 18, 19, 20, 21, 22],
|
|
||||||
'Sectie 5: Puntstuk gedeelte (onder)': [23, 24, 25, 26, 27, 28, 29, 30]
|
|
||||||
};
|
|
||||||
|
|
||||||
D.kruisingSectionMap = {
|
|
||||||
'Sectie 1: Puntstuk gedeelte (boven)': [1, 2, 3, 4, 5, 6],
|
|
||||||
'Sectie 2: Kruisstuk gedeelte': [7, 8, 9, 10, 11, 12],
|
|
||||||
'Sectie 3: Middengedeelte': [13, 14, 15, 16, 17, 18],
|
|
||||||
'Sectie 4: Puntstuk gedeelte (onder)': [19, 20, 21, 22, 23, 24]
|
|
||||||
};
|
|
||||||
|
|
||||||
D.sectionMapForType = function (type) {
|
|
||||||
if (type === 'engelsman') return D.engelsmanSectionMap;
|
|
||||||
if (type === 'kruising') return D.kruisingSectionMap;
|
|
||||||
return D.wisselSectionMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
D.getSectionForNr = function (nr, type) {
|
|
||||||
var map = D.sectionMapForType(type);
|
|
||||||
for (const [section, nrs] of Object.entries(map)) {
|
|
||||||
if (nrs.includes(nr)) return section;
|
if (nrs.includes(nr)) return section;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -39,27 +17,6 @@
|
||||||
ovz_bl: 'Overzichtsfoto LO', ovz_br: 'Overzichtsfoto RO',
|
ovz_bl: 'Overzichtsfoto LO', ovz_br: 'Overzichtsfoto RO',
|
||||||
foto_s3_l: 'Foto Puntstuk L', foto_s3_r: 'Foto Puntstuk R',
|
foto_s3_l: 'Foto Puntstuk L', foto_s3_r: 'Foto Puntstuk R',
|
||||||
foto_s2_l: 'Foto Midden L', foto_s2_r: 'Foto Midden R',
|
foto_s2_l: 'Foto Midden L', foto_s2_r: 'Foto Midden R',
|
||||||
foto_s1_l: 'Foto Tong L', foto_s1_r: 'Foto Tong R',
|
foto_s1_l: 'Foto Tong L', foto_s1_r: 'Foto Tong R'
|
||||||
foto_ow_sticker: 'Sticker overwegpaal', foto_ow_spoorbord: 'Spoornaambordje',
|
|
||||||
foto_ow_lk_1: 'Lage km foto 1', foto_ow_lk_2: 'Lage km foto 2',
|
|
||||||
foto_ow_lk_3: 'Lage km foto 3', foto_ow_lk_4: 'Lage km foto 4',
|
|
||||||
foto_ow_lk_5: 'Lage km foto 5', foto_ow_lk_6: 'Lage km foto 6',
|
|
||||||
foto_ow_hk_1: 'Hoge km foto 1', foto_ow_hk_2: 'Hoge km foto 2',
|
|
||||||
foto_ow_hk_3: 'Hoge km foto 3', foto_ow_hk_4: 'Hoge km foto 4',
|
|
||||||
foto_ow_hk_5: 'Hoge km foto 5', foto_ow_hk_6: 'Hoge km foto 6',
|
|
||||||
ovz_sp_1: 'Overzichtsfoto begin', ovz_sp_2: 'Overzichtsfoto einde',
|
|
||||||
ovz_eng_tl: 'Overzichtsfoto LB', ovz_eng_tr: 'Overzichtsfoto RB',
|
|
||||||
ovz_eng_bl: 'Overzichtsfoto LO', ovz_eng_br: 'Overzichtsfoto RO',
|
|
||||||
foto_eng_s5_l: 'Foto Puntstuk boven L', foto_eng_s5_r: 'Foto Puntstuk boven R',
|
|
||||||
foto_eng_s4_l: 'Foto Kruisstuk L', foto_eng_s4_r: 'Foto Kruisstuk R',
|
|
||||||
foto_eng_s3_l: 'Foto Midden L', foto_eng_s3_r: 'Foto Midden R',
|
|
||||||
foto_eng_s2_l: 'Foto Tong L', foto_eng_s2_r: 'Foto Tong R',
|
|
||||||
foto_eng_s1_l: 'Foto Puntstuk onder L', foto_eng_s1_r: 'Foto Puntstuk onder R',
|
|
||||||
ovz_kr_tl: 'Overzichtsfoto LB', ovz_kr_tr: 'Overzichtsfoto RB',
|
|
||||||
ovz_kr_bl: 'Overzichtsfoto LO', ovz_kr_br: 'Overzichtsfoto RO',
|
|
||||||
foto_kr_s4_l: 'Foto Puntstuk boven L', foto_kr_s4_r: 'Foto Puntstuk boven R',
|
|
||||||
foto_kr_s3_l: 'Foto Kruisstuk L', foto_kr_s3_r: 'Foto Kruisstuk R',
|
|
||||||
foto_kr_s2_l: 'Foto Midden L', foto_kr_s2_r: 'Foto Midden R',
|
|
||||||
foto_kr_s1_l: 'Foto Puntstuk onder L', foto_kr_s1_r: 'Foto Puntstuk onder R'
|
|
||||||
};
|
};
|
||||||
})(window.App.Domain);
|
})(window.App.Domain);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue