stop details and track info
This commit is contained in:
parent
3e89c654ec
commit
58a19efe14
@ -41,11 +41,15 @@
|
|||||||
<span class="departure__estimated">{{ departure.estimated.format('HH:mm') }}</span>
|
<span class="departure__estimated">{{ departure.estimated.format('HH:mm') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<stop :stop="departure.stop" class="departure__stop">
|
<div class="departure__stop">
|
||||||
<template slot="actions">
|
<fa :icon="['fal', 'sign']" fixed-width class="mr-1"/>
|
||||||
<fa :icon="['fal', 'sign']" fixed-width class="mr-1"/>
|
<stop :stop="departure.stop"></stop>
|
||||||
</template>
|
</div>
|
||||||
</stop>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<div class="alert alert-info" v-if="stops.length === 0">
|
||||||
|
<fa :icon="['fal', 'info-circle']"></fa>
|
||||||
|
Wybierz przystanki korzystając z wyszukiwarki poniżej, aby zobaczyć listę odjazdów.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -20,15 +20,12 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="stop-group__stops list-unstyled">
|
<ul class="stop-group__stops list-underlined">
|
||||||
<li v-for="stop in group" :key="stop.id">
|
<li v-for="stop in group" :key="stop.id" class="d-flex">
|
||||||
<stop :stop="stop">
|
<button @click="select(stop, $event)" class="btn btn-action">
|
||||||
<template slot="actions">
|
<fa :icon="['fal', 'check']" />
|
||||||
<button @click="select(stop, $event)" class="btn btn-action">
|
</button>
|
||||||
<fa :icon="['fal', 'check']" />
|
<stop :stop="stop" class="flex-grow-1"></stop>
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
</stop>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
6
resources/components/fold.html
Normal file
6
resources/components/fold.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<div class="collapse">
|
||||||
|
<lazy v-if="lazy" :activate="visible">
|
||||||
|
<slot></slot>
|
||||||
|
</lazy>
|
||||||
|
<slot v-else></slot>
|
||||||
|
</div>
|
3
resources/components/lazy.html
Normal file
3
resources/components/lazy.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<keep-alive>
|
||||||
|
<slot v-if="visible"></slot>
|
||||||
|
</keep-alive>
|
@ -2,14 +2,11 @@
|
|||||||
<departures :stops="stops"/>
|
<departures :stops="stops"/>
|
||||||
|
|
||||||
<ul class="picker__stops list-underlined">
|
<ul class="picker__stops list-underlined">
|
||||||
<li v-for="stop in stops" :key="stop.id">
|
<li v-for="stop in stops" :key="stop.id" class="d-flex align-items-center">
|
||||||
<stop :stop="stop">
|
<button @click="remove(stop)" class="btn btn-action">
|
||||||
<template slot="actions">
|
<fa :icon="['fal', 'times']" />
|
||||||
<button @click="remove(stop)" class="btn btn-action">
|
</button>
|
||||||
<fa :icon="['fal', 'times']" />
|
<stop :stop="stop" class="flex-grow-1"></stop>
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
</stop>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
4
resources/components/popper.html
Normal file
4
resources/components/popper.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<div class="popper" :class="{ 'has-arrow': arrow, 'd-none': !visible }">
|
||||||
|
<div class="popper-arrow" ref="arrow" v-if="arrow"></div>
|
||||||
|
<slot />
|
||||||
|
</div>
|
43
resources/components/stop-details.html
Normal file
43
resources/components/stop-details.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<div v-if="ready">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md">
|
||||||
|
<strong>Linie:</strong>
|
||||||
|
<ul class="stop__lines list-unstyled list-inline">
|
||||||
|
<li v-for="line in lines" class="list-inline-item">
|
||||||
|
<fa :icon="['fac', line.type]" fixed-width></fa>
|
||||||
|
|
||||||
|
<span class="badge badge-dark">
|
||||||
|
<fa :icon="['fas', 'walking']" fixed-width v-if="line.fast"/>
|
||||||
|
<fa :icon="['fal', 'moon']" fixed-width v-if="line.night"/>
|
||||||
|
|
||||||
|
{{ line.symbol }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md">
|
||||||
|
<strong>Trasy:</strong>
|
||||||
|
<ul class="stop__tracks list-underlined">
|
||||||
|
<li v-for="{ track, order } in tracks" class="track">
|
||||||
|
<div class="track__line">
|
||||||
|
<fa :icon="['fac', track.line.type]" fixed-width></fa>
|
||||||
|
<span class="badge badge-dark">
|
||||||
|
<fa :icon="['fas', 'walking']" fixed-width v-if="track.line.fast"/>
|
||||||
|
<fa :icon="['fal', 'moon']" fixed-width v-if="track.line.night"/>
|
||||||
|
|
||||||
|
{{ track.line.symbol }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="track__description">
|
||||||
|
{{ track.description }}
|
||||||
|
</div>
|
||||||
|
<span class="badge badge-pill badge-light track__order">#{{ order }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="text-center">
|
||||||
|
<fa icon="spinner-third" pulse></fa>
|
||||||
|
</div>
|
@ -1,19 +1,22 @@
|
|||||||
<div class="stop">
|
<div class="stop">
|
||||||
<div class="stop__actions">
|
|
||||||
<slot name="actions"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<span class="stop__name">{{ stop.name }}</span>
|
<span class="stop__name">{{ stop.name }}</span>
|
||||||
<span class="stop__description badge badge-dark" v-if="stop.variant">{{ stop.variant }}</span>
|
<span class="stop__description badge badge-dark" v-if="stop.variant">{{ stop.variant }}</span>
|
||||||
|
|
||||||
<slot/>
|
<slot/>
|
||||||
|
|
||||||
<div class="stop__actions flex-space-left">
|
<div class="stop__actions flex-space-left">
|
||||||
<button class="btn btn-action">
|
<slot name="actions">
|
||||||
<fa :icon="['fal', 'info-circle']"/>
|
<button class="btn btn-action" ref="action-info" @click="details = !details">
|
||||||
</button>
|
<fa :icon="['fal', details ? 'chevron-circle-up' : 'info-circle']"/>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button class="btn btn-action">
|
<button class="btn btn-action" ref="action-map">
|
||||||
<fa :icon="['fal', 'map-marked-alt']"/>
|
<fa :icon="['fal', 'map-marked-alt']"/>
|
||||||
</button>
|
</button>
|
||||||
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<fold :visible="details" class="stop__details" lazy>
|
||||||
|
<stop-details :stop="stop"></stop-details>
|
||||||
|
</fold>
|
||||||
</div>
|
</div>
|
@ -1,7 +1,7 @@
|
|||||||
.list-underlined {
|
.list-underlined {
|
||||||
@extend .list-unstyled;
|
@extend .list-unstyled;
|
||||||
|
|
||||||
li {
|
> li {
|
||||||
border-bottom: 1px solid $text-muted;
|
border-bottom: 1px solid $text-muted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,3 +29,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collapse {
|
||||||
|
padding-bottom: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
%flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
@ -8,7 +8,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.departure__stop {
|
.departure__stop {
|
||||||
|
@extend %flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
.stop {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.departure__time {
|
.departure__time {
|
||||||
|
@ -1,8 +1,23 @@
|
|||||||
.line {
|
.line {
|
||||||
display: flex;
|
@extend %flex;
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.line__symbol {
|
.line__symbol {
|
||||||
min-width: 4rem;
|
min-width: 4rem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.track {
|
||||||
|
@extend %flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
|
||||||
|
.track__line {
|
||||||
|
width: 6rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track__description {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
}
|
}
|
108
resources/styles/_popper.scss
Normal file
108
resources/styles/_popper.scss
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
@mixin triangle-border($color, $orientation, $size) {
|
||||||
|
border-width:
|
||||||
|
if($orientation == top, 0, $size)
|
||||||
|
if($orientation == right, 0, $size)
|
||||||
|
if($orientation == bottom, 0, $size)
|
||||||
|
if($orientation == left, 0, $size)
|
||||||
|
;
|
||||||
|
|
||||||
|
border-color:
|
||||||
|
if($orientation == bottom, $color, transparent)
|
||||||
|
if($orientation == left, $color, transparent)
|
||||||
|
if($orientation == top, $color, transparent)
|
||||||
|
if($orientation == right, $color, transparent)
|
||||||
|
;
|
||||||
|
|
||||||
|
#{$orientation}: -$size;
|
||||||
|
@if ($orientation == top) or ($orientation == bottom) {
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
} @else {
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin triangle($orientation, $size, $color, $border: none) {
|
||||||
|
background: $color;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-style: solid;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
@include triangle-border($color, $orientation, $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $border != none {
|
||||||
|
&::before {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-style: solid;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
@include triangle-border($border, $orientation, $size + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin triangle-top($size, $color, $border: none) { @include triangle(top, $size, $color, $border); }
|
||||||
|
@mixin triangle-bottom($size, $color, $border: none) { @include triangle(bottom, $size, $color, $border); }
|
||||||
|
@mixin triangle-left($size, $color, $border: none) { @include triangle(left, $size, $color, $border); }
|
||||||
|
@mixin triangle-right($size, $color, $border: none) { @include triangle(right, $size, $color, $border); }
|
||||||
|
|
||||||
|
.popper {
|
||||||
|
$arrow-base: 10px;
|
||||||
|
$arrow-color: white;
|
||||||
|
$arrow-border: black;
|
||||||
|
|
||||||
|
$popper-padding: .5rem;
|
||||||
|
|
||||||
|
padding: $popper-padding;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid black;
|
||||||
|
z-index: 1000;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
max-width: 500px;
|
||||||
|
min-width: 200px;
|
||||||
|
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
.popper-arrow {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin placement($placement) {
|
||||||
|
$opposite: (
|
||||||
|
left: right,
|
||||||
|
right: left,
|
||||||
|
top: bottom,
|
||||||
|
bottom: top
|
||||||
|
);
|
||||||
|
|
||||||
|
&[x-placement^="#{$placement}"] {
|
||||||
|
margin-#{map-get($opposite, $placement)}: $arrow-base;
|
||||||
|
|
||||||
|
.popper-arrow {
|
||||||
|
#{map-get($opposite, $placement)}: 0;
|
||||||
|
@include triangle(map-get($opposite, $placement), $arrow-base, $arrow-color, $arrow-border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.has-arrow {
|
||||||
|
@include placement("left");
|
||||||
|
@include placement("right");
|
||||||
|
@include placement("top");
|
||||||
|
@include placement("bottom");
|
||||||
|
}
|
||||||
|
|
||||||
|
animation: ease-in fade-in 150ms
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
.stop, .stop-group__header {
|
.stop, .stop-group__header {
|
||||||
display: flex;
|
@extend %flex;
|
||||||
align-items: center;
|
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stop__name {
|
.stop__name {
|
||||||
@ -14,6 +15,9 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stop__details {
|
||||||
|
flex-basis: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.stop-group__name {
|
.stop-group__name {
|
||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
|
@ -15,3 +15,4 @@ $custom-control-indicator-active-bg: $dark;
|
|||||||
@import "departure";
|
@import "departure";
|
||||||
@import "line";
|
@import "line";
|
||||||
@import "controls";
|
@import "controls";
|
||||||
|
@import "popper";
|
@ -1,4 +1,3 @@
|
|||||||
/// <reference path="types/popper.js.d.ts"/>
|
|
||||||
/// <reference path="types/webpack.d.ts"/>
|
/// <reference path="types/webpack.d.ts"/>
|
||||||
|
|
||||||
import '../styles/main.scss'
|
import '../styles/main.scss'
|
||||||
@ -6,13 +5,13 @@ import '../styles/main.scss'
|
|||||||
import './font-awesome'
|
import './font-awesome'
|
||||||
import './filters'
|
import './filters'
|
||||||
|
|
||||||
import * as Popper from 'popper.js';
|
import Popper from 'popper.js';
|
||||||
import * as $ from "jquery";
|
import * as $ from "jquery";
|
||||||
|
|
||||||
import * as components from './components';
|
import * as components from './components';
|
||||||
|
|
||||||
window['$'] = window['jQuery'] = $;
|
window['$'] = window['jQuery'] = $;
|
||||||
window['popper'] = Popper;
|
window['Popper'] = Popper;
|
||||||
|
|
||||||
// dependencies
|
// dependencies
|
||||||
import 'bootstrap'
|
import 'bootstrap'
|
||||||
|
@ -7,7 +7,7 @@ import moment = require("moment");
|
|||||||
import { Jsonified } from "../utils";
|
import { Jsonified } from "../utils";
|
||||||
import { debounce } from "../decorators";
|
import { debounce } from "../decorators";
|
||||||
|
|
||||||
@Component({template})
|
@Component({ template })
|
||||||
export class Departures extends Vue {
|
export class Departures extends Vue {
|
||||||
private _intervalId: number;
|
private _intervalId: number;
|
||||||
|
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
|
export * from './utils'
|
||||||
export * from './picker'
|
export * from './picker'
|
||||||
export * from './departures'
|
export * from './departures'
|
||||||
|
export * from './stop'
|
@ -70,12 +70,5 @@ export class FinderComponent extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({ template: stop })
|
|
||||||
export class StopComponent extends Vue {
|
|
||||||
@Prop(Object)
|
|
||||||
public stop: Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vue.component('StopPicker', PickerComponent);
|
Vue.component('StopPicker', PickerComponent);
|
||||||
Vue.component('StopFinder', FinderComponent);
|
Vue.component('StopFinder', FinderComponent);
|
||||||
Vue.component('Stop', StopComponent);
|
|
||||||
|
50
resources/ts/components/stop.ts
Normal file
50
resources/ts/components/stop.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { Component, Prop } from "vue-property-decorator";
|
||||||
|
import { Line, Stop, Track } from "../model";
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
import template = require('../../components/stop.html');
|
||||||
|
import details = require('../../components/stop-details.html');
|
||||||
|
import urls from "../urls";
|
||||||
|
|
||||||
|
@Component({ template: details })
|
||||||
|
class StopDetailsComponent extends Vue {
|
||||||
|
@Prop(Object)
|
||||||
|
public stop: Stop;
|
||||||
|
|
||||||
|
private ready: boolean = false;
|
||||||
|
|
||||||
|
tracks: { order: number, track: Track }[] = [];
|
||||||
|
|
||||||
|
get types() {
|
||||||
|
return this.tracks.map(t => t.track.line.type).filter((value, index, array) => {
|
||||||
|
return array.indexOf(value) === index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get lines(): Line[] {
|
||||||
|
return this.tracks.map(t => t.track.line).reduce((lines, line: Line) => {
|
||||||
|
return Object.assign(lines, { [line.symbol]: line });
|
||||||
|
}, {} as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
async mounted() {
|
||||||
|
const response = await fetch(urls.prepare(urls.stops.tracks, { id: this.stop.id }));
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
this.tracks = await response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ready = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({ template })
|
||||||
|
export class StopComponent extends Vue {
|
||||||
|
@Prop(Object)
|
||||||
|
public stop: Stop;
|
||||||
|
|
||||||
|
details: boolean = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.component('Stop', StopComponent);
|
||||||
|
Vue.component('StopDetails', StopDetailsComponent);
|
72
resources/ts/components/utils.ts
Normal file
72
resources/ts/components/utils.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import Vue from 'vue';
|
||||||
|
import { Component, Prop, Watch } from "vue-property-decorator";
|
||||||
|
import Popper, { Placement } from "popper.js";
|
||||||
|
import * as $ from 'jquery';
|
||||||
|
|
||||||
|
import popper = require("../../components/popper.html");
|
||||||
|
import lazy = require("../../components/lazy.html");
|
||||||
|
import collapse = require("../../components/fold.html");
|
||||||
|
|
||||||
|
@Component({ template: popper })
|
||||||
|
export class PopperComponent extends Vue {
|
||||||
|
@Prop(String)
|
||||||
|
public reference: string;
|
||||||
|
|
||||||
|
@Prop({ type: String, default: "auto" })
|
||||||
|
public placement: Placement;
|
||||||
|
|
||||||
|
@Prop(Boolean)
|
||||||
|
public arrow: boolean;
|
||||||
|
|
||||||
|
@Prop({ type: Boolean, default: false })
|
||||||
|
public visible: boolean;
|
||||||
|
|
||||||
|
private _popper;
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
const reference = this.$parent.$refs[this.reference] as HTMLElement;
|
||||||
|
|
||||||
|
this._popper = new Popper(reference, this.$el, {
|
||||||
|
placement: this.placement,
|
||||||
|
modifiers: {
|
||||||
|
arrow: { enabled: this.arrow, element: this.$refs['arrow'] as Element }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Watch('visible')
|
||||||
|
private onVisibilityUpdate() {
|
||||||
|
this._popper.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({ template: collapse })
|
||||||
|
export class FoldComponent extends Vue {
|
||||||
|
@Prop(Boolean)
|
||||||
|
public visible: boolean;
|
||||||
|
|
||||||
|
@Prop(Boolean)
|
||||||
|
public lazy: boolean;
|
||||||
|
|
||||||
|
@Watch('visible')
|
||||||
|
private onVisibilityChange(value) {
|
||||||
|
const action = () => $(this.$el).collapse(value ? 'show' : 'hide');
|
||||||
|
setTimeout(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({ template: lazy })
|
||||||
|
export class LazyComponent extends Vue {
|
||||||
|
@Prop(Boolean)
|
||||||
|
public activate: boolean;
|
||||||
|
protected visible: boolean = false;
|
||||||
|
|
||||||
|
@Watch('activate')
|
||||||
|
private onVisibilityChange(value, old) {
|
||||||
|
this.visible = value || old;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.component('Popper', PopperComponent);
|
||||||
|
Vue.component('Fold', FoldComponent);
|
||||||
|
Vue.component('Lazy', LazyComponent);
|
@ -1,4 +1,8 @@
|
|||||||
import { signed } from "./utils";
|
import { signed } from "./utils";
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
Vue.filter('signed', signed);
|
Vue.filter('signed', signed);
|
||||||
|
Vue.directive('hover', (el, binding) => {
|
||||||
|
el.addEventListener('mouseenter', binding.value);
|
||||||
|
el.addEventListener('mouseleave', binding.value);
|
||||||
|
});
|
@ -6,4 +6,10 @@ export interface Line {
|
|||||||
type: LineType;
|
type: LineType;
|
||||||
night: boolean;
|
night: boolean;
|
||||||
fast: boolean;
|
fast: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Track {
|
||||||
|
id: string;
|
||||||
|
description: string;
|
||||||
|
line: Line;
|
||||||
}
|
}
|
131
resources/ts/types/popper.js.d.ts
vendored
131
resources/ts/types/popper.js.d.ts
vendored
@ -1,131 +0,0 @@
|
|||||||
declare class Popper {
|
|
||||||
static modifiers: (Popper.BaseModifier & { name: string })[];
|
|
||||||
static placements: Popper.Placement[];
|
|
||||||
static Defaults: Popper.PopperOptions;
|
|
||||||
|
|
||||||
options: Popper.PopperOptions;
|
|
||||||
|
|
||||||
constructor(reference: Element | Popper.ReferenceObject, popper: Element, options?: Popper.PopperOptions);
|
|
||||||
|
|
||||||
destroy(): void;
|
|
||||||
update(): void;
|
|
||||||
scheduleUpdate(): void;
|
|
||||||
enableEventListeners(): void;
|
|
||||||
disableEventListeners(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare namespace Popper {
|
|
||||||
export type Position = 'top' | 'right' | 'bottom' | 'left';
|
|
||||||
|
|
||||||
export type Placement = 'auto-start'
|
|
||||||
| 'auto'
|
|
||||||
| 'auto-end'
|
|
||||||
| 'top-start'
|
|
||||||
| 'top'
|
|
||||||
| 'top-end'
|
|
||||||
| 'right-start'
|
|
||||||
| 'right'
|
|
||||||
| 'right-end'
|
|
||||||
| 'bottom-end'
|
|
||||||
| 'bottom'
|
|
||||||
| 'bottom-start'
|
|
||||||
| 'left-end'
|
|
||||||
| 'left'
|
|
||||||
| 'left-start';
|
|
||||||
|
|
||||||
export type Boundary = 'scrollParent' | 'viewport' | 'window';
|
|
||||||
|
|
||||||
export type Behavior = 'flip' | 'clockwise' | 'counterclockwise';
|
|
||||||
|
|
||||||
export type ModifierFn = (data: Data, options: Object) => Data;
|
|
||||||
|
|
||||||
export interface BaseModifier {
|
|
||||||
order?: number;
|
|
||||||
enabled?: boolean;
|
|
||||||
fn?: ModifierFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Modifiers {
|
|
||||||
shift?: BaseModifier;
|
|
||||||
offset?: BaseModifier & {
|
|
||||||
offset?: number | string,
|
|
||||||
};
|
|
||||||
preventOverflow?: BaseModifier & {
|
|
||||||
priority?: Position[],
|
|
||||||
padding?: number,
|
|
||||||
boundariesElement?: Boundary | Element,
|
|
||||||
escapeWithReference?: boolean
|
|
||||||
};
|
|
||||||
keepTogether?: BaseModifier;
|
|
||||||
arrow?: BaseModifier & {
|
|
||||||
element?: string | Element,
|
|
||||||
};
|
|
||||||
flip?: BaseModifier & {
|
|
||||||
behavior?: Behavior | Position[],
|
|
||||||
padding?: number,
|
|
||||||
boundariesElement?: Boundary | Element,
|
|
||||||
};
|
|
||||||
inner?: BaseModifier;
|
|
||||||
hide?: BaseModifier;
|
|
||||||
applyStyle?: BaseModifier & {
|
|
||||||
onLoad?: Function,
|
|
||||||
gpuAcceleration?: boolean,
|
|
||||||
};
|
|
||||||
computeStyle?: BaseModifier & {
|
|
||||||
gpuAcceleration?: boolean;
|
|
||||||
x?: 'bottom' | 'top',
|
|
||||||
y?: 'left' | 'right'
|
|
||||||
};
|
|
||||||
|
|
||||||
[name: string]: (BaseModifier & Record<string, any>) | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Offset {
|
|
||||||
top: number;
|
|
||||||
left: number;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Data {
|
|
||||||
instance: Popper;
|
|
||||||
placement: Placement;
|
|
||||||
originalPlacement: Placement;
|
|
||||||
flipped: boolean;
|
|
||||||
hide: boolean;
|
|
||||||
arrowElement: Element;
|
|
||||||
styles: CSSStyleDeclaration;
|
|
||||||
boundaries: Object;
|
|
||||||
offsets: {
|
|
||||||
popper: Offset,
|
|
||||||
reference: Offset,
|
|
||||||
arrow: {
|
|
||||||
top: number,
|
|
||||||
left: number,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PopperOptions {
|
|
||||||
placement?: Placement;
|
|
||||||
positionFixed?: boolean;
|
|
||||||
eventsEnabled?: boolean;
|
|
||||||
modifiers?: Modifiers;
|
|
||||||
removeOnDestroy?: boolean;
|
|
||||||
|
|
||||||
onCreate?(data: Data): void;
|
|
||||||
|
|
||||||
onUpdate?(data: Data): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReferenceObject {
|
|
||||||
clientHeight: number;
|
|
||||||
clientWidth: number;
|
|
||||||
|
|
||||||
getBoundingClientRect(): ClientRect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "popper.js" {
|
|
||||||
export = Popper;
|
|
||||||
}
|
|
@ -52,7 +52,8 @@ export default {
|
|||||||
stops: {
|
stops: {
|
||||||
all: `${base}/stops`,
|
all: `${base}/stops`,
|
||||||
search: `${base}/stops/search`,
|
search: `${base}/stops/search`,
|
||||||
get: `${base}/stops/{id}`
|
get: `${base}/stops/{id}`,
|
||||||
|
tracks: `${base}/stops/{id}/tracks`
|
||||||
},
|
},
|
||||||
prepare: (url: string, params: UrlParams = { }) => prepare(url, Object.assign({}, { provider: window['app'].provider }, params))
|
prepare: (url: string, params: UrlParams = { }) => prepare(url, Object.assign({}, { provider: window['app'].provider }, params))
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ type Simplify<T, K = any> = string |
|
|||||||
|
|
||||||
export type Jsonified<T> = { [K in keyof T]: Simplify<T[K]> }
|
export type Jsonified<T> = { [K in keyof T]: Simplify<T[K]> }
|
||||||
export type Optionalify<T> = { [K in keyof T]?: T[K] }
|
export type Optionalify<T> = { [K in keyof T]?: T[K] }
|
||||||
|
export type Dictionary<T> = { [key: string]: T };
|
||||||
|
|
||||||
export type Index = string | symbol | number;
|
export type Index = string | symbol | number;
|
||||||
|
|
||||||
|
@ -4,7 +4,10 @@
|
|||||||
namespace App\Controller\Api\v1;
|
namespace App\Controller\Api\v1;
|
||||||
|
|
||||||
use App\Controller\Controller;
|
use App\Controller\Controller;
|
||||||
|
use App\Model\Stop;
|
||||||
use App\Provider\StopRepository;
|
use App\Provider\StopRepository;
|
||||||
|
use App\Provider\TrackRepository;
|
||||||
|
use App\Service\Proxy\ReferenceFactory;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
@ -47,4 +50,16 @@ class StopsController extends Controller
|
|||||||
{
|
{
|
||||||
return $this->json($stops->getById($id));
|
return $this->json($stops->getById($id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/{id}/tracks", methods={"GET"})
|
||||||
|
*/
|
||||||
|
public function tracks(ReferenceFactory $reference, TrackRepository $tracks, $id)
|
||||||
|
{
|
||||||
|
$stop = $reference->get(Stop::class, $id);
|
||||||
|
|
||||||
|
return $this->json($tracks->getByStop($stop)->map(function ($tuple) {
|
||||||
|
return array_combine(['track', 'order'], $tuple);
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
@ -45,7 +45,7 @@ class TrackEntity implements Entity, Fillable
|
|||||||
/**
|
/**
|
||||||
* Stops in track
|
* Stops in track
|
||||||
* @var Collection
|
* @var Collection
|
||||||
* @ORM\OneToMany(targetEntity=StopInTrack::class, mappedBy="track", cascade={"persist"})
|
* @ORM\OneToMany(targetEntity=StopInTrack::class, fetch="EXTRA_LAZY", mappedBy="track", cascade={"persist"})
|
||||||
* @ORM\OrderBy({"order": "ASC"})
|
* @ORM\OrderBy({"order": "ASC"})
|
||||||
*/
|
*/
|
||||||
private $stopsInTrack;
|
private $stopsInTrack;
|
||||||
@ -104,9 +104,4 @@ class TrackEntity implements Entity, Fillable
|
|||||||
{
|
{
|
||||||
$this->stopsInTrack = new ArrayCollection($stopsInTrack);
|
$this->stopsInTrack = new ArrayCollection($stopsInTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStops()
|
|
||||||
{
|
|
||||||
return $this->getStopsInTrack()->map(t\property('stop'));
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ namespace App\Provider\Database;
|
|||||||
|
|
||||||
use App\Entity\Entity;
|
use App\Entity\Entity;
|
||||||
use App\Entity\ProviderEntity;
|
use App\Entity\ProviderEntity;
|
||||||
|
use App\Model\Referable;
|
||||||
use App\Service\EntityConverter;
|
use App\Service\EntityConverter;
|
||||||
use App\Service\IdUtils;
|
use App\Service\IdUtils;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
@ -48,4 +49,11 @@ class DatabaseRepository
|
|||||||
{
|
{
|
||||||
return $this->converter->convert($entity);
|
return $this->converter->convert($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function reference($class, Referable $referable)
|
||||||
|
{
|
||||||
|
$id = $this->id->generate($this->provider, $referable->getId());
|
||||||
|
|
||||||
|
return $this->em->getReference($class, $id);
|
||||||
|
}
|
||||||
}
|
}
|
61
src/Provider/Database/GenericTrackRepository.php
Normal file
61
src/Provider/Database/GenericTrackRepository.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Provider\Database;
|
||||||
|
|
||||||
|
use App\Entity\LineEntity;
|
||||||
|
use App\Entity\StopEntity;
|
||||||
|
use App\Entity\StopInTrack;
|
||||||
|
use App\Entity\TrackEntity;
|
||||||
|
use App\Model\Track;
|
||||||
|
use App\Provider\TrackRepository;
|
||||||
|
use Tightenco\Collect\Support\Collection;
|
||||||
|
use Kadet\Functional as f;
|
||||||
|
|
||||||
|
class GenericTrackRepository extends DatabaseRepository implements TrackRepository
|
||||||
|
{
|
||||||
|
public function getAll(): Collection
|
||||||
|
{
|
||||||
|
$tracks = $this->em->getRepository(TrackEntity::class)->findAll();
|
||||||
|
|
||||||
|
return collect($tracks)->map(f\ref([$this, 'convert']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getById($id): Track
|
||||||
|
{
|
||||||
|
// TODO: Implement getById() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getManyById($ids): Collection
|
||||||
|
{
|
||||||
|
// TODO: Implement getManyById() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByStop($stop): Collection
|
||||||
|
{
|
||||||
|
$tracks = $this->em->createQueryBuilder()
|
||||||
|
->from(StopInTrack::class, 'st')
|
||||||
|
->join('st.track', 't')
|
||||||
|
->where('st.stop = :stop')
|
||||||
|
->select(['st', 't'])
|
||||||
|
->getQuery()
|
||||||
|
->execute(['stop' => $this->reference(StopEntity::class, $stop)]);
|
||||||
|
|
||||||
|
return collect($tracks)->map(function (StopInTrack $entity) {
|
||||||
|
return [ $this->convert($entity->getTrack()), $entity->getOrder() ];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByLine($line): Collection
|
||||||
|
{
|
||||||
|
$tracks = $this->em->createQueryBuilder()
|
||||||
|
->from(StopInTrack::class, 'st')
|
||||||
|
->join('st.track', 't')
|
||||||
|
->join('t.stops', 's')
|
||||||
|
->where('st.line = :line')
|
||||||
|
->select(['st', 't', 's'])
|
||||||
|
->getQuery()
|
||||||
|
->execute(['stop' => $this->reference(LineEntity::class, $line)]);
|
||||||
|
|
||||||
|
return collect($tracks)->map(f\ref([$this, 'convert']));
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ interface Provider
|
|||||||
public function getLineRepository(): LineRepository;
|
public function getLineRepository(): LineRepository;
|
||||||
public function getStopRepository(): StopRepository;
|
public function getStopRepository(): StopRepository;
|
||||||
public function getMessageRepository(): MessageRepository;
|
public function getMessageRepository(): MessageRepository;
|
||||||
|
public function getTrackRepository(): TrackRepository;
|
||||||
|
|
||||||
public function getName();
|
public function getName();
|
||||||
public function getIdentifier();
|
public function getIdentifier();
|
||||||
|
17
src/Provider/TrackRepository.php
Normal file
17
src/Provider/TrackRepository.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Provider;
|
||||||
|
|
||||||
|
use App\Model\Track;
|
||||||
|
use Tightenco\Collect\Support\Collection;
|
||||||
|
|
||||||
|
interface TrackRepository
|
||||||
|
{
|
||||||
|
public function getAll(): Collection;
|
||||||
|
|
||||||
|
public function getById($id): Track;
|
||||||
|
public function getManyById($ids): Collection;
|
||||||
|
|
||||||
|
public function getByStop($stop): Collection;
|
||||||
|
public function getByLine($line): Collection;
|
||||||
|
}
|
@ -159,8 +159,8 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
|
|||||||
$this->logger->info(sprintf('Saving %d tracks from ZTM Gdańsk', count($stops)));
|
$this->logger->info(sprintf('Saving %d tracks from ZTM Gdańsk', count($stops)));
|
||||||
|
|
||||||
return collect($tracks)->map(function ($track) use ($provider, $stops) {
|
return collect($tracks)->map(function ($track) use ($provider, $stops) {
|
||||||
$track = TrackEntity::createFromArray([
|
$entity = TrackEntity::createFromArray([
|
||||||
'id' => $track['id'],
|
'id' => $this->ids->generate($provider, $track['id']),
|
||||||
'line' => $this->em->getReference(
|
'line' => $this->em->getReference(
|
||||||
LineEntity::class,
|
LineEntity::class,
|
||||||
$this->ids->generate($provider, $track['routeId'])
|
$this->ids->generate($provider, $track['routeId'])
|
||||||
@ -169,20 +169,20 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
|
|||||||
'provider' => $provider,
|
'provider' => $provider,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$stops = $stops->get($track->getId())->map(function ($stop) use ($track, $provider) {
|
$stops = $stops->get($track['id'])->map(function ($stop) use ($entity, $provider) {
|
||||||
return StopInTrack::createFromArray([
|
return StopInTrack::createFromArray([
|
||||||
'stop' => $this->em->getReference(
|
'stop' => $this->em->getReference(
|
||||||
StopEntity::class,
|
StopEntity::class,
|
||||||
$this->ids->generate($provider, $stop['stopId'])
|
$this->ids->generate($provider, $stop['stopId'])
|
||||||
),
|
),
|
||||||
'track' => $track,
|
'track' => $entity,
|
||||||
'order' => $stop['stopSequence'],
|
'order' => $stop['stopSequence'],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
$track->setStopsInTrack($stops->all());
|
$entity->setStopsInTrack($stops->all());
|
||||||
|
|
||||||
return $track;
|
return $entity;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ namespace App\Provider;
|
|||||||
use App\Entity\ProviderEntity;
|
use App\Entity\ProviderEntity;
|
||||||
use App\Provider\Database\GenericLineRepository;
|
use App\Provider\Database\GenericLineRepository;
|
||||||
use App\Provider\Database\GenericStopRepository;
|
use App\Provider\Database\GenericStopRepository;
|
||||||
|
use App\Provider\Database\GenericTrackRepository;
|
||||||
use App\Provider\ZtmGdansk\{ZtmGdanskDepartureRepository, ZtmGdanskMessageRepository};
|
use App\Provider\ZtmGdansk\{ZtmGdanskDepartureRepository, ZtmGdanskMessageRepository};
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ class ZtmGdanskProvider implements Provider
|
|||||||
private $lines;
|
private $lines;
|
||||||
private $departures;
|
private $departures;
|
||||||
private $stops;
|
private $stops;
|
||||||
|
private $tracks;
|
||||||
private $messages;
|
private $messages;
|
||||||
|
|
||||||
public function getName()
|
public function getName()
|
||||||
@ -30,17 +32,20 @@ class ZtmGdanskProvider implements Provider
|
|||||||
EntityManagerInterface $em,
|
EntityManagerInterface $em,
|
||||||
GenericLineRepository $lines,
|
GenericLineRepository $lines,
|
||||||
GenericStopRepository $stops,
|
GenericStopRepository $stops,
|
||||||
|
GenericTrackRepository $tracks,
|
||||||
ZtmGdanskMessageRepository $messages
|
ZtmGdanskMessageRepository $messages
|
||||||
) {
|
) {
|
||||||
$provider = $em->getReference(ProviderEntity::class, $this->getIdentifier());
|
$provider = $em->getReference(ProviderEntity::class, $this->getIdentifier());
|
||||||
|
|
||||||
$lines = $lines->withProvider($provider);
|
$lines = $lines->withProvider($provider);
|
||||||
$stops = $stops->withProvider($provider);
|
$stops = $stops->withProvider($provider);
|
||||||
|
$tracks = $tracks->withProvider($provider);
|
||||||
|
|
||||||
$this->lines = $lines;
|
$this->lines = $lines;
|
||||||
$this->departures = new ZtmGdanskDepartureRepository($lines);
|
$this->departures = new ZtmGdanskDepartureRepository($lines);
|
||||||
$this->stops = $stops;
|
$this->stops = $stops;
|
||||||
$this->messages = $messages;
|
$this->messages = $messages;
|
||||||
|
$this->tracks = $tracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDepartureRepository(): DepartureRepository
|
public function getDepartureRepository(): DepartureRepository
|
||||||
@ -62,4 +67,9 @@ class ZtmGdanskProvider implements Provider
|
|||||||
{
|
{
|
||||||
return $this->messages;
|
return $this->messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTrackRepository(): TrackRepository
|
||||||
|
{
|
||||||
|
return $this->tracks;
|
||||||
|
}
|
||||||
}
|
}
|
@ -11,10 +11,11 @@ use App\Model\Line;
|
|||||||
use App\Model\Operator;
|
use App\Model\Operator;
|
||||||
use App\Model\Stop;
|
use App\Model\Stop;
|
||||||
use App\Model\Track;
|
use App\Model\Track;
|
||||||
use App\Service\Proxy\ReferenceObjectFactory;
|
use App\Service\Proxy\ReferenceFactory;
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection;
|
||||||
use Doctrine\ORM\Proxy\Proxy;
|
use Doctrine\ORM\Proxy\Proxy;
|
||||||
use Kadet\Functional as f;
|
use Kadet\Functional as f;
|
||||||
|
use Kadet\Functional\Transforms as t;
|
||||||
use const Kadet\Functional\_;
|
use const Kadet\Functional\_;
|
||||||
|
|
||||||
final class EntityConverter
|
final class EntityConverter
|
||||||
@ -22,7 +23,7 @@ final class EntityConverter
|
|||||||
private $id;
|
private $id;
|
||||||
private $reference;
|
private $reference;
|
||||||
|
|
||||||
public function __construct(IdUtils $id, ReferenceObjectFactory $reference)
|
public function __construct(IdUtils $id, ReferenceFactory $reference)
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->reference = $reference;
|
$this->reference = $reference;
|
||||||
@ -66,7 +67,7 @@ final class EntityConverter
|
|||||||
'operator' => $convert($entity->getOperator()),
|
'operator' => $convert($entity->getOperator()),
|
||||||
'night' => $entity->isNight(),
|
'night' => $entity->isNight(),
|
||||||
'fast' => $entity->isFast(),
|
'fast' => $entity->isFast(),
|
||||||
'tracks' => $this->collection($entity->getTracks(), $convert),
|
'tracks' => $this->collection($entity->getTracks())->map($convert),
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -74,7 +75,9 @@ final class EntityConverter
|
|||||||
$result->fill([
|
$result->fill([
|
||||||
'variant' => $entity->getVariant(),
|
'variant' => $entity->getVariant(),
|
||||||
'description' => $entity->getDescription(),
|
'description' => $entity->getDescription(),
|
||||||
'stops' => $this->collection($entity->getStops(), $convert),
|
'stops' => $this->collection($entity->getStopsInTrack())
|
||||||
|
->map(t\property('stop'))
|
||||||
|
->map($convert),
|
||||||
'line' => $convert($entity->getLine()),
|
'line' => $convert($entity->getLine()),
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
@ -89,6 +92,7 @@ final class EntityConverter
|
|||||||
$entity->getLongitude(),
|
$entity->getLongitude(),
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@ -106,10 +110,10 @@ final class EntityConverter
|
|||||||
return $entity->getId();
|
return $entity->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function collection(PersistentCollection $collection, $converter)
|
private function collection($collection)
|
||||||
{
|
{
|
||||||
if ($collection->isInitialized()) {
|
if (!$collection instanceof PersistentCollection || $collection->isInitialized()) {
|
||||||
return collect($collection)->map($converter);
|
return collect($collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
return collect();
|
return collect();
|
||||||
|
@ -26,7 +26,7 @@ class JustReferenceNormalizer implements NormalizerInterface
|
|||||||
*/
|
*/
|
||||||
public function normalize($object, $format = null, array $context = [])
|
public function normalize($object, $format = null, array $context = [])
|
||||||
{
|
{
|
||||||
return [ 'id' => $object->getId() ];
|
return [ 'id' => $object->getId(), 'href' => '#' ];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,7 @@ namespace App\Service\Proxy;
|
|||||||
use ProxyManager\Factory\AbstractBaseFactory;
|
use ProxyManager\Factory\AbstractBaseFactory;
|
||||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||||
|
|
||||||
class ReferenceObjectFactory extends AbstractBaseFactory
|
class ReferenceFactory extends AbstractBaseFactory
|
||||||
{
|
{
|
||||||
public function get($class, $id)
|
public function get($class, $id)
|
||||||
{
|
{
|
@ -9,6 +9,7 @@ use App\Provider\DepartureRepository;
|
|||||||
use App\Provider\LineRepository;
|
use App\Provider\LineRepository;
|
||||||
use App\Provider\MessageRepository;
|
use App\Provider\MessageRepository;
|
||||||
use App\Provider\StopRepository;
|
use App\Provider\StopRepository;
|
||||||
|
use App\Provider\TrackRepository;
|
||||||
use const Kadet\Functional\_;
|
use const Kadet\Functional\_;
|
||||||
use function Kadet\Functional\any;
|
use function Kadet\Functional\any;
|
||||||
use function Kadet\Functional\curry;
|
use function Kadet\Functional\curry;
|
||||||
@ -59,6 +60,10 @@ class RepositoryParameterConverter implements ParamConverterInterface
|
|||||||
$request->attributes->set($configuration->getName(), $provider->getMessageRepository());
|
$request->attributes->set($configuration->getName(), $provider->getMessageRepository());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case is_a($class, TrackRepository::class, true):
|
||||||
|
$request->attributes->set($configuration->getName(), $provider->getTrackRepository());
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -75,7 +80,8 @@ class RepositoryParameterConverter implements ParamConverterInterface
|
|||||||
StopRepository::class,
|
StopRepository::class,
|
||||||
LineRepository::class,
|
LineRepository::class,
|
||||||
DepartureRepository::class,
|
DepartureRepository::class,
|
||||||
MessageRepository::class
|
MessageRepository::class,
|
||||||
|
TrackRepository::class,
|
||||||
]));
|
]));
|
||||||
|
|
||||||
return $supports($configuration->getClass());
|
return $supports($configuration->getClass());
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{% extends 'base.html.twig' %}
|
{% extends 'base.html.twig' %}
|
||||||
{% block title "#{parent()} - #{provider.name}" %}
|
{% block title "#{parent()} - #{provider.name}" %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<stop-picker></stop-picker>
|
<stop-picker></stop-picker>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user