Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 99019ddeef | |||
| 80f0e5437c | |||
| 80cfa52413 | |||
| 07575302cc | |||
| c765b06404 | |||
| 280067648f | |||
| 0ff30e9761 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -20,6 +20,7 @@ import { Public } from '@noahspan/noahspan-modules';
|
||||
export class LogController {
|
||||
constructor(private readonly logService: LogService) {}
|
||||
|
||||
@Public()
|
||||
@Get(':partitionKey/:rowKey')
|
||||
async find(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
|
||||
@@ -9,6 +9,7 @@ async function bootstrap() {
|
||||
const httpService = new HttpService();
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
app.enableCors();
|
||||
app.setGlobalPrefix('api');
|
||||
app.useGlobalFilters(new HttpExceptionFilter());
|
||||
|
||||
|
||||
@@ -19,15 +19,10 @@ export class PilotInterceptor implements NestInterceptor {
|
||||
name: pilot.name
|
||||
};
|
||||
});
|
||||
|
||||
console.log(pilots)
|
||||
return pilots;
|
||||
} else {
|
||||
return {
|
||||
partitionKey: data.partitionKey,
|
||||
rowKey: data.rowKey,
|
||||
id: data.id,
|
||||
name: data.name
|
||||
};
|
||||
return data;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@@ -7,18 +7,21 @@ import {
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
UseGuards,
|
||||
UseInterceptors,
|
||||
} from '@nestjs/common';
|
||||
import { PilotDto } from './pilot.dto';
|
||||
import { Pilot } from './pilot.entity';
|
||||
import { PilotService } from './pilot.service';
|
||||
import { CustomError } from '../error/customError';
|
||||
import { AuthGuard } from '@nestjs/passport'
|
||||
import { Public } from '@noahspan/noahspan-modules'
|
||||
import { PilotInterceptor } from './interceptors/pilot.interceptor';
|
||||
|
||||
@Controller('pilots')
|
||||
@UseInterceptors(new PilotInterceptor())
|
||||
export class PilotController {
|
||||
constructor(private readonly pilotService: PilotService) {}
|
||||
|
||||
@Public()
|
||||
@Get(':partitionKey/:rowKey')
|
||||
async find(
|
||||
@Param('partitionKey') partitionKey: string,
|
||||
@@ -33,6 +36,7 @@ export class PilotController {
|
||||
}
|
||||
}
|
||||
|
||||
@Public()
|
||||
@Get()
|
||||
async findAll() {
|
||||
try {
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Flying
|
||||
|
||||
A pilot's logbook for tracking flight hours.
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "app",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -12,11 +12,13 @@ import {
|
||||
TrashIcon
|
||||
} from '@noahspan/noahspan-components';
|
||||
import { FormMode } from '../../enums/formMode';
|
||||
import { useIsAuthenticated } from '@azure/msal-react';
|
||||
|
||||
const ActionMenu = ({ id, onDelete, onOpenCloseForm }: IActionMenuProps) => {
|
||||
const [anchorElAction, setAnchorElAction] = useState<null | HTMLElement>(
|
||||
null
|
||||
);
|
||||
const isAuthenticated = useIsAuthenticated();
|
||||
|
||||
const onOpenActionMenu = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorElAction(event.currentTarget);
|
||||
@@ -37,25 +39,31 @@ const ActionMenu = ({ id, onDelete, onOpenCloseForm }: IActionMenuProps) => {
|
||||
open={Boolean(anchorElAction)}
|
||||
onClose={onCloseActionMenu}
|
||||
>
|
||||
<MenuItem onClick={() => onOpenCloseForm(FormMode.EDIT, id)}>
|
||||
<ListItemIcon>
|
||||
<PenIcon size="lg" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>Edit</ListItemText>
|
||||
</MenuItem>
|
||||
{isAuthenticated &&
|
||||
<MenuItem onClick={() => onOpenCloseForm(FormMode.EDIT, id)}>
|
||||
<ListItemIcon>
|
||||
<PenIcon size="lg" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>Edit</ListItemText>
|
||||
</MenuItem>
|
||||
}
|
||||
<MenuItem onClick={() => onOpenCloseForm(FormMode.VIEW, id)}>
|
||||
<ListItemIcon>
|
||||
<EyeIcon size="lg" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>View</ListItemText>
|
||||
</MenuItem>
|
||||
<hr className="my-3" />
|
||||
<MenuItem onClick={() => onDelete(id)}>
|
||||
<ListItemIcon>
|
||||
<TrashIcon size="lg" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>Delete</ListItemText>
|
||||
</MenuItem>
|
||||
{isAuthenticated &&
|
||||
<>
|
||||
<hr className="my-3" />
|
||||
<MenuItem onClick={() => onDelete(id)}>
|
||||
<ListItemIcon>
|
||||
<TrashIcon size="lg" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>Delete</ListItemText>
|
||||
</MenuItem>
|
||||
</>
|
||||
}
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -123,6 +123,15 @@ const LogForm: React.FC<ILogFormProps> = ({
|
||||
);
|
||||
const entry = response.data;
|
||||
|
||||
// if (mode !== FormMode.ADD) {
|
||||
// const pilot = pilots?.find((pilot) => pilot.id === entry.pilotId);
|
||||
// console.log(pilot.name)
|
||||
// dispatch({
|
||||
// type: 'SET_SELECTED_ENTRY_PILOT_NAME',
|
||||
// payload: pilot.name
|
||||
// });
|
||||
// }
|
||||
|
||||
methods.reset(entry);
|
||||
} catch (error) {
|
||||
const axiosError = error as AxiosError;
|
||||
@@ -139,7 +148,7 @@ const LogForm: React.FC<ILogFormProps> = ({
|
||||
}, [entryId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (pilots) {
|
||||
if (pilots && FormMode.ADD) {
|
||||
const newPilotsOptions = pilots.map((pilot) => {
|
||||
return {
|
||||
label: pilot.name,
|
||||
@@ -166,7 +175,7 @@ const LogForm: React.FC<ILogFormProps> = ({
|
||||
<form onSubmit={methods.handleSubmit(onSubmit)}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid size={11}>
|
||||
<Typography variant="h4">{`${mode.toString().toLowerCase().charAt(0).toUpperCase() + mode.toString().slice(1).toLowerCase()} Pilot`}</Typography>
|
||||
<Typography variant="h4">{`${mode.toString().toLowerCase().charAt(0).toUpperCase() + mode.toString().slice(1).toLowerCase()} Entry`}</Typography>
|
||||
</Grid>
|
||||
<Grid display="flex" justifyContent="right" size={1}>
|
||||
<IconButton onClick={onCancel}>
|
||||
@@ -194,50 +203,29 @@ const LogForm: React.FC<ILogFormProps> = ({
|
||||
name="pilotId"
|
||||
control={methods.control}
|
||||
render={({ field: { onChange, value } }) => {
|
||||
useEffect(() => {
|
||||
if (value && mode !== FormMode.ADD) {
|
||||
const pilot = pilots?.find((pilot) => pilot.id === value);
|
||||
|
||||
dispatch({
|
||||
type: 'SET_SELECTED_ENTRY_PILOT_NAME',
|
||||
payload: pilot.name
|
||||
});
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
console.log(value)
|
||||
return (
|
||||
<>
|
||||
{mode === FormMode.ADD && (
|
||||
<Select
|
||||
disabled={state.isDisabled}
|
||||
fullWidth
|
||||
onChange={(event) => {
|
||||
const pilot = pilots?.find(
|
||||
(pilot) => (pilot.id = event.target.value)
|
||||
);
|
||||
<Select
|
||||
disabled={state.isDisabled}
|
||||
fullWidth
|
||||
onChange={(event) => {
|
||||
const pilot = pilots?.find(
|
||||
(pilot) => (pilot.id = event.target.value)
|
||||
);
|
||||
|
||||
if (pilot) {
|
||||
methods.setValue('pilotName', pilot.name);
|
||||
}
|
||||
if (pilot) {
|
||||
methods.setValue('pilotName', pilot.name);
|
||||
}
|
||||
|
||||
methods.setValue('pilotId', event.target.value);
|
||||
}}
|
||||
options={
|
||||
state.pilotOptions && state.pilotOptions.length > 0
|
||||
? state.pilotOptions
|
||||
: []
|
||||
}
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
{mode !== FormMode.ADD && (
|
||||
<TextField
|
||||
disabled={true}
|
||||
fullWidth
|
||||
value={state.selectedEntryPilotName}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
methods.setValue('pilotId', event.target.value);
|
||||
}}
|
||||
options={
|
||||
state.pilotOptions && state.pilotOptions.length > 0
|
||||
? state.pilotOptions
|
||||
: []
|
||||
}
|
||||
value={value ? value : ''}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -32,6 +32,9 @@ const Logbook: React.FC<unknown> = () => {
|
||||
dispatch({ type: 'SET_IS_LOADING', payload: true });
|
||||
|
||||
const response: AxiosResponse = await httpClient.get(`api/logs`);
|
||||
const entries: ILogbookEntry[] = response.data;
|
||||
|
||||
entries.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
|
||||
|
||||
if (response.data.length > 0) {
|
||||
dispatch({ type: 'SET_ENTRIES', payload: response.data });
|
||||
@@ -167,9 +170,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info: any) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
accessorKey: 'singleEngineLand',
|
||||
@@ -179,9 +180,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info: any) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
id: 'landings',
|
||||
@@ -223,9 +222,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
accessorKey: 'instrumentSimulated',
|
||||
@@ -235,9 +232,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
accessorKey: 'instrumentApproaches',
|
||||
@@ -280,9 +275,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
accessorKey: 'flightTrainingReceived',
|
||||
@@ -292,9 +285,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
accessorKey: 'crossCountry',
|
||||
@@ -304,9 +295,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
accessorKey: 'night',
|
||||
@@ -316,9 +305,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
accessorKey: 'solo',
|
||||
@@ -328,9 +315,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
},
|
||||
{
|
||||
accessorKey: 'pilotInCommand',
|
||||
@@ -340,9 +325,7 @@ const Logbook: React.FC<unknown> = () => {
|
||||
headerAlign: 'right'
|
||||
},
|
||||
cell: (info) =>
|
||||
info.getValue() !== null
|
||||
? parseFloat(info.getValue()).toFixed(1)
|
||||
: ''
|
||||
info.getValue() ? parseFloat(info.getValue()).toFixed(1) : ''
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -18,7 +18,7 @@ services:
|
||||
ports:
|
||||
- '3000:3000'
|
||||
env_file:
|
||||
- ./api/.env
|
||||
- ./api/.env.compose
|
||||
|
||||
app:
|
||||
container_name: flying-app
|
||||
@@ -27,7 +27,5 @@ services:
|
||||
target: app
|
||||
ports:
|
||||
- '8080:8080'
|
||||
# env_file:
|
||||
# - ./app/.env
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
module "storage" {
|
||||
source = "github.com/noahspannbauer/noahspan-terraform/modules/storage"
|
||||
resource_group_name = var.RESOURCE_GROUP_NAME
|
||||
storage_account_name = module.environment.storage_account_name
|
||||
storage_tables = module.environment.storage_tables
|
||||
}
|
||||
|
||||
module "container_app" {
|
||||
source = "github.com/noahspannbauer/noahspan-terraform/modules/container_app"
|
||||
app_subdomain_name = var.APP_SUBDOMAIN_NAME
|
||||
@@ -17,7 +24,6 @@ module "container_app" {
|
||||
domain_name = var.DOMAIN_NAME
|
||||
log_analytics_workspace_name = module.environment.log_analytics_workspace_name
|
||||
resource_group_name = var.RESOURCE_GROUP_NAME
|
||||
storage_account_name = module.environment.storage_account_name
|
||||
storage_tables = module.environment.storage_tables
|
||||
storage_account_primary_connection_string = module.storage.storage_account_primary_connection_string
|
||||
tenant_id = var.TENANT_ID
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@noahspan/flying",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"scripts": {
|
||||
"start": "concurrently 'npm run start:azure -w api' 'wait-on tcp:0.0.0.0:7071 && npm run dev -w app'",
|
||||
"format": "prettier --write \"**/src/**/*.ts\" \"**/test/**/*.ts\"",
|
||||
|
||||
Reference in New Issue
Block a user