diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b6afd82 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "endOfLine": "auto", + "printWidth": 120 +} diff --git a/src/components/VehiclesManager/VehicleGroupsTable.vue b/src/components/VehiclesManager/VehicleGroupsTable.vue new file mode 100644 index 0000000..0ffc0c3 --- /dev/null +++ b/src/components/VehiclesManager/VehicleGroupsTable.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/components/VehiclesManager/VehiclesTable.vue b/src/components/VehiclesManager/VehiclesTable.vue new file mode 100644 index 0000000..6989e58 --- /dev/null +++ b/src/components/VehiclesManager/VehiclesTable.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/stores/vehicles.store.ts b/src/stores/vehicles.store.ts index 06a81cf..08f6bf7 100644 --- a/src/stores/vehicles.store.ts +++ b/src/stores/vehicles.store.ts @@ -1,6 +1,13 @@ import { defineStore } from 'pinia'; import client from '../common/http'; -import { IVehicle, IVehicleTableRow, VehicleAPIResponse } from '../types/vehicles.types'; +import { + IVehicle, + IVehicleAPI, + IVehicleGroupTableRow, + IVehicleTableRow, + VehicleAPIResponse, + VehicleGroupAPIResponse, +} from '../types/vehicles.types'; import { LoadingState } from '../types/common.types'; export const useVehiclesStore = defineStore('vehiclesStore', { @@ -9,6 +16,7 @@ export const useVehiclesStore = defineStore('vehiclesStore', { dataState: LoadingState.INIT, vehiclesTable: [] as IVehicleTableRow[], + vehicleGroupsTable: [] as IVehicleGroupTableRow[], }), actions: { @@ -16,9 +24,25 @@ export const useVehiclesStore = defineStore('vehiclesStore', { try { this.dataState = LoadingState.LOADING; - const vehiclesResponseData = (await client.get(`api/getVehicles`)).data; - this.vehicles = vehiclesResponseData; - this.vehiclesTable = vehiclesResponseData.map((v) => ({ vehicleRef: v, pendingChanges: {} })); + const [vehiclesData, vehicleGroupsData] = await Promise.all([ + (await client.get(`manager/vehicles`)).data, + (await client.get(`manager/vehicleGroups`)).data, + ]); + + this.vehicles = vehiclesData.map((v) => { + return { + ...v, + group: vehicleGroupsData.find((g) => g.id == v.vehicleGroupsId)!, + }; + }); + + this.vehiclesTable = this.vehicles.map((v) => ({ + vehicleRef: v, + })); + + this.vehicleGroupsTable = vehicleGroupsData.map((g) => ({ + vehicleGroupRef: g, + })); this.dataState = LoadingState.SUCCESS; } catch (error) { @@ -26,5 +50,19 @@ export const useVehiclesStore = defineStore('vehiclesStore', { this.dataState = LoadingState.ERROR; } }, + + async updateVehicle(vehicleId: number, propKey: string, propValue: any) { + try { + const response = await client.put(`/manager/vehicles/${vehicleId}`, { + [propKey]: propValue, + }); + + return response.data; + } catch (error) { + console.error(error); + } + + return null; + }, }, }); diff --git a/src/styles/_global.scss b/src/styles/_global.scss index d85b277..7e6941d 100644 --- a/src/styles/_global.scss +++ b/src/styles/_global.scss @@ -33,6 +33,56 @@ a:visited { box-sizing: inherit; } +// Tables +table { + table-layout: fixed; + text-align: center; + color: white; + position: relative; + border-collapse: collapse; + width: 100%; +} + +table thead { + position: sticky; + top: 0; +} + +table thead td { + padding: 0.4rem 0.45rem; + background-color: #151b24; + color: white; + top: 0; +} + +table tbody tr { + background-color: #2c394b; + transition: background-color 100ms; + text-overflow: ellipsis; +} + +table tr:nth-child(even) { + background-color: #334756; +} + +table tr:hover { + background-color: #1a293b; + cursor: pointer; +} + +table tbody tr td { + padding: 0.3rem 0.5rem; + border: 1px solid #2c2c2c; + overflow: hidden; + text-overflow: ellipsis; +} + +td img { + height: 1.45em; + vertical-align: middle; +} + +// Other button, select, input { diff --git a/src/types/vehicles.types.ts b/src/types/vehicles.types.ts index 2e624be..a664703 100644 --- a/src/types/vehicles.types.ts +++ b/src/types/vehicles.types.ts @@ -1,4 +1,14 @@ -export type VehicleAPIResponse = IVehicle[]; +export type VehicleAPIResponse = IVehicleAPI[]; +export type VehicleGroupAPIResponse = IVehicleGroup[]; + +export interface IVehicleAPI { + id: number; + name: string; + type: string; + cabinName?: string; + restrictions?: IVehicleRestrictions; + vehicleGroupsId: number; +} export interface IVehicle { id: number; @@ -6,7 +16,6 @@ export interface IVehicle { type: string; cabinName?: string; restrictions?: IVehicleRestrictions; - vehicleGroupsId: number; group: IVehicleGroup; } @@ -15,14 +24,24 @@ export interface IVehicleRestrictions { teamOnly?: boolean; } +export interface IVehicleGroupMassSpeeds { + none: number; + passenger: Record | null; + cargo: Record | null; +} + export interface IVehicleGroup { id: number; name: string; speed: number; + speedLoaded: number | null; + speedLoco: number | null; length: number; weight: number; - cargoTypes?: IVehicleCargoType[]; - locoProps?: IVehicleLocoProps; + cargoTypes: IVehicleCargoType[] | null; + locoProps: IVehicleLocoProps | null; + massSpeeds: IVehicleGroupMassSpeeds | null; + _count: { vehicles: number }; } export interface IVehicleCargoType { @@ -37,17 +56,21 @@ export interface IVehicleLocoProps { export interface IVehicleTableRow { vehicleRef: IVehicle; - pendingChanges: Partial; + // pendingChanges: Partial; +} + +export interface IVehicleGroupTableRow { + vehicleGroupRef: IVehicleGroup; + // pendingChanges: Partial; } export enum VehicleEditRowKey { NAME = 'name', TYPE = 'type', CABIN = 'cabinName', - } export enum VehicleEditRestrictionKey { - SPONSOR_ONLY = "sponsorOnly", - TEAM_ONLY = "teamOnly" -} \ No newline at end of file + SPONSOR_ONLY = 'sponsorOnly', + TEAM_ONLY = 'teamOnly', +} diff --git a/src/views/ManagerView.vue b/src/views/ManagerView.vue index 3461a2b..b7e0501 100644 --- a/src/views/ManagerView.vue +++ b/src/views/ManagerView.vue @@ -19,9 +19,15 @@ - + URL - URL + URL {{ station[propName] ? 'POKAŻ' : 'DODAJ' }} @@ -141,7 +147,9 @@ export default defineComponent({ return; } - const stationListRow = this.sceneriesStore.stationList.findIndex((station) => station.name == this.sceneriesStore.sortedStationList[row].name); + const stationListRow = this.sceneriesStore.stationList.findIndex( + (station) => station.name == this.sceneriesStore.sortedStationList[row].name, + ); if (stationListRow == -1) return; const oldValue = (this.sceneriesStore.stationList[stationListRow] as any)[propertyName]; @@ -152,15 +160,21 @@ export default defineComponent({ return; } - let newValue = prompt(`Zmień wartość dla rubryki ${this.headers.find((h) => h.id === propertyName)?.value ?? ''}`, oldValue || ''); + let newValue = prompt( + `Zmień wartość dla rubryki ${this.headers.find((h) => h.id === propertyName)?.value ?? ''}`, + oldValue || '', + ); if (newValue == null) return; - (this.sceneriesStore.stationList[stationListRow] as any)[propertyName] = typeof oldValue === 'number' ? parseInt(newValue) : newValue; + (this.sceneriesStore.stationList[stationListRow] as any)[propertyName] = + typeof oldValue === 'number' ? parseInt(newValue) : newValue; // this.$set(this.stationList[stationListRow], propertyName, parseInt(newValue)); this.addChange(station, propertyName, oldValue, typeof oldValue === 'number' ? parseInt(newValue) : newValue); }, changeCheckpoints(row: number) { - const stationListRow = this.sceneriesStore.stationList.findIndex((station) => station.name == this.sceneriesStore.sortedStationList[row].name); + const stationListRow = this.sceneriesStore.stationList.findIndex( + (station) => station.name == this.sceneriesStore.sortedStationList[row].name, + ); if (stationListRow == -1) return; const oldCheckpoints = this.sceneriesStore.stationList[stationListRow].checkpoints; @@ -200,33 +214,6 @@ export default defineComponent({ width: 100%; } -table { - table-layout: fixed; - text-align: center; - color: white; - position: relative; - border-collapse: collapse; - width: 100%; -} - -table thead { - position: sticky; - top: 0; -} - -table thead td { - padding: 0.4rem 0.45rem; - background-color: #151b24; - color: white; - top: 0; -} - -table tbody tr { - background-color: #2c394b; - transition: background-color 100ms; - text-overflow: ellipsis; -} - table tr.current { outline: 1px solid white; } @@ -235,25 +222,4 @@ table td.routes { font-size: 0.9em; min-width: 150px; } - -table tr:nth-child(even) { - background-color: #334756; -} - -table tr:hover { - background-color: #1a293b; - cursor: pointer; -} - -table tbody tr td { - padding: 0.3rem 0.5rem; - border: 1px solid #2c2c2c; - overflow: hidden; - text-overflow: ellipsis; -} - -td img { - height: 1.45em; - vertical-align: middle; -} diff --git a/src/views/VehiclesManagerView.vue b/src/views/VehiclesManagerView.vue index 1d52bbf..2c63e94 100644 --- a/src/views/VehiclesManagerView.vue +++ b/src/views/VehiclesManagerView.vue @@ -6,188 +6,47 @@ logo

Edytor pojazdów

- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
#NazwaTypKabina (lok.)GrupaTylko sponsorzy doTylko zespół
{{ row.vehicleRef.id }} - {{ row.pendingChanges.name ?? row.vehicleRef.name }} - - {{ row.pendingChanges.type ?? row.vehicleRef.type }} - - {{ row.pendingChanges.cabinName ?? row.vehicleRef.cabinName }} - {{ row.vehicleRef.group.name }} - - {{ new Date(row.pendingChanges.restrictions.sponsorOnly).toLocaleString() }} - - - - {{ new Date(row.vehicleRef.restrictions.sponsorOnly).toLocaleString() }} - - - - - - {{ row.pendingChanges.restrictions.teamOnly ? '✔️' : '❌' }} - - - - {{ row.vehicleRef.restrictions.teamOnly ? '✔️' : '❌' }} - - - -
+
+ +
+ + + +
- -