initial
|
@ -0,0 +1,261 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace RPS.Core.Models.Dto
|
||||
{
|
||||
public class PtDashboardFilter
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
public DateTime DateStart { get; set; }
|
||||
public DateTime DateEnd { get; set; }
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RPS.Core.Models.Dto
|
||||
{
|
||||
|
||||
public class ItemsForMonth
|
||||
{
|
||||
public List<PtItem> Closed { get; set; }
|
||||
public List<PtItem> Open { get; set; }
|
||||
|
||||
public ItemsForMonth()
|
||||
{
|
||||
Closed = new List<PtItem>();
|
||||
Open = new List<PtItem>();
|
||||
}
|
||||
}
|
||||
|
||||
public class PtDashboardFilteredIssues
|
||||
{
|
||||
public List<DateTime> Categories { get; set; }
|
||||
public List<ItemsForMonth> MonthItems { get; set; }
|
||||
|
||||
public PtDashboardFilteredIssues()
|
||||
{
|
||||
Categories = new List<DateTime>();
|
||||
MonthItems = new List<ItemsForMonth>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace RPS.Core.Models.Dto
|
||||
{
|
||||
public class PtDashboardStatusCounts
|
||||
{
|
||||
public int ClosedItemsCount { get; set; }
|
||||
public int OpenItemsCount { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace RPS.Core.Models.Dto
|
||||
{
|
||||
public class PtNewComment
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public int ItemId { get; set; }
|
||||
public int UserId { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using RPS.Core.Models.Enums;
|
||||
|
||||
namespace RPS.Core.Models.Dto
|
||||
{
|
||||
public class PtNewItem
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public ItemTypeEnum TypeStr { get; set; }
|
||||
public int UserId { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace RPS.Core.Models.Dto
|
||||
{
|
||||
public class PtNewTask
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public int ItemId { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using RPS.Core.Models.Enums;
|
||||
|
||||
namespace RPS.Core.Models.Dto
|
||||
{
|
||||
public class PtUpdateItem
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int Estimate { get; set; }
|
||||
public PriorityEnum Priority { get; set; }
|
||||
public StatusEnum Status { get; set; }
|
||||
public ItemTypeEnum Type { get; set; }
|
||||
public int AssigneeId { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace RPS.Core.Models.Dto
|
||||
{
|
||||
public class PtUpdateTask
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public bool Completed { get; set; }
|
||||
public int ItemId { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace RPS.Core.Models.Enums
|
||||
{
|
||||
public enum ItemTypeEnum
|
||||
{
|
||||
PBI,
|
||||
Bug,
|
||||
Chore,
|
||||
Impediment
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace RPS.Core.Models.Enums
|
||||
{
|
||||
public enum PriorityEnum
|
||||
{
|
||||
Low = 2,
|
||||
Medium = 4,
|
||||
High = 8,
|
||||
Critical = 16
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace RPS.Core.Models.Enums
|
||||
{
|
||||
public enum StatusEnum
|
||||
{
|
||||
Submitted = 2,
|
||||
Open = 4,
|
||||
Closed = 8,
|
||||
ReOpened = 16
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace RPS.Core.Models
|
||||
{
|
||||
public class PtComment : PtObjectBase
|
||||
{
|
||||
public PtUser User { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using RPS.Core.Models.Enums;
|
||||
|
||||
namespace RPS.Core.Models
|
||||
{
|
||||
public class PtItem : PtObjectBase
|
||||
{
|
||||
public string Description { get; set; }
|
||||
public int Estimate { get; set; }
|
||||
public PriorityEnum Priority { get; set; }
|
||||
public StatusEnum Status { get; set; }
|
||||
public ItemTypeEnum Type { get; set; }
|
||||
public PtUser Assignee { get; set; }
|
||||
public List<PtTask> Tasks { get; set; }
|
||||
public List<PtComment> Comments { get; set; }
|
||||
|
||||
public PtItem()
|
||||
{
|
||||
Tasks = new List<PtTask>();
|
||||
Comments = new List<PtComment>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace RPS.Core.Models
|
||||
{
|
||||
public class PtObjectBase
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public DateTime DateCreated { get; set; }
|
||||
public DateTime DateModified { get; set; }
|
||||
public DateTime? DateDeleted { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace RPS.Core.Models
|
||||
{
|
||||
public class PtTask:PtObjectBase
|
||||
{
|
||||
public bool Completed { get; set; }
|
||||
public DateTime DateStart { get; set; }
|
||||
public DateTime DateEnd { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace RPS.Core.Models
|
||||
{
|
||||
public class PtUser : PtObjectBase
|
||||
{
|
||||
public string FullName { get; set; }
|
||||
public string Avatar { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\Dto\" />
|
||||
<Folder Include="Models\Enums\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,149 @@
|
|||
[
|
||||
{
|
||||
"avatar": "images/avatars/me/me.png",
|
||||
"dateCreated": "2018-05-31T14:36:33.560Z",
|
||||
"dateModified": "2018-05-31T14:36:33.560Z",
|
||||
"fullName": "Alex Ziskind",
|
||||
"id": 21
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-1.png",
|
||||
"dateCreated": "2019-01-30T13:55:12.528Z",
|
||||
"dateModified": "2019-01-30T13:55:12.528Z",
|
||||
"fullName": "Barbara Pfeffer",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/males/image-2.png",
|
||||
"dateCreated": "2018-05-26T20:49:07.704Z",
|
||||
"dateModified": "2018-05-26T20:49:07.704Z",
|
||||
"fullName": "Lysanne Baumbach",
|
||||
"id": 2
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-3.png",
|
||||
"dateCreated": "2019-02-23T14:16:47.553Z",
|
||||
"dateModified": "2019-02-23T14:16:47.553Z",
|
||||
"fullName": "Brian Upton",
|
||||
"id": 3
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-4.png",
|
||||
"dateCreated": "2018-07-05T20:24:45.565Z",
|
||||
"dateModified": "2018-07-05T20:24:45.565Z",
|
||||
"fullName": "Carolyn Cronin",
|
||||
"id": 4
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-5.png",
|
||||
"dateCreated": "2018-03-23T19:51:11.902Z",
|
||||
"dateModified": "2018-03-23T19:51:11.902Z",
|
||||
"fullName": "Waylon Jakubowski",
|
||||
"id": 5
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-6.png",
|
||||
"dateCreated": "2018-06-25T07:44:17.800Z",
|
||||
"dateModified": "2018-06-25T07:44:17.800Z",
|
||||
"fullName": "Lera Witting",
|
||||
"id": 6
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-7.png",
|
||||
"dateCreated": "2018-09-18T13:56:03.825Z",
|
||||
"dateModified": "2018-09-18T13:56:03.825Z",
|
||||
"fullName": "Valentin Ledner",
|
||||
"id": 7
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-8.png",
|
||||
"dateCreated": "2019-03-01T03:56:59.841Z",
|
||||
"dateModified": "2019-03-01T03:56:59.841Z",
|
||||
"fullName": "Israel Gleichner",
|
||||
"id": 8
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/males/image-9.png",
|
||||
"dateCreated": "2018-12-26T00:09:37.109Z",
|
||||
"dateModified": "2018-12-26T00:09:37.109Z",
|
||||
"fullName": "Freeda Watsica",
|
||||
"id": 9
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/males/image-10.png",
|
||||
"dateCreated": "2018-06-14T03:29:47.253Z",
|
||||
"dateModified": "2018-06-14T03:29:47.253Z",
|
||||
"fullName": "Branson Prosacco",
|
||||
"id": 10
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/males/image-11.png",
|
||||
"dateCreated": "2019-01-18T09:06:15.372Z",
|
||||
"dateModified": "2019-01-18T09:06:15.372Z",
|
||||
"fullName": "Emmie Herzog",
|
||||
"id": 11
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-12.png",
|
||||
"dateCreated": "2019-01-22T22:12:15.668Z",
|
||||
"dateModified": "2019-01-22T22:12:15.668Z",
|
||||
"fullName": "Stephania Rogahn",
|
||||
"id": 12
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-13.png",
|
||||
"dateCreated": "2018-08-12T10:09:06.552Z",
|
||||
"dateModified": "2018-08-12T10:09:06.552Z",
|
||||
"fullName": "Pat Langosh",
|
||||
"id": 13
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-14.png",
|
||||
"dateCreated": "2019-01-19T09:34:38.291Z",
|
||||
"dateModified": "2019-01-19T09:34:38.291Z",
|
||||
"fullName": "Reynold Ziemann",
|
||||
"id": 14
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-15.png",
|
||||
"dateCreated": "2018-11-14T20:05:10.339Z",
|
||||
"dateModified": "2018-11-14T20:05:10.339Z",
|
||||
"fullName": "Arlo Mitchell",
|
||||
"id": 15
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/males/image-16.png",
|
||||
"dateCreated": "2018-03-25T05:26:54.466Z",
|
||||
"dateModified": "2018-03-25T05:26:54.466Z",
|
||||
"fullName": "Velva Renner",
|
||||
"id": 16
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/males/image-17.png",
|
||||
"dateCreated": "2018-08-13T16:43:18.673Z",
|
||||
"dateModified": "2018-08-13T16:43:18.673Z",
|
||||
"fullName": "Noelia Frami",
|
||||
"id": 17
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-18.png",
|
||||
"dateCreated": "2018-05-05T01:58:36.413Z",
|
||||
"dateModified": "2018-05-05T01:58:36.413Z",
|
||||
"fullName": "Amir Vandervort",
|
||||
"id": 18
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/females/image-19.png",
|
||||
"dateCreated": "2019-02-21T04:20:11.074Z",
|
||||
"dateModified": "2019-02-21T04:20:11.074Z",
|
||||
"fullName": "Phoebe Durgan",
|
||||
"id": 19
|
||||
},
|
||||
{
|
||||
"avatar": "images/avatars/males/image-20.png",
|
||||
"dateCreated": "2018-09-30T21:35:39.078Z",
|
||||
"dateModified": "2018-09-30T21:35:39.078Z",
|
||||
"fullName": "Orpha Dooley",
|
||||
"id": 20
|
||||
}
|
||||
]
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RPS.Data.Helpers
|
||||
{
|
||||
public class AndSpecification<T> : Specification<T>
|
||||
{
|
||||
private readonly Specification<T> _left;
|
||||
private readonly Specification<T> _right;
|
||||
|
||||
public AndSpecification(Specification<T> left, Specification<T> right)
|
||||
{
|
||||
_right = right;
|
||||
_left = left;
|
||||
}
|
||||
|
||||
public override Expression<Func<T, bool>> ToExpression()
|
||||
{
|
||||
Expression<Func<T, bool>> leftExpression = _left.ToExpression();
|
||||
Expression<Func<T, bool>> rightExpression = _right.ToExpression();
|
||||
|
||||
BinaryExpression andExpression = Expression.AndAlso(
|
||||
leftExpression.Body, rightExpression.Body);
|
||||
|
||||
return Expression.Lambda<Func<T, bool>>(
|
||||
andExpression, leftExpression.Parameters.Single());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using RPS.Core.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RPS.Data.Helpers
|
||||
{
|
||||
public class PtItemDateRangeSpecification : Specification<PtItem>
|
||||
{
|
||||
private readonly DateTime _start;
|
||||
private readonly DateTime _end;
|
||||
|
||||
public PtItemDateRangeSpecification(DateTime start, DateTime end)
|
||||
{
|
||||
_start = start;
|
||||
_end = end;
|
||||
}
|
||||
|
||||
public override Expression<Func<PtItem, bool>> ToExpression()
|
||||
{
|
||||
return item => item.DateCreated >= _start && item.DateCreated <= _end;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using RPS.Core.Models;
|
||||
using RPS.Core.Models.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RPS.Data.Helpers
|
||||
{
|
||||
public class PtItemStatusSpecification : Specification<PtItem>
|
||||
{
|
||||
private readonly StatusEnum _status;
|
||||
|
||||
public PtItemStatusSpecification(StatusEnum status)
|
||||
{
|
||||
_status = status;
|
||||
}
|
||||
|
||||
public override Expression<Func<PtItem, bool>> ToExpression()
|
||||
{
|
||||
return item => item.Status == _status;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using RPS.Core.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RPS.Data.Helpers
|
||||
{
|
||||
public class PtItemUserIdSpecification : Specification<PtItem>
|
||||
{
|
||||
private readonly int _userId;
|
||||
|
||||
public PtItemUserIdSpecification(int userId)
|
||||
{
|
||||
_userId = userId;
|
||||
}
|
||||
|
||||
public override Expression<Func<PtItem, bool>> ToExpression()
|
||||
{
|
||||
if (_userId == 0)
|
||||
{
|
||||
return item => true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return item => item.Assignee.Id == _userId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RPS.Data.Helpers
|
||||
{
|
||||
public abstract class Specification<T>
|
||||
{
|
||||
public abstract Expression<Func<T, bool>> ToExpression();
|
||||
|
||||
public bool IsSatisfiedBy(T entity)
|
||||
{
|
||||
Func<T, bool> predicate = ToExpression().Compile();
|
||||
return predicate(entity);
|
||||
}
|
||||
|
||||
public Specification<T> And(Specification<T> specification)
|
||||
{
|
||||
return new AndSpecification<T>(this, specification);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using RPS.Core.Models;
|
||||
using RPS.Core.Models.Dto;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public interface IPtCommentsRepository
|
||||
{
|
||||
IEnumerable<PtComment> GetAllForItem(int itemId);
|
||||
PtComment AddNewComment(PtNewComment newComment);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using RPS.Core.Models.Dto;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public interface IPtDashboardRepository
|
||||
{
|
||||
PtDashboardStatusCounts GetStatusCounts(PtDashboardFilter filter);
|
||||
PtDashboardFilteredIssues GetFilteredIssues(PtDashboardFilter filter);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using RPS.Core.Models;
|
||||
using RPS.Core.Models.Dto;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public interface IPtItemsRepository
|
||||
{
|
||||
IEnumerable<PtItem> GetAll();
|
||||
IEnumerable<PtItem> GetUserItems(int userId);
|
||||
IEnumerable<PtItem> GetOpenItems();
|
||||
IEnumerable<PtItem> GetClosedItems();
|
||||
PtItem GetItemById(int itemId);
|
||||
|
||||
PtItem AddNewItem(PtNewItem newItem);
|
||||
PtItem UpdateItem(PtUpdateItem updateItem);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using RPS.Core.Models;
|
||||
using RPS.Core.Models.Dto;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public interface IPtTasksRepository
|
||||
{
|
||||
IEnumerable<PtTask> GetAllForItem(int itemId);
|
||||
|
||||
PtTask AddNewTask(PtNewTask newTask);
|
||||
PtTask UpdateTask(PtUpdateTask updateTask);
|
||||
bool DeleteTask(int id, int itemId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using RPS.Core.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public interface IPtUserRepository
|
||||
{
|
||||
IEnumerable<PtUser> GetAll();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RPS.Core.Models;
|
||||
using RPS.Core.Models.Dto;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public class PtCommentsRepository : IPtCommentsRepository
|
||||
{
|
||||
private PtInMemoryContext context;
|
||||
|
||||
public PtCommentsRepository(PtInMemoryContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public PtComment AddNewComment(PtNewComment newComment)
|
||||
{
|
||||
var item = context.PtItems.Single(i => i.Id == newComment.ItemId);
|
||||
|
||||
PtComment comment = new PtComment
|
||||
{
|
||||
Id = item.Comments.Max(t => t.Id) + 1,
|
||||
Title = newComment.Title,
|
||||
DateCreated = DateTime.Now,
|
||||
DateModified = DateTime.Now,
|
||||
User = context.PtUsers.Find(u => u.Id == newComment.UserId)
|
||||
};
|
||||
|
||||
item.Comments.Insert(0, comment);
|
||||
return comment;
|
||||
}
|
||||
|
||||
public IEnumerable<PtComment> GetAllForItem(int itemId)
|
||||
{
|
||||
var item = context.PtItems.Single(i => i.Id == itemId);
|
||||
return item.Comments.Where(t => !t.DateDeleted.HasValue);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RPS.Core.Models;
|
||||
using RPS.Core.Models.Dto;
|
||||
using RPS.Core.Models.Enums;
|
||||
using RPS.Data.Helpers;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public class PtDashboardRepository : IPtDashboardRepository
|
||||
{
|
||||
private PtInMemoryContext context;
|
||||
|
||||
public PtDashboardRepository(PtInMemoryContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public PtDashboardFilteredIssues GetFilteredIssues(PtDashboardFilter filter)
|
||||
{
|
||||
var openItemSpec = new PtItemStatusSpecification(StatusEnum.Open);
|
||||
var closedItemSpec = new PtItemStatusSpecification(StatusEnum.Closed);
|
||||
|
||||
var userIdSpec = new PtItemUserIdSpecification(filter.UserId);
|
||||
var dateRangeSpec = new PtItemDateRangeSpecification(filter.DateStart, filter.DateEnd);
|
||||
|
||||
//var items = Find(userIdSpec.And(dateRangeSpec));
|
||||
|
||||
var itemsForUserAndDates = context.PtItems
|
||||
.Where(userIdSpec.ToExpression().Compile())
|
||||
.Where(dateRangeSpec.ToExpression().Compile());
|
||||
|
||||
var minDate = itemsForUserAndDates.Min(i => i.DateCreated);
|
||||
var maxDate = itemsForUserAndDates.Max(i => i.DateCreated);
|
||||
|
||||
var categories = GetDates(minDate, maxDate);
|
||||
|
||||
var itemsByMonth = categories.Select(c => {
|
||||
return itemsForUserAndDates.Where(i => {
|
||||
var dc = i.DateCreated;
|
||||
return dc.Month == c.Month && dc.Year == c.Year;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var categorizedAndDivided = itemsByMonth.Select(c => {
|
||||
var openItemsForMonth = c.Where(openItemSpec.ToExpression().Compile()).ToList();
|
||||
var closedItemsForMonth = c.Where(closedItemSpec.ToExpression().Compile()).ToList();
|
||||
|
||||
return new ItemsForMonth
|
||||
{
|
||||
Open = openItemsForMonth,
|
||||
Closed = closedItemsForMonth
|
||||
};
|
||||
});
|
||||
|
||||
var issues = new PtDashboardFilteredIssues
|
||||
{
|
||||
Categories = categories,
|
||||
MonthItems = categorizedAndDivided.ToList()
|
||||
};
|
||||
|
||||
return issues;
|
||||
}
|
||||
|
||||
public PtDashboardStatusCounts GetStatusCounts(PtDashboardFilter filter)
|
||||
{
|
||||
var openItemSpec = new PtItemStatusSpecification(StatusEnum.Open);
|
||||
var closedItemSpec = new PtItemStatusSpecification(StatusEnum.Closed);
|
||||
var userIdSpec = new PtItemUserIdSpecification(filter.UserId);
|
||||
var dateRangeSpec = new PtItemDateRangeSpecification(filter.DateStart, filter.DateEnd);
|
||||
|
||||
|
||||
var itemsForUserAndDates = context.PtItems
|
||||
.Where(userIdSpec.ToExpression().Compile())
|
||||
.Where(dateRangeSpec.ToExpression().Compile());
|
||||
|
||||
//var openItems = Find(openItemSpec.And(userIdSpec).And(dateRangeSpec)).ToList();
|
||||
//var closedItems = Find(closedItemSpec.And(userIdSpec).And(dateRangeSpec)).ToList();
|
||||
var openItems = itemsForUserAndDates.Where(openItemSpec.ToExpression().Compile()).ToList();
|
||||
|
||||
var closedItems = itemsForUserAndDates.Where(closedItemSpec.ToExpression().Compile()).ToList();
|
||||
|
||||
return new PtDashboardStatusCounts
|
||||
{
|
||||
OpenItemsCount = openItems.Count,
|
||||
ClosedItemsCount = closedItems.Count
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private IReadOnlyList<PtItem> Find(Specification<PtItem> specification)
|
||||
{
|
||||
return context.PtItems.Where(specification.ToExpression().Compile()).ToList();
|
||||
}
|
||||
|
||||
private List<DateTime> GetDates(DateTime min, DateTime max)
|
||||
{
|
||||
List<DateTime> months = new List<DateTime>();
|
||||
while (min <= max)
|
||||
{
|
||||
months.Add(new DateTime(min.Year, min.Month, 1));
|
||||
min = min.AddMonths(1);
|
||||
}
|
||||
return months;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using Newtonsoft.Json;
|
||||
using RPS.Core.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public class PtInMemoryContext
|
||||
{
|
||||
string resourceNameItems = "RPS.Data.GenData.fs-items.json";
|
||||
string resourceNameUsers = "RPS.Data.GenData.fs-users.json";
|
||||
|
||||
List<PtItem> items;
|
||||
List<PtUser> users;
|
||||
|
||||
public List<PtItem> PtItems { get { return items; } }
|
||||
public List<PtUser> PtUsers { get { return users; } }
|
||||
|
||||
public PtInMemoryContext()
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
string contentsItems = "[]";
|
||||
|
||||
using (Stream stream = assembly.GetManifestResourceStream(resourceNameItems))
|
||||
using (StreamReader file = new StreamReader(stream))
|
||||
{
|
||||
contentsItems = file.ReadToEnd();
|
||||
}
|
||||
|
||||
items = JsonConvert.DeserializeObject<List<PtItem>>(contentsItems);
|
||||
|
||||
string contentsUsers = "[]";
|
||||
|
||||
using (Stream stream = assembly.GetManifestResourceStream(resourceNameUsers))
|
||||
using (StreamReader file = new StreamReader(stream))
|
||||
{
|
||||
contentsUsers = file.ReadToEnd();
|
||||
}
|
||||
|
||||
users = JsonConvert.DeserializeObject<List<PtUser>>(contentsUsers);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
using RPS.Core.Models;
|
||||
using RPS.Core.Models.Enums;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RPS.Core.Models.Dto;
|
||||
using System;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public class PtItemsRepository : IPtItemsRepository
|
||||
{
|
||||
private PtInMemoryContext context;
|
||||
|
||||
public PtItemsRepository(PtInMemoryContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public IEnumerable<PtItem> GetAll()
|
||||
{
|
||||
return context.PtItems;
|
||||
}
|
||||
|
||||
public IEnumerable<PtItem> GetClosedItems()
|
||||
{
|
||||
return context.PtItems.Where(i => i.Status == StatusEnum.Closed &&
|
||||
i.DateDeleted == null);
|
||||
}
|
||||
|
||||
public PtItem GetItemById(int itemId)
|
||||
{
|
||||
var item = context.PtItems.SingleOrDefault(i => i.Id == itemId);
|
||||
|
||||
item.Tasks = item.Tasks.Where(t => !t.DateDeleted.HasValue).ToList();
|
||||
return item;
|
||||
}
|
||||
|
||||
public IEnumerable<PtItem> GetOpenItems()
|
||||
{
|
||||
return context.PtItems.Where(i => (i.Status == StatusEnum.Open ||
|
||||
i.Status == StatusEnum.ReOpened) &&
|
||||
i.DateDeleted == null);
|
||||
}
|
||||
|
||||
public IEnumerable<PtItem> GetUserItems(int userId)
|
||||
{
|
||||
return context.PtItems.Where(i => i.Assignee.Id == userId &&
|
||||
i.DateDeleted == null);
|
||||
}
|
||||
|
||||
public PtItem AddNewItem(PtNewItem newItem)
|
||||
{
|
||||
var item1 = new PtItem
|
||||
{
|
||||
Id = context.PtItems.Max(i=>i.Id) + 1,
|
||||
Title = newItem.Title,
|
||||
Description = newItem.Description,
|
||||
Type = newItem.TypeStr,
|
||||
Assignee = context.PtUsers.Find(u=>u.Id == newItem.UserId),
|
||||
Estimate = 0,
|
||||
Priority = PriorityEnum.Medium,
|
||||
Status = StatusEnum.Open,
|
||||
Tasks = new List<PtTask>(),
|
||||
Comments = new List<PtComment>(),
|
||||
DateCreated = DateTime.Now,
|
||||
DateModified = DateTime.Now
|
||||
};
|
||||
|
||||
context.PtItems.Insert(0, item1);
|
||||
|
||||
return item1;
|
||||
}
|
||||
|
||||
public PtItem UpdateItem(PtUpdateItem updateItem)
|
||||
{
|
||||
var idx = context.PtItems.FindIndex(i => i.Id == updateItem.Id);
|
||||
var oldItem = context.PtItems.Find(i => i.Id == updateItem.Id);
|
||||
|
||||
var uItem = new PtItem
|
||||
{
|
||||
Id = updateItem.Id,
|
||||
Title = updateItem.Title,
|
||||
Description = updateItem.Description,
|
||||
Type = updateItem.Type,
|
||||
Assignee = context.PtUsers.Find(u => u.Id == updateItem.AssigneeId),
|
||||
Estimate = updateItem.Estimate,
|
||||
Priority = updateItem.Priority,
|
||||
Status = updateItem.Status,
|
||||
Tasks = oldItem.Tasks,
|
||||
Comments = oldItem.Comments,
|
||||
DateCreated = oldItem.DateCreated,
|
||||
DateModified = DateTime.Now
|
||||
};
|
||||
|
||||
context.PtItems[idx] = uItem;
|
||||
return uItem;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RPS.Core.Models;
|
||||
using RPS.Core.Models.Dto;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public class PtTasksRepository : IPtTasksRepository
|
||||
{
|
||||
private PtInMemoryContext context;
|
||||
|
||||
public PtTasksRepository(PtInMemoryContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public PtTask AddNewTask(PtNewTask newTask)
|
||||
{
|
||||
var item = context.PtItems.Single(i => i.Id == newTask.ItemId);
|
||||
|
||||
PtTask task = new PtTask
|
||||
{
|
||||
Id = item.Tasks.Max(t=>t.Id) + 1,
|
||||
Title = newTask.Title,
|
||||
Completed = false,
|
||||
DateCreated = DateTime.Now,
|
||||
DateModified = DateTime.Now
|
||||
};
|
||||
|
||||
item.Tasks.Insert(0, task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public bool DeleteTask(int id, int itemId)
|
||||
{
|
||||
var item = context.PtItems.SingleOrDefault(i => i.Id == itemId);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
var task = item.Tasks.Single(t => t.Id == id);
|
||||
task.DateDeleted = DateTime.Now;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<PtTask> GetAllForItem(int itemId)
|
||||
{
|
||||
var item = context.PtItems.Single(i => i.Id == itemId);
|
||||
return item.Tasks.Where(t => !t.DateDeleted.HasValue);
|
||||
}
|
||||
|
||||
public PtTask UpdateTask(PtUpdateTask updateTask)
|
||||
{
|
||||
var item = context.PtItems.Single(i => i.Id == updateTask.ItemId);
|
||||
var oldTask = item.Tasks.Single(t => t.Id == updateTask.Id);
|
||||
var idx = item.Tasks.FindIndex(t => t.Id == updateTask.Id);
|
||||
|
||||
PtTask uTask = new PtTask
|
||||
{
|
||||
Id = oldTask.Id,
|
||||
Title = updateTask.Title,
|
||||
Completed = updateTask.Completed,
|
||||
DateCreated = oldTask.DateCreated,
|
||||
DateModified = DateTime.Now,
|
||||
DateEnd = oldTask.DateEnd,
|
||||
DateStart = oldTask.DateStart
|
||||
};
|
||||
|
||||
item.Tasks[idx] = uTask;
|
||||
|
||||
return uTask;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using RPS.Core.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RPS.Data
|
||||
{
|
||||
public class PtUserRepository : IPtUserRepository
|
||||
{
|
||||
private PtInMemoryContext context;
|
||||
|
||||
public PtUserRepository(PtInMemoryContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public IEnumerable<PtUser> GetAll()
|
||||
{
|
||||
return context.PtUsers;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="GenData\" />
|
||||
<Folder Include="Helpers\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RPS.Core\RPS.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,8 @@
|
|||
@page
|
||||
@model core_test.Pages.BacklogModel
|
||||
@{
|
||||
ViewData["Title"] = "Backlog";
|
||||
}
|
||||
|
||||
<h2>Backlog</h2>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace core_test.Pages
|
||||
{
|
||||
public class BacklogModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@page
|
||||
@model core_test.Pages.DashboardModel
|
||||
@{
|
||||
ViewData["Title"] = "Dashboard";
|
||||
}
|
||||
|
||||
<h2>Dashboard</h2>
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace core_test.Pages
|
||||
{
|
||||
public class DashboardModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
@page
|
||||
@model ErrorModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
|
||||
</p>
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace RPS.Web.Pages
|
||||
{
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public class ErrorModel : PageModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
@using Microsoft.AspNetCore.Http.Features
|
||||
|
||||
@{
|
||||
var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
|
||||
var showBanner = !consentFeature?.CanTrack ?? false;
|
||||
var cookieString = consentFeature?.CreateConsentCookie();
|
||||
}
|
||||
|
||||
@if (showBanner)
|
||||
{
|
||||
<nav id="cookieConsent" class="navbar navbar-default navbar-fixed-top" role="alert">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#cookieConsent .navbar-collapse">
|
||||
<span class="sr-only">Toggle cookie consent banner</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<span class="navbar-brand"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span></span>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse">
|
||||
<p class="navbar-text">
|
||||
Use this space to summarize your privacy and cookie use policy.
|
||||
</p>
|
||||
<div class="navbar-right">
|
||||
<a asp-page="/Privacy" class="btn btn-info navbar-btn">Learn More</a>
|
||||
<button type="button" class="btn btn-default navbar-btn" data-cookie-string="@cookieString">Accept</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<script>
|
||||
(function () {
|
||||
document.querySelector("#cookieConsent button[data-cookie-string]").addEventListener("click", function (el) {
|
||||
document.cookie = el.target.dataset.cookieString;
|
||||
document.querySelector("#cookieConsent").classList.add("hidden");
|
||||
}, false);
|
||||
})();
|
||||
</script>
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - RPS</title>
|
||||
|
||||
<link href="~/lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="~/css/site.css" rel="stylesheet" />
|
||||
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
|
||||
<a class="navbar-brand col-sm-3 col-md-2 mr-0">
|
||||
<img src="~/images/rpslogo.png" class="logo">
|
||||
</a>
|
||||
<nav class="my-2 my-md-0 mr-md-3">
|
||||
<a class="p-2 text-light" href="/Dashboard">Dashboard</a>
|
||||
<a class="p-2 text-light" href="/Backlog">Backlog</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<nav class="col-md-2 d-none d-md-block bg-light sidebar">
|
||||
<div class="sidebar-sticky">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" routerLink="/dashboard">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-home">
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
|
||||
<polyline points="9 22 9 12 15 12 15 22"></polyline>
|
||||
</svg>
|
||||
Dashboard <span class="sr-only">(current)</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="/backlog/my">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-layers">
|
||||
<polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
|
||||
<polyline points="2 17 12 22 22 17"></polyline>
|
||||
<polyline points="2 12 12 17 22 12"></polyline>
|
||||
</svg>
|
||||
My Items
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="/backlog/open">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-file">
|
||||
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path>
|
||||
<polyline points="13 2 13 9 20 9"></polyline>
|
||||
</svg>
|
||||
Open Items
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="/backlog/closed">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-shopping-cart">
|
||||
<circle cx="9" cy="21" r="1"></circle>
|
||||
<circle cx="20" cy="21" r="1"></circle>
|
||||
<path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
|
||||
</svg>
|
||||
Done Items
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-users">
|
||||
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="9" cy="7" r="4"></circle>
|
||||
<path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
|
||||
</svg>
|
||||
Users
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-bar-chart-2">
|
||||
<line x1="18" y1="20" x2="18" y2="10"></line>
|
||||
<line x1="12" y1="20" x2="12" y2="4"></line>
|
||||
<line x1="6" y1="20" x2="6" y2="14"></line>
|
||||
</svg>
|
||||
Reports
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||
<span>Saved reports</span>
|
||||
<a class="d-flex align-items-center text-muted" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-plus-circle">
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<line x1="12" y1="8" x2="12" y2="16"></line>
|
||||
<line x1="8" y1="12" x2="16" y2="12"></line>
|
||||
</svg>
|
||||
</a>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-file-text">
|
||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
|
||||
<polyline points="14 2 14 8 20 8"></polyline>
|
||||
<line x1="16" y1="13" x2="8" y2="13"></line>
|
||||
<line x1="16" y1="17" x2="8" y2="17"></line>
|
||||
<polyline points="10 9 9 9 8 9"></polyline>
|
||||
</svg>
|
||||
Current month
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-file-text">
|
||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
|
||||
<polyline points="14 2 14 8 20 8"></polyline>
|
||||
<line x1="16" y1="13" x2="8" y2="13"></line>
|
||||
<line x1="16" y1="17" x2="8" y2="17"></line>
|
||||
<polyline points="10 9 9 9 8 9"></polyline>
|
||||
</svg>
|
||||
Last quarter
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-file-text">
|
||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
|
||||
<polyline points="14 2 14 8 20 8"></polyline>
|
||||
<line x1="16" y1="13" x2="8" y2="13"></line>
|
||||
<line x1="16" y1="17" x2="8" y2="17"></line>
|
||||
<polyline points="10 9 9 9 8 9"></polyline>
|
||||
</svg>
|
||||
Social engagement
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-file-text">
|
||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
|
||||
<polyline points="14 2 14 8 20 8"></polyline>
|
||||
<line x1="16" y1="13" x2="8" y2="13"></line>
|
||||
<line x1="16" y1="17" x2="8" y2="17"></line>
|
||||
<polyline points="10 9 9 9 8 9"></polyline>
|
||||
</svg>
|
||||
Year-end sale
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
|
||||
|
||||
@RenderBody()
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>© 2019 - RPS</p>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<environment include="Development">
|
||||
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
|
||||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"
|
||||
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.validator"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-rZfj/ogBloos6wzLGpPkkOr/gpkBNLZ6b6yLy4o+ok+t/SAKlL5mvXLr0OXNi1Hp">
|
||||
</script>
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.9/jquery.validate.unobtrusive.min.js"
|
||||
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds">
|
||||
</script>
|
||||
</environment>
|
|
@ -0,0 +1,3 @@
|
|||
@using RPS.Web
|
||||
@namespace RPS.Web.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@ -0,0 +1,3 @@
|
|||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace RPS.Web
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateWebHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:59008",
|
||||
"sslPort": 44374
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"RPS.Web": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.HttpsPolicy;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace RPS.Web
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
|
||||
options.CheckConsentNeeded = context => true;
|
||||
options.MinimumSameSitePolicy = SameSiteMode.None;
|
||||
});
|
||||
|
||||
|
||||
services.AddMvc()
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
|
||||
.AddRazorPagesOptions(options =>
|
||||
{
|
||||
options.Conventions.AddPageRoute("/Dashboard", "");
|
||||
});
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Error");
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
app.UseCookiePolicy();
|
||||
|
||||
app.UseMvc();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
.backlog-icon {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.li-indicator {
|
||||
height: 58px;
|
||||
width: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.li-indicator div {
|
||||
width: 5px;
|
||||
height: 58px;
|
||||
}
|
||||
|
||||
.li-info-wrapper {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.li-title {
|
||||
font-size: 14px;
|
||||
color: #4b5833;
|
||||
}
|
||||
|
||||
.pt-table-row {
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
.comp-label strong {
|
||||
font-size: 4em;
|
||||
line-height: 1;
|
||||
font-weight: 200;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.comp-label small {
|
||||
font-size: .7em;
|
||||
text-transform: uppercase;
|
||||
display: block;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
.backlog-icon {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.chitchat-item {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.chitchat-text {
|
||||
color: #495057;
|
||||
font-size: .9em;
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
|
||||
.logo {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.feather {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sidebar
|
||||
*/
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100; /* Behind the navbar */
|
||||
padding: 67px 0 0; /* Height of navbar */
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
position: relative;
|
||||
top: 0;
|
||||
height: calc(100vh - 67px);
|
||||
padding-top: .5rem;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||
}
|
||||
|
||||
@supports ((position: -webkit-sticky) or (position: sticky)) {
|
||||
.sidebar-sticky {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sidebar .nav-link .feather {
|
||||
margin-right: 4px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover .feather,
|
||||
.sidebar .nav-link.active .feather {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: .75rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/*
|
||||
* Content
|
||||
*/
|
||||
|
||||
[role="main"] {
|
||||
padding-top: 133px; /* Space for fixed navbar */
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
[role="main"] {
|
||||
padding-top: 67px; /* Space for fixed navbar */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Navbar
|
||||
*/
|
||||
|
||||
.navbar-brand {
|
||||
padding-top: .75rem;
|
||||
padding-bottom: .75rem;
|
||||
font-size: 1rem;
|
||||
background-color: rgba(0, 0, 0, .25);
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
|
||||
.navbar .form-control {
|
||||
padding: .75rem 1rem;
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.form-control-dark {
|
||||
color: #fff;
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
border-color: rgba(255, 255, 255, .1);
|
||||
}
|
||||
|
||||
.form-control-dark:focus {
|
||||
border-color: transparent;
|
||||
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
|
||||
}
|
||||
|
||||
|
||||
.li-avatar {
|
||||
background-color: #eeeeee;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.li-estimate {
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
color: #555a97;
|
||||
}
|
||||
|
||||
.li-date {
|
||||
font-size: 12px;
|
||||
color: #555a97;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.indicator-pbi {
|
||||
background-color: #527FD7;
|
||||
}
|
||||
|
||||
.indicator-bug {
|
||||
background-color: #D75252;
|
||||
}
|
||||
|
||||
.indicator-chore {
|
||||
background-color: #666666;
|
||||
}
|
||||
|
||||
.indicator-impediment {
|
||||
background-color: #D7C152;
|
||||
}
|
||||
|
||||
.priority-critical {
|
||||
color: #fff;
|
||||
background-color: #820101;
|
||||
}
|
||||
|
||||
.priority-high {
|
||||
color: #fff;
|
||||
background-color: #b27100;
|
||||
}
|
||||
|
||||
.priority-medium {
|
||||
color: #fff;
|
||||
background-color: #0c6d00;
|
||||
}
|
||||
|
||||
.priority-low {
|
||||
color: #fff;
|
||||
background-color: #002b6d;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
max-height: 400px;
|
||||
overflow: scroll;
|
||||
}
|
После Ширина: | Высота: | Размер: 31 KiB |
После Ширина: | Высота: | Размер: 75 KiB |
После Ширина: | Высота: | Размер: 58 KiB |
После Ширина: | Высота: | Размер: 70 KiB |
После Ширина: | Высота: | Размер: 63 KiB |
После Ширина: | Высота: | Размер: 66 KiB |
После Ширина: | Высота: | Размер: 73 KiB |
После Ширина: | Высота: | Размер: 73 KiB |
После Ширина: | Высота: | Размер: 61 KiB |
После Ширина: | Высота: | Размер: 76 KiB |
После Ширина: | Высота: | Размер: 62 KiB |
После Ширина: | Высота: | Размер: 64 KiB |
После Ширина: | Высота: | Размер: 66 KiB |
После Ширина: | Высота: | Размер: 67 KiB |
После Ширина: | Высота: | Размер: 72 KiB |
После Ширина: | Высота: | Размер: 62 KiB |
После Ширина: | Высота: | Размер: 82 KiB |
После Ширина: | Высота: | Размер: 63 KiB |
После Ширина: | Высота: | Размер: 61 KiB |
После Ширина: | Высота: | Размер: 79 KiB |
После Ширина: | Высота: | Размер: 69 KiB |
После Ширина: | Высота: | Размер: 69 KiB |
После Ширина: | Высота: | Размер: 60 KiB |
После Ширина: | Высота: | Размер: 56 KiB |
После Ширина: | Высота: | Размер: 78 KiB |
После Ширина: | Высота: | Размер: 78 KiB |
После Ширина: | Высота: | Размер: 72 KiB |
После Ширина: | Высота: | Размер: 79 KiB |
После Ширина: | Высота: | Размер: 55 KiB |
После Ширина: | Высота: | Размер: 85 KiB |
После Ширина: | Высота: | Размер: 61 KiB |
После Ширина: | Высота: | Размер: 70 KiB |
После Ширина: | Высота: | Размер: 68 KiB |
После Ширина: | Высота: | Размер: 77 KiB |
После Ширина: | Высота: | Размер: 76 KiB |
После Ширина: | Высота: | Размер: 74 KiB |
После Ширина: | Высота: | Размер: 66 KiB |
После Ширина: | Высота: | Размер: 78 KiB |
После Ширина: | Высота: | Размер: 79 KiB |