client API communication

This commit is contained in:
Ruidy Nemausat 2020-02-07 17:49:11 +01:00
parent d8a792efb0
commit c14f47efc3
17 changed files with 103 additions and 40 deletions

BIN
.DS_Store vendored

Binary file not shown.

2
.gitignore vendored
View file

@ -3,5 +3,5 @@ obj/
.vs/
.vscode/
Migrations/
app.db
app.db*
.DS_Store

BIN
Controllers/.DS_Store vendored

Binary file not shown.

View file

@ -40,6 +40,18 @@ namespace TicketManager.Controllers
return project;
}
// GET: api/Projects/5/Members
[HttpGet("{id}/members")]
public async Task<ActionResult<IEnumerable<User>>> GetProjectMembers(int id)
{
var project = await _context.Projects.FindAsync(id);
if (project == null)
{ return NotFound(); }
return project.GetMembers();
}
// PUT: api/Projects/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.

View file

@ -16,10 +16,12 @@ namespace TicketManager.Data
public DbSet<Note> Notes { get; set; }
public DbSet<File> Files { get; set; }
// protected override void OnModelCreating(ModelBuilder builder)
// {
// base.OnModelCreating(builder);
// builder.Entity<Team>().HasKey(t => new { t.ProjectId, t.UserId });
// }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Assignment>().HasKey(a => new { a.ProjectId, a.UserId });
builder.Entity<Assignment>().HasOne(a => a.Project).WithMany(p => p.Assignments).HasForeignKey(a => a.ProjectId);
builder.Entity<Assignment>().HasOne(a => a.User).WithMany(u => u.Assignments).HasForeignKey(a => a.UserId);
}
}
}

View file

@ -15,7 +15,7 @@ namespace TicketManager.Models
{
get
{
return (float)this.Tickets.
return this.Tickets.Count() == 0 ? 0 : (float)this.Tickets.
Where(t => t.Status == Status.Done).Count()
/ this.Tickets.Count()
* 100;

View file

@ -10,6 +10,8 @@ namespace TicketManager.Models
public string LastName { get; set; }
public string FullName => $"{FirstName} {LastName}";
public string Presentation { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public DateTime Created_at { get; } = DateTime.Now;
public byte[] Picture { get; set; }
// public Role Role { get; set; }

View file

@ -1,14 +1,11 @@
import React, { FC } from "react";
type ProgressBarProps = {
value?: number;
value: number;
max?: number;
};
export const ProgressBar: FC<ProgressBarProps> = ({
value = 60,
max = 100
}) => {
export const ProgressBar: FC<ProgressBarProps> = ({ value, max = 100 }) => {
return (
<div className="row">
<progress value={value} max={max}></progress>

View file

@ -2,16 +2,10 @@ import React, { FC } from "react";
import { Ticket } from "../types/Ticket";
type TicketListProps = {
tickets?: Ticket[];
tickets: Ticket[];
};
export const TicketList: FC<TicketListProps> = ({
tickets = [
{ Id: 1, Title: "Todo today" },
{ Id: 2, Title: "Todo tomorrow" },
{ Id: 5, Title: "Todo NOW!!!" }
]
}) => {
export const TicketList: FC<TicketListProps> = ({ tickets }) => {
return (
<div className="row">
{tickets.map((t: Ticket) => (

View file

@ -1,6 +1,28 @@
import React, { FC } from "react";
import React, { FC, useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { ProjectPage } from "../pages/ProjectPage";
import ProjectVM from "../viewModels/ProjectVM";
import { Constants } from "../utils/Constants";
import { Project } from "../types/Project";
export const ProjectController: FC = () => {
return <ProjectPage />;
const [project, setProject] = useState({});
const [isLoading, setIsLoading] = useState(true);
const { id } = useParams();
const getProject: Function = (id: number) => {
fetch(`${Constants.getProjectURI}/${id}`)
.then(res => res.json())
.catch(err => console.log(err))
.then(data => setProject(data))
.finally(() => setIsLoading(false));
};
useEffect(() => {
getProject(id);
}, []);
const viewModel = new ProjectVM(project as Project);
return isLoading ? <p>Loading ...</p> : <ProjectPage viewModel={viewModel} />;
};

View file

@ -3,21 +3,27 @@ import { Header } from "../components/Header";
import { AvatarList } from "../components/AvatarList";
import { ProgressBar } from "../components/ProgressBar";
import { TicketList } from "../components/TicketList";
import ProjectVM from "../viewModels/ProjectVM";
export const ProjectPage: FC = () => {
interface IProps {
viewModel: ProjectVM;
}
export const ProjectPage: FC<IProps> = ({ viewModel }) => {
const {
title,
description,
// avatars,
value,
tickets
} = viewModel;
return (
<div className="section">
<div className="container">
<Header title = "Brand Concept and Design" description = "Research, ideate and present brand concepts for client consideration"/>
<AvatarList
avatars={[
"data:image/jpeg;base64,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",
"data:image/jpeg;base64,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"
]}
/>
<ProgressBar />
<Header title={title} description={description} />
{/* <AvatarList avatars={avatars} /> */}
<ProgressBar value={value} />
{/* <TabView> */}
<TicketList />
<TicketList tickets={tickets} />
{/* <ChildFile />
<ChildActivity /> */}
{/* </TabView> */}

View file

@ -6,9 +6,12 @@ import { ProgressBar } from "../components/ProgressBar";
export const TicketPage: FC = () => {
return (
<>
<Header description = "Research, ideate and present brand concepts for client consideration" title = "Brand Concept and Design"/>
<Header
description="Research, ideate and present brand concepts for client consideration"
title="Brand Concept and Design"
/>
<AvatarList avatars={["../images/user_1.jpg", "../images/user_2.jpg"]} />
<ProgressBar />
<ProgressBar value={60} />
{/* // <TabView>
// <ChildTicket/>
// <ChildFile/>

View file

@ -3,7 +3,7 @@ import { Header } from "../components/Header";
export const UserPage: FC = () => {
return (
<Header />
<Header title = "Brand Concept and Design" description = "Research, ideate and present brand concepts for client consideration"/>
// <TabView>
// <CardList>
// <CardList>

View file

@ -1,3 +1,12 @@
import { Ticket } from "./Ticket";
import { User } from "./User";
export interface Project {
Id: number;
id: number;
title: string;
description: string;
progression: number;
tickets: Ticket[];
getUsers(): User[];
}

View file

@ -1,3 +1,4 @@
export interface User {
Id: number;
Picture: string;
}

View file

@ -1,3 +1,3 @@
export class Constants {
static weatherIconUrl?: string;
static getProjectURI: string = "/api/projects";
}

View file

@ -1,5 +1,20 @@
export class ProjectVM {
public Id?: number;
import { Ticket } from "../types/Ticket";
import { Project } from "../types/Project";
public constructor() {}
export default class ProjectVM {
public id: number;
public title: string;
public description: string;
// public avatars: string[];
public value: number;
public tickets: Ticket[];
public constructor(project: Project) {
this.id = project.id;
this.title = project.title;
this.description = project.description;
// this.avatars = project.getUsers().map(u => u.Picture);
this.value = project.progression;
this.tickets = project.tickets;
}
}