diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 8f7896791..2a6e54ce1 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,11 +1,5 @@ name: Continuous Integration -on: - push: - branches: - - main - pull_request: - branches: - - main +on: [push] concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -29,6 +23,7 @@ jobs: lint: runs-on: ubuntu-latest + continue-on-error: true steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -100,3 +95,26 @@ jobs: with: name: build-standalone-demo path: dist/netzgrafik-frontend/ + + publish: + runs-on: ubuntu-latest + needs: build-standalone + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-standalone + path: dist/netzgrafik-frontend/ + - uses: actions/setup-node@v4 + with: + registry-url: "https://registry.npmjs.org" + - run: npm pkg set name="@osrd-project/netzgrafik-frontend" + - run: npm version --no-git-tag-version "0.0.0-snapshot.$GITHUB_SHA" + - run: npm pkg delete dependencies optionalDependencies devDependencies + - run: npm publish --provenance --access public --tag snapshot + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/README.md b/README.md index 917c03450..722ec5b32 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,68 @@ +# Netzgrafik-Editor's OSRD fork + +Our fork uses the branch `standalone`, regularily rebased onto the base +repository's `main` branch. We try to keep the list of patches applied on top +of the base repository as small as possible, ideally upstreaming them little by +little when it makes sense. The list of patches can be viewed here: +https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/compare/main...osrd-project:netzgrafik-editor-frontend:standalone + +A new NPM package is automatically published on all pushes to any branch of the +fork. The list of versions can be seen here: +https://www.npmjs.com/package/@osrd-project/netzgrafik-frontend?activeTab=versions + +## Initial setup + +Clone the base repository, add OSRD's fork as a separate remote, checkout the +fork's branch: + +```sh +git clone git@github.com:SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git +cd netzgrafik-editor-frontend +git remote add osrd-project git@github.com:osrd-project/netzgrafik-editor-frontend.git +git fetch osrd-project +git checkout standalone +``` + +## Pulling in changes from the base repository + +Fetch changes from the base repository and rebase our fork: + +```sh +git fetch --all +git checkout standalone +git reset --hard osrd-project/standalone +git rebase origin/main +git push --force-with-lease +``` + +## Making changes to fork patches + +Sometimes it's necessary to make a change to one of our fork's patches (as +opposed to one of the commits present in the base repository). + +First switch to the `standalone` branch and identify the commit you want to +edit. Then create a new working branch, make the changes to the source files, +and create a fixup commit: + +```sh +git checkout standalone +git checkout -b emersion/fix-all-the-bugs +# edit source files, work work work +git commit -a --fixup +git push osrd-project +``` + +A pull request can then be opened and the changes can be reviewed. Once the PR +is merged, the fixup can be squashed into its original commit: + +```sh +git fetch --all +git checkout standalone +git reset --hard osrd-project/standalone +git rebase --autosquash --keep-base origin/main +git push --force-with-lease +``` + # Netzgrafik-Editor
diff --git a/package.json b/package.json index 8e71a3432..2223813d8 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "version": "2.9.29", "repository": { "type": "git", - "url": "https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend.git" + "url": "https://github.com/osrd-project/netzgrafik-editor-frontend.git" }, "files": [ "dist/*" diff --git a/src/app/app.component.html b/src/app/app.component.html index fccac0f23..290e8b3a8 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,6 +2,7 @@ label="Netzgrafik-Editor" [subtitle]="'app.version' | translate: {version: version}" class="sbb-header-fixed-columns noprint" + *ngIf="!disableBackend" > set human-readable warning diff --git a/src/app/models/trainrunsection.model.ts b/src/app/models/trainrunsection.model.ts index 0410b232f..99fab28bb 100644 --- a/src/app/models/trainrunsection.model.ts +++ b/src/app/models/trainrunsection.model.ts @@ -12,6 +12,7 @@ import { } from "../data-structures/technical.data.structures"; import {TrainrunSectionValidator} from "../services/util/trainrunsection.validator"; import {formatDate} from "@angular/common"; +import {environment} from "src/environments/environment"; export class TrainrunSection { private static currentId = 0; @@ -171,6 +172,9 @@ export class TrainrunSection { } private static formatDisplayText(time: TimeLockDto, offset: number): string { + if (time.time === null) { + return "?"; + } if (!time?.timeFormatter?.stylePattern) { return undefined; } @@ -455,22 +459,27 @@ export class TrainrunSection { } hasTravelTimeWarning(): boolean { + if (environment.disableBackend) return false; return this.travelTime.warning !== null; } hasSourceDepartureWarning(): boolean { + if (environment.disableBackend) return false; return this.sourceDeparture.warning !== null; } hasSourceArrivalWarning(): boolean { + if (environment.disableBackend) return false; return this.sourceArrival.warning !== null; } hasTargetDepartureWarning(): boolean { + if (environment.disableBackend) return false; return this.targetDeparture.warning !== null; } hasTargetArrivalWarning(): boolean { + if (environment.disableBackend) return false; return this.targetArrival.warning !== null; } diff --git a/src/app/netzgrafik-application/netzgrafik-application.component.scss b/src/app/netzgrafik-application/netzgrafik-application.component.scss index d20061c9c..8a259dac6 100644 --- a/src/app/netzgrafik-application/netzgrafik-application.component.scss +++ b/src/app/netzgrafik-application/netzgrafik-application.component.scss @@ -13,5 +13,5 @@ a.SideBarMainIcon.sbb-active { } .sbb-icon-sidebar-container.disableBackend { - top: 53px; + top: 0px; } diff --git a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.html b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.html index 21b6fa15c..da7a9823e 100644 --- a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.html +++ b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.html @@ -21,7 +21,7 @@ height="28px" /> {{ perlenketteNode.shortName }} - + {{ perlenketteNode.connectionTime }} @@ -267,6 +267,7 @@ [attr.y]="55 + heightConnectionSurplus" text-anchor="end" class="node_connection_time" + *ngIf="false" > {{ perlenketteNode.connectionTime }} diff --git a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts index 38b32b5c2..01f978da9 100644 --- a/src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts +++ b/src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts @@ -169,9 +169,7 @@ export class PerlenketteNodeComponent implements OnInit { } getTextNameOrTime(connection: PerlenketteConnection, connectionGrpKey: number, pos: number) { - return pos === 0 - ? connection.categoryShortName + "" + connection.title - : "" + connection.remainingTime; + return pos === 0 ? "" + connection.title : "" + connection.remainingTime; } transformIndex(index: number, connectionGrpKey: number): number { @@ -311,7 +309,7 @@ export class PerlenketteNodeComponent implements OnInit { this.perlenketteTrainrun.pathItems.forEach((item: PerlenketteItem) => { if (item.isPerlenketteNode()) { item.getPerlenketteNode().connections.forEach((connection: PerlenketteConnection) => { - const name = connection.categoryShortName + "" + connection.title; + const name = "" + connection.title; maxTrainrunNameLen = Math.max( 3 + connection.terminalStationBackward.length, Math.max( diff --git a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.ts b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.ts index 2ace8a00c..b086b9a35 100644 --- a/src/app/perlenkette/perlenkette-section/perlenkette-section.component.ts +++ b/src/app/perlenkette/perlenkette-section/perlenkette-section.component.ts @@ -624,6 +624,9 @@ export class PerlenketteSectionComponent implements OnInit, AfterContentInit, On } getTravelTime() { + if (this.trainrunSectionTimesService.getTimeStructure().travelTime === null) { + return null; + } if ( TrainrunSectionsView.getNode(this.trainrunSection, true).isNonStop(this.trainrunSection) || TrainrunSectionsView.getNode(this.trainrunSection, false).isNonStop(this.trainrunSection) @@ -899,6 +902,9 @@ export class PerlenketteSectionComponent implements OnInit, AfterContentInit, On } roundTime(time: number) { + if (time === null) { + return time; + } return MathUtils.round(time, this.filterService.getTimeDisplayPrecision()); } diff --git a/src/app/perlenkette/perlenkette.component.html b/src/app/perlenkette/perlenkette.component.html index 5eaaf393a..1b23af069 100644 --- a/src/app/perlenkette/perlenkette.component.html +++ b/src/app/perlenkette/perlenkette.component.html @@ -40,9 +40,7 @@ >

- {{ perlenketteTrainrun.categoryShortName }}{{ perlenketteTrainrun.title }} + {{ perlenketteTrainrun.title }}

diff --git a/src/app/services/data/trainrun-section-times.service.ts b/src/app/services/data/trainrun-section-times.service.ts index 72918035b..a07b515f9 100644 --- a/src/app/services/data/trainrun-section-times.service.ts +++ b/src/app/services/data/trainrun-section-times.service.ts @@ -422,21 +422,38 @@ export class TrainrunSectionTimesService { this.initialLeftAndRightElement === LeftAndRightElement.LeftRightTrainrunName ) { this.timeStructure.leftDepartureTime = - (this.timeStructure.leftDepartureTime + this.offset) % 60; + this.timeStructure.leftDepartureTime === null + ? null + : (this.timeStructure.leftDepartureTime + this.offset) % 60; this.timeStructure.rightArrivalTime = - (this.timeStructure.rightArrivalTime + this.offset) % 60; + this.timeStructure.rightArrivalTime === null + ? null + : (this.timeStructure.rightArrivalTime + this.offset) % 60; this.timeStructure.leftArrivalTime = - (maxMinutes + this.timeStructure.leftArrivalTime - this.offset) % 60; + this.timeStructure.leftArrivalTime === null + ? null + : (maxMinutes + this.timeStructure.leftArrivalTime - this.offset) % 60; this.timeStructure.rightDepartureTime = - (maxMinutes + this.timeStructure.rightDepartureTime - this.offset) % 60; + this.timeStructure.rightDepartureTime === null + ? null + : (maxMinutes + this.timeStructure.rightDepartureTime - this.offset) % 60; } else { this.timeStructure.leftDepartureTime = - (maxMinutes + this.timeStructure.leftDepartureTime - this.offset) % 60; + this.timeStructure.leftDepartureTime === null + ? null + : (maxMinutes + this.timeStructure.leftDepartureTime - this.offset) % 60; this.timeStructure.rightArrivalTime = - (maxMinutes + this.timeStructure.rightArrivalTime - this.offset) % 60; - this.timeStructure.leftArrivalTime = (this.timeStructure.leftArrivalTime + this.offset) % 60; + this.timeStructure.rightArrivalTime === null + ? null + : (maxMinutes + this.timeStructure.rightArrivalTime - this.offset) % 60; + this.timeStructure.leftArrivalTime = + this.timeStructure.leftArrivalTime === null + ? null + : (this.timeStructure.leftArrivalTime + this.offset) % 60; this.timeStructure.rightDepartureTime = - (this.timeStructure.rightDepartureTime + this.offset) % 60; + this.timeStructure.rightDepartureTime === null + ? null + : (this.timeStructure.rightDepartureTime + this.offset) % 60; } this.offsetTransformationActive = true; this.fixAllTimesPrecision(); @@ -495,6 +512,13 @@ export class TrainrunSectionTimesService { this.timeStructure.travelTime, timeDisplayPrecision, ); + // Populate travel time here, otherwise it'll be up to + // setTimeStructureToTrainrunSections() and it may overwrite values entered + // by the user + const minTravelTime = 1.0 / Math.pow(10, this.filterService.getTimeDisplayPrecision()); + if (this.timeStructure.travelTime < 0.1) { + this.timeStructure.travelTime = 0.1; + } } private fixAllTimesPrecision() { diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index 136f8af18..feca77396 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -860,7 +860,7 @@ export class TrainrunSectionService implements OnDestroy { const newTotalTravelTime = timeStructure.travelTime; const oldTotalTravelTime = this.trainrunService.getCumulativeTravelTime(trainrunSection); - const travelTimeFactor = newTotalTravelTime / oldTotalTravelTime; + const travelTimeFactor = newTotalTravelTime / (oldTotalTravelTime || 1); // prepare data structure for the first trainrunsection const bothLastNonStopNodes = this.trainrunService.getBothLastNonStopNodes(trainrunSection); diff --git a/src/app/services/ui/ui.interaction.service.ts b/src/app/services/ui/ui.interaction.service.ts index f9e19f464..739cf1950 100644 --- a/src/app/services/ui/ui.interaction.service.ts +++ b/src/app/services/ui/ui.interaction.service.ts @@ -223,7 +223,7 @@ export class UiInteractionService implements OnDestroy { this.loadUserSettingFromLocalStorage(); if (this.activeTheme === null) { // detect at initialization - if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) { + if (false && window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) { this.setActiveTheme(new ThemeFachDark(), false); } else { this.setActiveTheme(new ThemeFach(), false); diff --git a/src/app/services/util/trainrunsection.helper.ts b/src/app/services/util/trainrunsection.helper.ts index 219568a72..a69019152 100644 --- a/src/app/services/util/trainrunsection.helper.ts +++ b/src/app/services/util/trainrunsection.helper.ts @@ -289,7 +289,7 @@ export class TrainrunsectionHelper { leftArrivalTime: lastLeftNode.getArrivalTime(leftTrainrunSection), rightDepartureTime: lastRightNode.getDepartureTime(rightTrainrunSection), rightArrivalTime: lastRightNode.getArrivalTime(rightTrainrunSection), - travelTime: cumulativeTravelTime, + travelTime: cumulativeTravelTime || null, }; } diff --git a/src/app/streckengrafik/components/train-run-section/train-run-section.component.ts b/src/app/streckengrafik/components/train-run-section/train-run-section.component.ts index be3db2317..fdf2eb7f6 100644 --- a/src/app/streckengrafik/components/train-run-section/train-run-section.component.ts +++ b/src/app/streckengrafik/components/train-run-section/train-run-section.component.ts @@ -654,7 +654,7 @@ export class TrainRunSectionComponent implements OnDestroy, UpdateCounterHandler } getText(): string { - return this.trainrun.categoryShortName + this.trainrun.title; + return this.trainrun.title; } textWidth(): number { diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.html index bfab8faf7..954a2e04f 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-and-section-dialog.component.html @@ -15,10 +15,7 @@ >
- + diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html index 942bbec71..b465ce044 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrun-tab/trainrun-tab.component.html @@ -47,7 +47,7 @@
-
+
{{ "app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.verkehrt" | translate }} @@ -74,6 +74,7 @@ [title]=" 'app.view.dialogs.trainrun-and-section-dialog.trainrun-tab.trainrunDuplicate' | translate " + *ngIf="false" > diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-card/trainrun-section-card.component.ts b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-card/trainrun-section-card.component.ts index 471fa86b4..0df4ef869 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-card/trainrun-section-card.component.ts +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-card/trainrun-section-card.component.ts @@ -30,7 +30,7 @@ export class TrainrunSectionCardComponent implements AfterViewInit, OnDestroy { public categoryColorRef: ColorRefType; public timeCategoryLinePattern: LinePatternRefs; public direction = Direction; - public chosenCard: "top" | "bottom"; + public chosenCard: "top" | "bottom" | null = null; private trainrunSectionHelper: TrainrunsectionHelper; private destroyed = new Subject(); @@ -54,14 +54,6 @@ export class TrainrunSectionCardComponent implements AfterViewInit, OnDestroy { this.trainrunSectionService.trainrunSections.pipe(takeUntil(this.destroyed)).subscribe(() => { this.updateAllValues(); }); - // Initialize the selected trainrun as one-way, selecting the [source] → [target] card - if (this.selectedTrainrunSection.getTrainrun().isRoundTrip()) { - if (TrainrunsectionHelper.isTargetRightOrBottom(this.selectedTrainrunSection)) { - this.onTrainrunSectionCardClick("top"); - } else { - this.onTrainrunSectionCardClick("bottom"); - } - } } updateAllValues() { @@ -87,7 +79,9 @@ export class TrainrunSectionCardComponent implements AfterViewInit, OnDestroy { ); this.endNode = [endNode.getFullName(), endNode.getBetriebspunktName()]; - if (!selectedTrainrun.isRoundTrip()) { + if (selectedTrainrun.isRoundTrip()) { + this.chosenCard = null; + } else { this.chosenCard = TrainrunsectionHelper.isTargetRightOrBottom(this.selectedTrainrunSection) ? "top" : "bottom"; diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html index 140f55dd7..409ec3bf3 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html @@ -7,7 +7,10 @@ {{ leftBetriebspunkt[0] }} {{ leftBetriebspunkt[1] }} - + - + {{ rightBetriebspunkt[0] }} {{ rightBetriebspunkt[1] }} diff --git a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html index f683a3d8c..2b3971b99 100644 --- a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html +++ b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html @@ -13,7 +13,8 @@

{{ "app.view.editor-edit-tools-view-component.edit" | t [componentLabelRef]="'Trainrun'" > - + + {{ "app.view.editor-edit-tools-view-component.nodes" | translate }} @@ -30,8 +31,9 @@

{{ "app.view.editor-edit-tools-view-component.edit" | t {{ "app.view.editor-edit-tools-view-component.delete-netzgrafik-title" | translate @@ -99,7 +101,7 @@

{{ "app.view.editor-edit-tools-view-component.edit" | t {{ "app.view.editor-edit-tools-view-component.delete-all-visible-elements" | translate }} - + {{ "app.view.editor-edit-tools-view-component.merge-netzgrafik-title" | translate }} diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.html b/src/app/view/editor-filter-view/editor-filter-view.component.html index 90935def5..7f33eb09d 100644 --- a/src/app/view/editor-filter-view/editor-filter-view.component.html +++ b/src/app/view/editor-filter-view/editor-filter-view.component.html @@ -39,10 +39,10 @@

{{ "app.view.editor-filter-view.filter" | translate }}<

- {{ + {{ "app.view.editor-filter-view.time-category" | translate }} -
+
- {{ "app.view.editor-side-view.editor-tools-view-component.import-base-data" | translate }} - {{ "app.view.editor-side-view.editor-tools-view-component.help-csv-data" | translate }} - -
- + class="TrainrunDialog EditorToolButton" + > + + + {{ "app.view.editor-side-view.editor-tools-view-component.import-base-data" | translate }} + {{ "app.view.editor-side-view.editor-tools-view-component.help-csv-data" | translate }} + +
+ + -->