├── Ollert ├── Icon.png ├── favicon.ico ├── Views │ ├── _ViewStart.cshtml │ ├── Account │ │ ├── ExternalLoginFailure.cshtml │ │ ├── Manage.cshtml │ │ ├── Login.cshtml │ │ ├── _SetPasswordPartial.cshtml │ │ ├── _ExternalLoginsListPartial.cshtml │ │ ├── _RemoveAccountPartial.cshtml │ │ ├── ExternalLoginConfirmation.cshtml │ │ ├── _ChangePasswordPartial.cshtml │ │ └── Register.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _LoginPartial.cshtml │ │ └── _LayoutPublic.cshtml │ ├── Board │ │ ├── List │ │ │ └── _AddModal.cshtml │ │ ├── Salle │ │ │ ├── _AddTableModal.cshtml │ │ │ ├── _EditCardModal.cshtml │ │ │ ├── _MessagesList.cshtml │ │ │ ├── _AddCardModal.cshtml │ │ │ └── _Steps.cshtml │ │ └── Salle.cshtml │ ├── Web.config │ └── Member │ │ └── Profil.cshtml ├── Scripts │ ├── typings │ │ ├── navigator │ │ │ └── navigator.d.ts │ │ ├── array │ │ │ └── array.d.ts │ │ ├── knockout │ │ │ └── Knockout.extension.d.ts │ │ ├── webkit │ │ │ └── webkit.d.ts │ │ ├── gritter │ │ │ └── gritter.d.ts │ │ ├── signalr │ │ │ ├── signalr.ollert.d.ts │ │ │ └── signalr.d.ts │ │ ├── knockout.mapping │ │ │ └── knockout.mapping.d.ts │ │ ├── dropzone │ │ │ └── dropzone.d.ts │ │ └── bootstrap │ │ │ └── bootstrap.d.ts │ ├── _references.js │ ├── pages │ │ ├── Classes │ │ │ ├── Attachment.js │ │ │ ├── Attachment.ts │ │ │ ├── Attachment.js.map │ │ │ ├── User.js │ │ │ ├── User.js.map │ │ │ ├── User.ts │ │ │ ├── Message.js │ │ │ ├── Notification.js │ │ │ ├── Message.js.map │ │ │ ├── Notification.js.map │ │ │ ├── Message.ts │ │ │ ├── Notification.ts │ │ │ ├── BoardsList.js │ │ │ ├── BoardsList.js.map │ │ │ ├── Step.js │ │ │ ├── BoardsList.ts │ │ │ ├── Step.ts │ │ │ ├── Step.js.map │ │ │ ├── List.js │ │ │ ├── List.js.map │ │ │ ├── List.ts │ │ │ ├── BoardDetails.js │ │ │ ├── BoardDetails.js.map │ │ │ └── BoardDetails.ts │ │ └── extensions.js │ ├── npm.js │ └── jquery.cookie.js ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── Content │ ├── img │ │ ├── gritter.png │ │ ├── ie-spacer.gif │ │ ├── gritter-light.png │ │ └── gritter-long.png │ ├── images │ │ ├── date_add.png │ │ ├── favicon.png │ │ ├── note_add.png │ │ ├── oldpaper.jpg │ │ ├── tag_add.png │ │ ├── tag_info.png │ │ ├── tag_move.png │ │ ├── date_info.png │ │ ├── date_trash.png │ │ ├── note_trash.png │ │ ├── notifyIcon.png │ │ ├── spritemap.png │ │ ├── tag_trash.png │ │ ├── avatar │ │ │ ├── david.png │ │ │ ├── avatar1.png │ │ │ ├── avatar2.png │ │ │ ├── yannick.png │ │ │ └── avatarblue.png │ │ ├── comment_add.png │ │ ├── comment_trash.png │ │ ├── spritemap@2x.png │ │ ├── text_enriched.png │ │ ├── connection_error.png │ │ ├── apple-touch-icon-precomposed.png │ │ ├── apple-touch-icon-72x72-precomposed.png │ │ ├── apple-touch-icon-114x114-precomposed.png │ │ ├── apple-touch-icon-120x120-precomposed.png │ │ ├── apple-touch-icon-144x144-precomposed.png │ │ └── apple-touch-icon-152x152-precomposed.png │ ├── themes │ │ └── base │ │ │ ├── images │ │ │ ├── ui-icons_222222_256x240.png │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ ├── ui-icons_454545_256x240.png │ │ │ ├── ui-icons_888888_256x240.png │ │ │ ├── ui-icons_cd0a0a_256x240.png │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ │ ├── sortable.css │ │ │ ├── draggable.css │ │ │ ├── all.css │ │ │ ├── autocomplete.css │ │ │ ├── selectable.css │ │ │ ├── tooltip.css │ │ │ ├── base.css │ │ │ ├── accordion.css │ │ │ ├── selectmenu.css │ │ │ ├── menu.css │ │ │ ├── tabs.css │ │ │ ├── spinner.css │ │ │ ├── resizable.css │ │ │ ├── dialog.css │ │ │ ├── slider.css │ │ │ ├── core.css │ │ │ ├── progressbar.css │ │ │ └── button.css │ ├── signin.css │ └── jquery.gritter.css ├── Global.asax ├── Tools │ └── TypeScript │ │ ├── 1.4 │ │ ├── tsc.exe │ │ └── tschost.dll │ │ ├── TypeScript.Tasks.dll │ │ ├── en │ │ ├── TypeScript.Tasks.resources.dll │ │ ├── ProjectItemsSchema.xaml │ │ └── TypeScriptCompile.xaml │ │ ├── Microsoft.TypeScript.Default.props │ │ └── Microsoft.TypeScript.jsproj.targets ├── Models │ ├── IEntity.cs │ ├── MailEventViewModel.cs │ ├── DeplacementModelView.cs │ ├── CarteVue.cs │ ├── ParticipantSalle.cs │ ├── CarteEtape.cs │ ├── Tableau.cs │ ├── Notification.cs │ ├── Fichier.cs │ ├── Message.cs │ ├── OllertUser.cs │ ├── AccountViewModels.cs │ ├── Salle.cs │ └── Carte.cs ├── App_Start │ ├── FilterConfig.cs │ ├── Startup.SignalR.cs │ ├── RouteConfig.cs │ ├── WebApiConfig.cs │ ├── Startup.Auth.cs │ └── BundleConfig.cs ├── Startup.cs ├── Controllers │ └── MemberController.cs ├── Extensions │ ├── IEnumerableExtensions.cs │ ├── StringExtension.cs │ └── ObjectQueryExtensions.cs ├── Mailers │ └── NotificationMailer.cs ├── Global.asax.cs ├── Api │ ├── UserController.cs │ └── NotificationController.cs ├── Taches.txt ├── Web.Debug.config ├── Web.Release.config ├── Properties │ ├── AssemblyInfo.cs │ └── PublishProfiles │ │ └── ServerspamWebDeploy.pubxml ├── DAL │ ├── RepositoryFactory.cs │ ├── OllertDbContext.cs │ └── GenericRepository.cs └── Hubs │ └── OllertHub.cs ├── docs ├── Capture.PNG ├── Capture2.PNG ├── Capture3.PNG └── TypeScript Language Specification.pdf ├── scaffolding.config ├── Ollert.Tests ├── packages.config ├── Controllers │ └── HomeControllerTest.cs ├── Properties │ └── AssemblyInfo.cs └── App.config ├── README.md ├── Ollert.sln └── .gitignore /Ollert/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Icon.png -------------------------------------------------------------------------------- /docs/Capture.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/docs/Capture.PNG -------------------------------------------------------------------------------- /Ollert/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/favicon.ico -------------------------------------------------------------------------------- /docs/Capture2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/docs/Capture2.PNG -------------------------------------------------------------------------------- /docs/Capture3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/docs/Capture3.PNG -------------------------------------------------------------------------------- /Ollert/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /Ollert/Scripts/typings/navigator/navigator.d.ts: -------------------------------------------------------------------------------- 1 | interface Navigator { 2 | standalone: boolean 3 | } -------------------------------------------------------------------------------- /Ollert/Scripts/_references.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Scripts/_references.js -------------------------------------------------------------------------------- /Ollert/Scripts/typings/array/array.d.ts: -------------------------------------------------------------------------------- 1 | interface Array { 2 | sortBy: (objet: any) => Array 3 | } -------------------------------------------------------------------------------- /Ollert/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /Ollert/Content/img/gritter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/img/gritter.png -------------------------------------------------------------------------------- /Ollert/Content/images/date_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/date_add.png -------------------------------------------------------------------------------- /Ollert/Content/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/favicon.png -------------------------------------------------------------------------------- /Ollert/Content/images/note_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/note_add.png -------------------------------------------------------------------------------- /Ollert/Content/images/oldpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/oldpaper.jpg -------------------------------------------------------------------------------- /Ollert/Content/images/tag_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/tag_add.png -------------------------------------------------------------------------------- /Ollert/Content/images/tag_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/tag_info.png -------------------------------------------------------------------------------- /Ollert/Content/images/tag_move.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/tag_move.png -------------------------------------------------------------------------------- /Ollert/Content/img/ie-spacer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/img/ie-spacer.gif -------------------------------------------------------------------------------- /Ollert/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="Ollert.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /Ollert/Content/images/date_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/date_info.png -------------------------------------------------------------------------------- /Ollert/Content/images/date_trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/date_trash.png -------------------------------------------------------------------------------- /Ollert/Content/images/note_trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/note_trash.png -------------------------------------------------------------------------------- /Ollert/Content/images/notifyIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/notifyIcon.png -------------------------------------------------------------------------------- /Ollert/Content/images/spritemap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/spritemap.png -------------------------------------------------------------------------------- /Ollert/Content/images/tag_trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/tag_trash.png -------------------------------------------------------------------------------- /Ollert/Content/img/gritter-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/img/gritter-light.png -------------------------------------------------------------------------------- /Ollert/Content/img/gritter-long.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/img/gritter-long.png -------------------------------------------------------------------------------- /Ollert/Tools/TypeScript/1.4/tsc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Tools/TypeScript/1.4/tsc.exe -------------------------------------------------------------------------------- /Ollert/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /Ollert/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /Ollert/Content/images/avatar/david.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/avatar/david.png -------------------------------------------------------------------------------- /Ollert/Content/images/comment_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/comment_add.png -------------------------------------------------------------------------------- /Ollert/Content/images/comment_trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/comment_trash.png -------------------------------------------------------------------------------- /Ollert/Content/images/spritemap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/spritemap@2x.png -------------------------------------------------------------------------------- /Ollert/Content/images/text_enriched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/text_enriched.png -------------------------------------------------------------------------------- /Ollert/Tools/TypeScript/1.4/tschost.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Tools/TypeScript/1.4/tschost.dll -------------------------------------------------------------------------------- /Ollert/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /Ollert/Content/images/avatar/avatar1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/avatar/avatar1.png -------------------------------------------------------------------------------- /Ollert/Content/images/avatar/avatar2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/avatar/avatar2.png -------------------------------------------------------------------------------- /Ollert/Content/images/avatar/yannick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/avatar/yannick.png -------------------------------------------------------------------------------- /Ollert/Content/images/avatar/avatarblue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/avatar/avatarblue.png -------------------------------------------------------------------------------- /Ollert/Content/images/connection_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/connection_error.png -------------------------------------------------------------------------------- /Ollert/Tools/TypeScript/TypeScript.Tasks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Tools/TypeScript/TypeScript.Tasks.dll -------------------------------------------------------------------------------- /docs/TypeScript Language Specification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/docs/TypeScript Language Specification.pdf -------------------------------------------------------------------------------- /Ollert/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Ollert/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Ollert/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Ollert/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Ollert/Content/images/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /Ollert/Scripts/typings/knockout/Knockout.extension.d.ts: -------------------------------------------------------------------------------- 1 | // For knockout sortable 2 | interface KnockoutObservableArrayFunctions { 3 | id: number; 4 | } -------------------------------------------------------------------------------- /Ollert/Models/IEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Ollert.Models 3 | { 4 | public interface IEntity 5 | { 6 | int Id { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Ollert/Tools/TypeScript/en/TypeScript.Tasks.resources.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Tools/TypeScript/en/TypeScript.Tasks.resources.dll -------------------------------------------------------------------------------- /Ollert/Content/images/apple-touch-icon-72x72-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/apple-touch-icon-72x72-precomposed.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /Ollert/Content/images/apple-touch-icon-114x114-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/apple-touch-icon-114x114-precomposed.png -------------------------------------------------------------------------------- /Ollert/Content/images/apple-touch-icon-120x120-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/apple-touch-icon-120x120-precomposed.png -------------------------------------------------------------------------------- /Ollert/Content/images/apple-touch-icon-144x144-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/apple-touch-icon-144x144-precomposed.png -------------------------------------------------------------------------------- /Ollert/Content/images/apple-touch-icon-152x152-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/images/apple-touch-icon-152x152-precomposed.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /Ollert/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragouf/Ollert/HEAD/Ollert/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /Ollert/Views/Account/ExternalLoginFailure.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Login Failure"; 3 | } 4 | 5 |

@ViewBag.Title.

6 |

Unsuccessful login with service.

7 | -------------------------------------------------------------------------------- /Ollert/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 | @{ 4 | ViewBag.Title = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | -------------------------------------------------------------------------------- /Ollert/Scripts/typings/webkit/webkit.d.ts: -------------------------------------------------------------------------------- 1 | interface WebkitNotifications 2 | { 3 | checkPermission: () => number; 4 | createNotification: (notifyIconUrl: string, titre: string, message: string) => any; 5 | requestPermission: () => any; 6 | } 7 | interface Window { 8 | webkitNotifications: WebkitNotifications; 9 | } -------------------------------------------------------------------------------- /Ollert/Content/themes/base/sortable.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Sortable 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | */ 9 | .ui-sortable-handle { 10 | -ms-touch-action: none; 11 | touch-action: none; 12 | } 13 | -------------------------------------------------------------------------------- /Ollert/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace Ollert 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/draggable.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Draggable 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | */ 9 | .ui-draggable-handle { 10 | -ms-touch-action: none; 11 | touch-action: none; 12 | } 13 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/all.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | */ 11 | @import "base.css"; 12 | @import "theme.css"; 13 | -------------------------------------------------------------------------------- /Ollert/Scripts/typings/gritter/gritter.d.ts: -------------------------------------------------------------------------------- 1 | interface GritterSettings { 2 | title: string; 3 | text: string; 4 | image: string; 5 | sticky: boolean; 6 | class_name: string 7 | } 8 | 9 | interface GritterMethods { 10 | add(settings: GritterSettings): void; 11 | } 12 | 13 | interface JQueryStatic { 14 | gritter: GritterMethods; 15 | } -------------------------------------------------------------------------------- /Ollert/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Owin; 2 | using Owin; 3 | 4 | [assembly: OwinStartupAttribute(typeof(Ollert.Startup))] 5 | namespace Ollert 6 | { 7 | public partial class Startup 8 | { 9 | public void Configuration(IAppBuilder app) 10 | { 11 | ConfigureAuth(app); 12 | ConfigureSignalR(app); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Ollert/Models/MailEventViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Ollert.Models 4 | { 5 | public class MailEventViewModel 6 | { 7 | public string Titre { get; set; } 8 | public string Message { get; set; } 9 | public int SalleId { get; set; } 10 | //public object NotifObject { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Ollert/Models/DeplacementModelView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | 6 | namespace Ollert.Models 7 | { 8 | public class DeplacementModelView 9 | { 10 | public int CarteId { get; set; } 11 | public int AncienTableauId { get; set; } 12 | public int NouveauTableauId { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Attachment.js: -------------------------------------------------------------------------------- 1 | var Attachment = (function () { 2 | function Attachment(id, name, date, type, size) { 3 | this.id = id; 4 | this.name = ko.observable(name); 5 | this.date = ko.observable(date); 6 | this.type = ko.observable(type); 7 | this.size = ko.observable(size); 8 | } 9 | return Attachment; 10 | })(); 11 | //# sourceMappingURL=Attachment.js.map -------------------------------------------------------------------------------- /Ollert/Content/themes/base/autocomplete.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Autocomplete 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/autocomplete/#theming 10 | */ 11 | .ui-autocomplete { 12 | position: absolute; 13 | top: 0; 14 | left: 0; 15 | cursor: default; 16 | } 17 | -------------------------------------------------------------------------------- /Ollert/App_Start/Startup.SignalR.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Identity; 2 | using Microsoft.Owin; 3 | using Microsoft.Owin.Security.Cookies; 4 | using Owin; 5 | 6 | namespace Ollert 7 | { 8 | public partial class Startup 9 | { 10 | public void ConfigureSignalR(IAppBuilder app) 11 | { 12 | // Any connection or hub wire up and configuration should go here 13 | app.MapSignalR(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Ollert/Content/themes/base/selectable.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Selectable 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | */ 9 | .ui-selectable { 10 | -ms-touch-action: none; 11 | touch-action: none; 12 | } 13 | .ui-selectable-helper { 14 | position: absolute; 15 | z-index: 100; 16 | border: 1px dotted black; 17 | } 18 | -------------------------------------------------------------------------------- /scaffolding.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Ollert.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Ollert/Controllers/MemberController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | 7 | namespace Ollert.Controllers 8 | { 9 | public class MemberController : Controller 10 | { 11 | // 12 | // GET: /Member/ 13 | public ActionResult Index() 14 | { 15 | return View(); 16 | } 17 | 18 | public ActionResult Profil() 19 | { 20 | 21 | return View(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Ollert/Content/themes/base/tooltip.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Tooltip 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/tooltip/#theming 10 | */ 11 | .ui-tooltip { 12 | padding: 8px; 13 | position: absolute; 14 | z-index: 9999; 15 | max-width: 300px; 16 | -webkit-box-shadow: 0 0 5px #aaa; 17 | box-shadow: 0 0 5px #aaa; 18 | } 19 | body .ui-tooltip { 20 | border-width: 2px; 21 | } 22 | -------------------------------------------------------------------------------- /Ollert/Scripts/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Ollert/Tools/TypeScript/en/ProjectItemsSchema.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Attachment.ts: -------------------------------------------------------------------------------- 1 | class Attachment { 2 | id: number; 3 | name: KnockoutObservable; 4 | date: KnockoutObservable; 5 | type: KnockoutObservable; 6 | size: KnockoutObservable; 7 | 8 | constructor(id: number, name: string, date: moment.Moment, type: string, size: number) { 9 | this.id = id; 10 | this.name = ko.observable(name); 11 | this.date = ko.observable(date); 12 | this.type = ko.observable(type); 13 | this.size = ko.observable(size); 14 | } 15 | } -------------------------------------------------------------------------------- /Ollert/Extensions/IEnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity.Core.Objects; 4 | using System.Data.Entity.Core.Objects.DataClasses; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | using System.Text; 9 | using System.Web; 10 | 11 | namespace Ollert 12 | { 13 | public static class IEnumerableExtensions 14 | { 15 | public static HashSet ToHashSet(this IEnumerable source) 16 | { 17 | return new HashSet(source); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Attachment.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Attachment.js","sourceRoot":"","sources":["Attachment.ts"],"names":["Attachment","Attachment.constructor"],"mappings":"AAAA,IAAM,UAAU;IAOZA,SAPEA,UAAUA,CAOAA,EAAUA,EAAEA,IAAYA,EAAEA,IAAmBA,EAAEA,IAAYA,EAAEA,IAAYA;QACjFC,IAAIA,CAACA,EAAEA,GAAGA,EAAEA,CAACA;QACbA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,CAACA,CAACA;QAChCA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,CAACA,CAACA;QAChCA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,CAACA,CAACA;QAChCA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,CAACA,CAACA;IACpCA,CAACA;IACLD,iBAACA;AAADA,CAACA,AAdD,IAcC"} -------------------------------------------------------------------------------- /Ollert/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace Ollert 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Board", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Ollert/Mailers/NotificationMailer.cs: -------------------------------------------------------------------------------- 1 | using Mvc.Mailer; 2 | using Ollert.Models; 3 | using System.Web.Mvc; 4 | 5 | namespace Ollert.Mailers 6 | { 7 | public class NotificationMailer : MailerBase 8 | { 9 | public NotificationMailer() 10 | { 11 | MasterName="_Layout"; 12 | } 13 | 14 | public virtual MvcMailMessage NewEvent(MailEventViewModel model, string userEmail) 15 | { 16 | ViewData = new ViewDataDictionary(model); 17 | 18 | return Populate(x => 19 | { 20 | x.Subject = model.Titre; 21 | x.ViewName = "NewEvent"; 22 | x.From = new System.Net.Mail.MailAddress(userEmail); 23 | x.To.Add(userEmail); 24 | }); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/User.js: -------------------------------------------------------------------------------- 1 | var User = (function () { 2 | function User(id, name, lastViewed, emailMd5, useGravatar, email) { 3 | var _this = this; 4 | this.id = id; 5 | this.name = ko.observable(name); 6 | this.email = ko.observable(email); 7 | this.emailMd5 = ko.observable(emailMd5); 8 | this.useGravatar = ko.observable(useGravatar); 9 | this.lastViewed = ko.observable(lastViewed); 10 | this.avatarPath = function () { 11 | return _this.useGravatar ? "http://www.gravatar.com/avatar/" + _this.emailMd5 : "/Board/AvatarImage/" + _this.id; 12 | }; 13 | } 14 | return User; 15 | })(); 16 | //# sourceMappingURL=User.js.map -------------------------------------------------------------------------------- /Ollert.Tests/Controllers/HomeControllerTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Web.Mvc; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using Ollert; 8 | using Ollert.Controllers; 9 | 10 | namespace Ollert.Tests.Controllers 11 | { 12 | [TestClass] 13 | public class HomeControllerTest 14 | { 15 | [TestMethod] 16 | public void Index() 17 | { 18 | // Arrange 19 | BoardController controller = new BoardController(); 20 | 21 | // Act 22 | ViewResult result = controller.Index() as ViewResult; 23 | 24 | // Assert 25 | Assert.IsNotNull("OK"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Ollert/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.Mvc; 7 | using System.Web.Optimization; 8 | using System.Web.Routing; 9 | 10 | namespace Ollert 11 | { 12 | public class MvcApplication : System.Web.HttpApplication 13 | { 14 | protected void Application_Start() 15 | { 16 | AreaRegistration.RegisterAllAreas(); 17 | GlobalConfiguration.Configure(WebApiConfig.Register); 18 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 19 | RouteConfig.RegisterRoutes(RouteTable.Routes); 20 | BundleConfig.RegisterBundles(BundleTable.Bundles); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Ollert/Models/CarteVue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Ollert.Models 8 | { 9 | /// 10 | /// Cette table sert a determiner si des notifications doivent etre affichees 11 | /// 12 | public class CarteVue : Ollert.Models.IEntity 13 | { 14 | public CarteVue() 15 | { 16 | this.Carte = new Carte(); 17 | } 18 | 19 | [Key] 20 | public int Id { get; set; } 21 | public virtual OllertUser Utilisateur { get; set; } 22 | [Required] 23 | public virtual Carte Carte { get; set; } 24 | public DateTime DerniereConsultation { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/base.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | */ 11 | @import url("core.css"); 12 | 13 | @import url("accordion.css"); 14 | @import url("autocomplete.css"); 15 | @import url("button.css"); 16 | @import url("datepicker.css"); 17 | @import url("dialog.css"); 18 | @import url("draggable.css"); 19 | @import url("menu.css"); 20 | @import url("progressbar.css"); 21 | @import url("resizable.css"); 22 | @import url("selectable.css"); 23 | @import url("selectmenu.css"); 24 | @import url("sortable.css"); 25 | @import url("slider.css"); 26 | @import url("spinner.css"); 27 | @import url("tabs.css"); 28 | @import url("tooltip.css"); 29 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/User.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"User.js","sourceRoot":"","sources":["User.ts"],"names":["User","User.constructor"],"mappings":"AAAA,IAAM,IAAI;IAUNA,SAVEA,IAAIA,CAUMA,EAAUA,EAAEA,IAAYA,EAAEA,UAAyBA,EAAEA,QAAgBA,EAAEA,WAAoBA,EAAEA,KAAaA;QAV1HC,iBAsBCA;QAXOA,IAAIA,CAACA,EAAEA,GAAGA,EAAEA,CAACA;QACbA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,CAACA,CAACA;QAChCA,IAAIA,CAACA,KAAKA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,KAAKA,CAACA,CAACA;QAClCA,IAAIA,CAACA,QAAQA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,QAAQA,CAACA,CAACA;QACxCA,IAAIA,CAACA,WAAWA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,WAAWA,CAACA,CAACA;QAC9CA,IAAIA,CAACA,UAAUA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,UAAUA,CAACA,CAACA;QAE5CA,IAAIA,CAACA,UAAUA,GAAGA;YACdA,MAAMA,CAACA,KAAIA,CAACA,WAAWA,GAAGA,iCAAiCA,GAAGA,KAAIA,CAACA,QAAQA,GAAGA,qBAAqBA,GAAGA,KAAIA,CAACA,EAAEA,CAACA;QAClHA,CAACA,CAAAA;IACLA,CAACA;IACLD,WAACA;AAADA,CAACA,AAtBD,IAsBC"} -------------------------------------------------------------------------------- /Ollert/Views/Account/Manage.cshtml: -------------------------------------------------------------------------------- 1 | @using Ollert.Models; 2 | @using Microsoft.AspNet.Identity; 3 | @{ 4 | ViewBag.Title = "Manage Account"; 5 | } 6 | 7 |

@ViewBag.Title.

8 | 9 |

@ViewBag.StatusMessage

10 |
11 |
12 | @if (ViewBag.HasLocalPassword) 13 | { 14 | @Html.Partial("_ChangePasswordPartial") 15 | } 16 | else 17 | { 18 | @Html.Partial("_SetPasswordPartial") 19 | } 20 | 21 |
22 | @Html.Action("RemoveAccountList") 23 | @Html.Partial("_ExternalLoginsListPartial", new { Action = "LinkLogin", ReturnUrl = ViewBag.ReturnUrl }) 24 |
25 |
26 |
27 | @section Scripts { 28 | @Scripts.Render("~/bundles/jqueryval") 29 | } 30 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/User.ts: -------------------------------------------------------------------------------- 1 | class User { 2 | id: number; 3 | name: KnockoutObservable; 4 | email: KnockoutObservable; 5 | emailMd5: KnockoutObservable; 6 | useGravatar: KnockoutObservable; 7 | lastViewed: KnockoutObservable; 8 | 9 | avatarPath: () => string; 10 | 11 | constructor(id: number, name: string, lastViewed: moment.Moment, emailMd5: string, useGravatar: boolean, email: string) { 12 | this.id = id; 13 | this.name = ko.observable(name); 14 | this.email = ko.observable(email); 15 | this.emailMd5 = ko.observable(emailMd5); 16 | this.useGravatar = ko.observable(useGravatar); 17 | this.lastViewed = ko.observable(lastViewed); 18 | 19 | this.avatarPath = () => { 20 | return this.useGravatar ? "http://www.gravatar.com/avatar/" + this.emailMd5 : "/Board/AvatarImage/" + this.id; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Ollert/Content/signin.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 40px; 3 | padding-bottom: 40px; 4 | background-color: #eee; 5 | } 6 | 7 | .form-signin { 8 | max-width: 330px; 9 | padding: 15px; 10 | margin: 0 auto; 11 | } 12 | .form-signin .form-signin-heading, 13 | .form-signin .checkbox { 14 | margin-bottom: 10px; 15 | } 16 | .form-signin .checkbox { 17 | font-weight: normal; 18 | } 19 | .form-signin .form-control { 20 | position: relative; 21 | font-size: 16px; 22 | height: auto; 23 | padding: 10px; 24 | -webkit-box-sizing: border-box; 25 | -moz-box-sizing: border-box; 26 | box-sizing: border-box; 27 | } 28 | .form-signin .form-control:focus { 29 | z-index: 2; 30 | } 31 | .form-signin input[type="text"] { 32 | margin-bottom: -1px; 33 | border-bottom-left-radius: 0; 34 | border-bottom-right-radius: 0; 35 | } 36 | .form-signin input[type="password"] { 37 | margin-bottom: 10px; 38 | border-top-left-radius: 0; 39 | border-top-right-radius: 0; 40 | } -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Message.js: -------------------------------------------------------------------------------- 1 | var Message = (function () { 2 | function Message(id, text, user, date, cardViewed) { 3 | var self = this; 4 | this.id = id; 5 | this.text = ko.observable(text); 6 | this.user = ko.observable(user); 7 | this.date = ko.observable(date); 8 | this.cardViewed = cardViewed; 9 | // Computed 10 | this.isViewed = ko.computed(function () { 11 | if (self.cardViewed() != null) 12 | return self.date() > self.cardViewed(); 13 | else 14 | return true; 15 | }, self); 16 | this.formattedDate = ko.computed(function () { 17 | var formattedDate = ''; 18 | if (self.date() != null) { 19 | formattedDate = self.date().calendar(); 20 | } 21 | return formattedDate; 22 | }, self); 23 | } 24 | return Message; 25 | })(); 26 | //# sourceMappingURL=Message.js.map -------------------------------------------------------------------------------- /Ollert/Tools/TypeScript/Microsoft.TypeScript.Default.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ES5 5 | true 6 | false 7 | none 8 | false 9 | 10 | 11 | false 12 | true 13 | 14 | 15 | true 16 | 17 | 18 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/accordion.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Accordion 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/accordion/#theming 10 | */ 11 | .ui-accordion .ui-accordion-header { 12 | display: block; 13 | cursor: pointer; 14 | position: relative; 15 | margin: 2px 0 0 0; 16 | padding: .5em .5em .5em .7em; 17 | min-height: 0; /* support: IE7 */ 18 | font-size: 100%; 19 | } 20 | .ui-accordion .ui-accordion-icons { 21 | padding-left: 2.2em; 22 | } 23 | .ui-accordion .ui-accordion-icons .ui-accordion-icons { 24 | padding-left: 2.2em; 25 | } 26 | .ui-accordion .ui-accordion-header .ui-accordion-header-icon { 27 | position: absolute; 28 | left: .5em; 29 | top: 50%; 30 | margin-top: -8px; 31 | } 32 | .ui-accordion .ui-accordion-content { 33 | padding: 1em 2.2em; 34 | border-top: 0; 35 | overflow: auto; 36 | } 37 | -------------------------------------------------------------------------------- /Ollert/Scripts/typings/signalr/signalr.ollert.d.ts: -------------------------------------------------------------------------------- 1 | // SignalR 2 | interface SignalR { 3 | ollertHub: HubProxy; 4 | } 5 | interface HubProxy { 6 | client: IOlertHubClient; 7 | server: IOlertHubServer; 8 | } 9 | 10 | interface IOlertHubClient { 11 | newMessage(message: Ollert.ServerMessage); 12 | deleteMessage(message: Ollert.ServerMessage); 13 | newMove(move: Ollert.ServerMove); 14 | newCard(card: Ollert.ServerCard); 15 | changeCard(card: Ollert.ServerCard); 16 | deleteCard(card: Ollert.ServerCard); 17 | addFile(file: Ollert.ServerAttachment); 18 | deleteFile(file: Ollert.ServerAttachment); 19 | addStep(step: Ollert.ServerStep); 20 | deleteStep(step: Ollert.ServerStep); 21 | changeStep(step: Ollert.ServerStep); 22 | newNotification(notification: Ollert.ServerNotification); 23 | onConnected(users: any); 24 | onDisconnected(users: any); 25 | } 26 | 27 | interface IOlertHubServer { 28 | //join(user: User): JQueryPromise; 29 | } -------------------------------------------------------------------------------- /Ollert/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNet.Identity 2 | @if (Request.IsAuthenticated) 3 | { 4 | using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" })) 5 | { 6 | @Html.AntiForgeryToken() 7 | 8 | 14 | } 15 | } 16 | else 17 | { 18 | 22 | } 23 | -------------------------------------------------------------------------------- /Ollert/Api/UserController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Entity; 5 | using System.Data.Entity.Infrastructure; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Net.Http; 9 | using System.Threading.Tasks; 10 | using System.Web.Http; 11 | using System.Web.Http.Description; 12 | using Ollert.Models; 13 | using Ollert.DAL; 14 | 15 | namespace Ollert.Api 16 | { 17 | [Authorize] 18 | public class UserController : ApiController 19 | { 20 | private OllertDbContext db = new OllertDbContext(); 21 | 22 | // GET api/User 23 | public async Task> GetUsers() 24 | { 25 | return await db.Users.ToListAsync(); 26 | } 27 | 28 | protected override void Dispose(bool disposing) 29 | { 30 | if (disposing) 31 | { 32 | db.Dispose(); 33 | } 34 | base.Dispose(disposing); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Ollert/Models/ParticipantSalle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Text; 8 | using Microsoft.AspNet.Identity; 9 | using Microsoft.AspNet.Identity.EntityFramework; 10 | using Ollert.DAL; 11 | using System.Web; 12 | using Newtonsoft.Json; 13 | 14 | namespace Ollert.Models 15 | { 16 | public class ParticipantSalle : Ollert.Models.IEntity 17 | { 18 | [Key] 19 | public int Id { get; set; } 20 | 21 | [Column(Order = 1)] 22 | [ForeignKey("Participant")] 23 | public string UserId { get; set; } 24 | 25 | [Column(Order = 2)] 26 | [ForeignKey("Salle")] 27 | public int SalleId { get; set; } 28 | 29 | public virtual OllertUser Participant { get; set; } 30 | [Required] 31 | public virtual Salle Salle { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Ollert/Taches.txt: -------------------------------------------------------------------------------- 1 | - Gestion de plusieurs salles (TERMINE) 2 | - Ajout de progression (TERMINE) 3 | - Rendre notification global dans le layout (TERMINE) 4 | - demande suppression par popover (TERMINE) 5 | - wep app iphone (TERMINE) 6 | 7 | - possibilite de mettre une date limite 8 | - import des donnees de trello 9 | - affichage d'une roue a la place de la barre de progression 10 | 11 | - possibilite d'archiver un tableau 12 | 13 | 14 | - positions 15 | - ouvrir carte par un lien 16 | - possibilité de deplacer en cliquant sur la roue de la carte 17 | - possibilité de mettre une etiquette 18 | 19 | - Profil -> changer la photo d'identité ou le mot de passe 20 | - Profil -> Utilisation de gravatar 21 | - Parametre -> notification par email 22 | 23 | 24 | - Reorganisation des fichiers 25 | 26 | ----FUTUR 27 | - affichage de toutes les taches 28 | - affichage calendrier 29 | - verif securité 30 | - possibilité de générer facture a partir des taches terminées 31 | - App iphone 32 | 33 | ---------BUGS 34 | - notif nouveau fichier tj affiché pour utilisateur -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Notification.js: -------------------------------------------------------------------------------- 1 | var Notification = (function () { 2 | function Notification(data) { 3 | var self = this; 4 | this.id = data.id; 5 | this.type = data.type; 6 | this.title = data.title; 7 | this.text = data.text; 8 | this.date = data.date; 9 | this.lastUserViewed = data.lastUserViewed; 10 | this.creator = data.creator; 11 | this.isNotifViewed = ko.computed(function () { 12 | if (self.lastUserViewed != null) { 13 | return self.date > self.lastUserViewed; 14 | } 15 | else 16 | return true; 17 | }, self); 18 | this.formattedDate = ko.computed(function () { 19 | return self.date.calendar(); 20 | }, self); 21 | this.notificationImgUrl = ko.computed(function () { 22 | var imgUrl = Global.getNotifyIconUrl(self.type); 23 | return imgUrl; 24 | }, self); 25 | } 26 | return Notification; 27 | })(); 28 | //# sourceMappingURL=Notification.js.map -------------------------------------------------------------------------------- /Ollert/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Http; 5 | 6 | namespace Ollert 7 | { 8 | public static class WebApiConfig 9 | { 10 | public static void Register(HttpConfiguration config) 11 | { 12 | // Web API configuration and services 13 | //var json = config.Formatters.JsonFormatter; 14 | //json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; 15 | //json.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; 16 | config.Formatters.Remove(config.Formatters.XmlFormatter); 17 | 18 | 19 | // Web API routes 20 | config.MapHttpAttributeRoutes(); 21 | 22 | config.Routes.MapHttpRoute( 23 | name: "DefaultApi", 24 | routeTemplate: "api/{controller}/{id}", 25 | defaults: new { id = RouteParameter.Optional } 26 | ); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Message.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Message.js","sourceRoot":"","sources":["Message.ts"],"names":["Message","Message.constructor"],"mappings":"AAAA,IAAM,OAAO;IAUTA,SAVEA,OAAOA,CAUGA,EAAUA,EAAEA,IAAYA,EAAEA,IAAUA,EAAEA,IAAmBA,EAAEA,UAA6CA;QAChHC,IAAIA,IAAIA,GAAGA,IAAIA,CAACA;QAEhBA,IAAIA,CAACA,EAAEA,GAAGA,EAAEA,CAACA;QACbA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,CAACA,CAACA;QAChCA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,CAACA,CAACA;QAChCA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,CAACA,CAACA;QAChCA,IAAIA,CAACA,UAAUA,GAAGA,UAAUA,CAACA;QAG7BA,AADAA,WAAWA;QACXA,IAAIA,CAACA,QAAQA,GAAGA,EAAEA,CAACA,QAAQA,CAACA;YACxB,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3C,IAAI;gBACA,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC,EAAEA,IAAIA,CAACA,CAACA;QACTA,IAAIA,CAACA,aAAaA,GAAGA,EAAEA,CAACA,QAAQA,CAACA;YAC7B,IAAI,aAAa,GAAG,EAAE,CAAC;YACvB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;gBACtB,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YAC3C,CAAC;YACD,MAAM,CAAC,aAAa,CAAC;QACzB,CAAC,EAAEA,IAAIA,CAACA,CAACA;IACbA,CAACA;IACLD,cAACA;AAADA,CAACA,AAlCD,IAkCC"} -------------------------------------------------------------------------------- /Ollert/Extensions/StringExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Diagnostics; 6 | using System.Text.RegularExpressions; 7 | using System.Security.Cryptography; 8 | using System.Text; 9 | 10 | namespace Ollert 11 | { 12 | public static class StringExtension 13 | { 14 | public static string FormatWith(this string target, params object[] args) 15 | { 16 | return string.Format(target, args); 17 | } 18 | 19 | public static string Md5(this string target) 20 | { 21 | // step 1, calculate MD5 hash from input 22 | MD5 md5 = System.Security.Cryptography.MD5.Create(); 23 | byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(target); 24 | byte[] hash = md5.ComputeHash(inputBytes); 25 | 26 | // step 2, convert byte array to hex string 27 | StringBuilder sb = new StringBuilder(); 28 | for (int i = 0; i < hash.Length; i++) 29 | { 30 | sb.Append(hash[i].ToString("X2")); 31 | } 32 | return sb.ToString(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Ollert/Models/CarteEtape.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Text; 8 | using Microsoft.AspNet.Identity; 9 | using Microsoft.AspNet.Identity.EntityFramework; 10 | using Ollert.DAL; 11 | using System.Web; 12 | using Newtonsoft.Json; 13 | 14 | namespace Ollert.Models 15 | { 16 | public class CarteEtape : Ollert.Models.IEntity 17 | { 18 | [Key] 19 | public int Id { get; set; } 20 | public string Titre { get; set; } 21 | public int Position { get; set; } 22 | public int Estimation { get; set; } 23 | public int Reel { get; set; } 24 | public bool Terminee { get; set; } 25 | [Required] 26 | [JsonIgnore] 27 | public virtual Carte Carte { get; set; } 28 | [NotMapped] 29 | public int CarteId 30 | { 31 | get 32 | { 33 | if (Carte != null) 34 | return Carte.Id; 35 | else 36 | return -1; 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Ollert/Models/Tableau.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Web; 8 | 9 | namespace Ollert.Models 10 | { 11 | [DataContract] 12 | public class Tableau : Ollert.Models.IEntity 13 | { 14 | public Tableau() 15 | { 16 | this.Cartes = new List(); 17 | } 18 | 19 | [Key] 20 | [DataMember] 21 | public int Id { get; set; } 22 | [DataMember] 23 | public string Nom { get; set; } 24 | [DataMember] 25 | public int Position { get; set; } 26 | [DataMember] 27 | public virtual ICollection Cartes { get; set; } 28 | [Required] 29 | public virtual Salle Salle { get; set; } 30 | 31 | [NotMapped] 32 | [DataMember] 33 | public int SalleId 34 | { 35 | get 36 | { 37 | if (this.Salle != null) 38 | return this.Salle.Id; 39 | else 40 | return -1; 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Ollert/Models/Notification.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Linq; 8 | using System.Text; 9 | 10 | namespace Ollert.Models 11 | { 12 | [Flags] 13 | public enum TypeNotification 14 | { 15 | NouveauMessage = 1, 16 | SuppressionMessage = 2, 17 | 18 | MouvementCarte = 3, 19 | NouvelleCarte = 4, 20 | EditionCarte = 5, 21 | SuppressionCarte = 6, 22 | 23 | AjoutFichier = 7, 24 | SuppressionFichier = 8, 25 | 26 | AjoutEtape = 9, 27 | SuppressionEtape = 10, 28 | ModificationEtape = 11 29 | 30 | } 31 | public class Notification : Ollert.Models.IEntity 32 | { 33 | [Key] 34 | public int Id { get; set; } 35 | [JsonConverter(typeof(StringEnumConverter))] 36 | public TypeNotification Type { get; set; } 37 | public string Titre { get; set; } 38 | public string Texte { get; set; } 39 | public DateTime Date { get; set; } 40 | public virtual OllertUser Createur { get; set; } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Notification.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Notification.js","sourceRoot":"","sources":["Notification.ts"],"names":["Notification","Notification.constructor"],"mappings":"AAUA,IAAM,YAAY;IAadA,SAbEA,YAAYA,CAaFA,IAAmBA;QAC3BC,IAAIA,IAAIA,GAAGA,IAAIA,CAACA;QAEhBA,IAAIA,CAACA,EAAEA,GAAGA,IAAIA,CAACA,EAAEA,CAACA;QAClBA,IAAIA,CAACA,IAAIA,GAAGA,IAAIA,CAACA,IAAIA,CAAAA;QACrBA,IAAIA,CAACA,KAAKA,GAAGA,IAAIA,CAACA,KAAKA,CAACA;QACxBA,IAAIA,CAACA,IAAIA,GAAGA,IAAIA,CAACA,IAAIA,CAACA;QACtBA,IAAIA,CAACA,IAAIA,GAAGA,IAAIA,CAACA,IAAIA,CAACA;QACtBA,IAAIA,CAACA,cAAcA,GAAGA,IAAIA,CAACA,cAAcA,CAACA;QAC1CA,IAAIA,CAACA,OAAOA,GAAGA,IAAIA,CAACA,OAAOA,CAACA;QAE5BA,IAAIA,CAACA,aAAaA,GAAGA,EAAEA,CAACA,QAAQA,CAACA;YAC7B,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC;gBAC9B,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC;YAC3C,CAAC;YACD,IAAI;gBACA,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC,EAAEA,IAAIA,CAACA,CAACA;QACTA,IAAIA,CAACA,aAAaA,GAAGA,EAAEA,CAACA,QAAQA,CAACA;YAC7B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,CAAC,EAAEA,IAAIA,CAACA,CAACA;QACTA,IAAIA,CAACA,kBAAkBA,GAAGA,EAAEA,CAACA,QAAQA,CAACA;YAClC,IAAI,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,CAAC,MAAM,CAAC;QAClB,CAAC,EAAEA,IAAIA,CAACA,CAACA;IACbA,CAACA;IACLD,mBAACA;AAADA,CAACA,AAvCD,IAuCC"} -------------------------------------------------------------------------------- /Ollert/Views/Account/Login.cshtml: -------------------------------------------------------------------------------- 1 | @model Ollert.Models.LoginViewModel 2 | 3 | @{ 4 | Layout = "~/Views/Shared/_LayoutPublic.cshtml"; 5 | } 6 | 7 | @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-signin", role = "form", id = "loginForm" })) 8 | { 9 | @Html.AntiForgeryToken() 10 | 11 | 12 | 13 |
14 | 17 |
18 | 19 | } 20 | 21 | @section Scripts { 22 | 28 | } 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Ollert/Models/Fichier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Text; 8 | 9 | namespace Ollert.Models 10 | { 11 | [DataContract] 12 | public class Fichier : Ollert.Models.IEntity 13 | { 14 | [Key] 15 | [DataMember] 16 | public int Id { get; set; } 17 | [DataMember] 18 | public string Nom { get; set; } 19 | [DataMember] 20 | public DateTime DateEnvoi { get; set; } 21 | [DataMember] 22 | public string ContentType { get; set; } 23 | public byte[] Data { get; set; } 24 | [Required] 25 | public virtual Carte Carte { get; set; } 26 | 27 | [NotMapped] 28 | [DataMember] 29 | public int CarteId 30 | { 31 | get 32 | { 33 | if (Carte != null) 34 | return Carte.Id; 35 | else 36 | return -1; 37 | } 38 | } 39 | [NotMapped] 40 | [DataMember] 41 | public int FileSize { get { return this.Data.Length; } } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Ollert/Views/Account/_SetPasswordPartial.cshtml: -------------------------------------------------------------------------------- 1 | @model Ollert.Models.ManageUserViewModel 2 | 3 |

4 | You do not have a local username/password for this site. Add a local 5 | account so you can log in without an external login. 6 |

7 | 8 | @using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 | 12 |

Create Local Login

13 |
14 | @Html.ValidationSummary() 15 |
16 | @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" }) 17 |
18 | @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" }) 19 |
20 |
21 |
22 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 23 |
24 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 25 |
26 |
27 |
28 |
29 | 30 |
31 |
32 | } 33 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Message.ts: -------------------------------------------------------------------------------- 1 | class Message { 2 | id: number; 3 | text: KnockoutObservable; 4 | user: KnockoutObservable; 5 | date: KnockoutObservable; 6 | cardViewed: KnockoutObservable; // observable 7 | 8 | isViewed: KnockoutComputed; 9 | formattedDate: KnockoutComputed; 10 | 11 | constructor(id: number, text: string, user: User, date: moment.Moment, cardViewed: KnockoutObservable) { 12 | var self = this; 13 | 14 | this.id = id; 15 | this.text = ko.observable(text); 16 | this.user = ko.observable(user); 17 | this.date = ko.observable(date); 18 | this.cardViewed = cardViewed; 19 | 20 | // Computed 21 | this.isViewed = ko.computed(function () { 22 | if (self.cardViewed() != null) 23 | return self.date() > self.cardViewed(); 24 | else 25 | return true; 26 | }, self); 27 | this.formattedDate = ko.computed(function () { 28 | var formattedDate = ''; 29 | if (self.date() != null) { 30 | formattedDate = self.date().calendar(); 31 | } 32 | return formattedDate; 33 | }, self); 34 | } 35 | } -------------------------------------------------------------------------------- /Ollert/Views/Account/_ExternalLoginsListPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.Owin.Security 2 | 3 |

Use another service to log in.

4 |
5 | @{ 6 | var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes(); 7 | if (loginProviders.Count() == 0) 8 | { 9 |
10 |

There are no external authentication services configured. See this article 11 | for details on setting up this ASP.NET application to support logging in via external services.

12 |
13 | } 14 | else 15 | { 16 | string action = Model.Action; 17 | string returnUrl = Model.ReturnUrl; 18 | using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl })) 19 | { 20 | @Html.AntiForgeryToken() 21 |
22 |

23 | @foreach (AuthenticationDescription p in loginProviders) 24 | { 25 | 26 | } 27 |

28 |
29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Ollert/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Ollert/Views/Account/_RemoveAccountPartial.cshtml: -------------------------------------------------------------------------------- 1 | @model ICollection 2 | 3 | @if (Model.Count > 0) 4 | { 5 |

Registered Logins

6 | 7 | 8 | @foreach (var account in Model) 9 | { 10 | 11 | 12 | 30 | 31 | } 32 | 33 |
@account.LoginProvider 13 | @if (ViewBag.ShowRemoveButton) 14 | { 15 | using (Html.BeginForm("Disassociate", "Account")) 16 | { 17 | @Html.AntiForgeryToken() 18 |
19 | @Html.Hidden("loginProvider", account.LoginProvider) 20 | @Html.Hidden("providerKey", account.ProviderKey) 21 | 22 |
23 | } 24 | } 25 | else 26 | { 27 | @:   28 | } 29 |
34 | } 35 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/selectmenu.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Selectmenu 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/selectmenu/#theming 10 | */ 11 | .ui-selectmenu-menu { 12 | padding: 0; 13 | margin: 0; 14 | position: absolute; 15 | top: 0; 16 | left: 0; 17 | display: none; 18 | } 19 | .ui-selectmenu-menu .ui-menu { 20 | overflow: auto; 21 | /* Support: IE7 */ 22 | overflow-x: hidden; 23 | padding-bottom: 1px; 24 | } 25 | .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { 26 | font-size: 1em; 27 | font-weight: bold; 28 | line-height: 1.5; 29 | padding: 2px 0.4em; 30 | margin: 0.5em 0 0 0; 31 | height: auto; 32 | border: 0; 33 | } 34 | .ui-selectmenu-open { 35 | display: block; 36 | } 37 | .ui-selectmenu-button { 38 | display: inline-block; 39 | overflow: hidden; 40 | position: relative; 41 | text-decoration: none; 42 | cursor: pointer; 43 | } 44 | .ui-selectmenu-button span.ui-icon { 45 | right: 0.5em; 46 | left: auto; 47 | margin-top: -8px; 48 | position: absolute; 49 | top: 50%; 50 | } 51 | .ui-selectmenu-button span.ui-selectmenu-text { 52 | text-align: left; 53 | padding: 0.4em 2.1em 0.4em 1em; 54 | display: block; 55 | line-height: 1.4; 56 | overflow: hidden; 57 | text-overflow: ellipsis; 58 | white-space: nowrap; 59 | } 60 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/menu.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Menu 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/menu/#theming 10 | */ 11 | .ui-menu { 12 | list-style: none; 13 | padding: 0; 14 | margin: 0; 15 | display: block; 16 | outline: none; 17 | } 18 | .ui-menu .ui-menu { 19 | position: absolute; 20 | } 21 | .ui-menu .ui-menu-item { 22 | position: relative; 23 | margin: 0; 24 | padding: 3px 1em 3px .4em; 25 | cursor: pointer; 26 | min-height: 0; /* support: IE7 */ 27 | /* support: IE10, see #8844 */ 28 | list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); 29 | } 30 | .ui-menu .ui-menu-divider { 31 | margin: 5px 0; 32 | height: 0; 33 | font-size: 0; 34 | line-height: 0; 35 | border-width: 1px 0 0 0; 36 | } 37 | .ui-menu .ui-state-focus, 38 | .ui-menu .ui-state-active { 39 | margin: -1px; 40 | } 41 | 42 | /* icon support */ 43 | .ui-menu-icons { 44 | position: relative; 45 | } 46 | .ui-menu-icons .ui-menu-item { 47 | padding-left: 2em; 48 | } 49 | 50 | /* left-aligned */ 51 | .ui-menu .ui-icon { 52 | position: absolute; 53 | top: 0; 54 | bottom: 0; 55 | left: .2em; 56 | margin: auto 0; 57 | } 58 | 59 | /* right-aligned */ 60 | .ui-menu .ui-menu-icon { 61 | left: auto; 62 | right: 0; 63 | } 64 | -------------------------------------------------------------------------------- /Ollert/Views/Account/ExternalLoginConfirmation.cshtml: -------------------------------------------------------------------------------- 1 | @model Ollert.Models.ExternalLoginConfirmationViewModel 2 | @{ 3 | ViewBag.Title = "Register"; 4 | } 5 |

@ViewBag.Title.

6 |

Associate your @ViewBag.LoginProvider account.

7 | 8 | @using (Html.BeginForm("ExternalLoginConfirmation", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 | 12 |

Association Form

13 |
14 | @Html.ValidationSummary(true) 15 |

16 | You've successfully authenticated with @ViewBag.LoginProvider. 17 | Please enter a user name for this site below and click the Register button to finish 18 | logging in. 19 |

20 |
21 | @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) 22 |
23 | @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) 24 | @Html.ValidationMessageFor(m => m.UserName) 25 |
26 |
27 |
28 |
29 | 30 |
31 |
32 | } 33 | 34 | @section Scripts { 35 | @Scripts.Render("~/bundles/jqueryval") 36 | } 37 | -------------------------------------------------------------------------------- /Ollert/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/tabs.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Tabs 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/tabs/#theming 10 | */ 11 | .ui-tabs { 12 | position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ 13 | padding: .2em; 14 | } 15 | .ui-tabs .ui-tabs-nav { 16 | margin: 0; 17 | padding: .2em .2em 0; 18 | } 19 | .ui-tabs .ui-tabs-nav li { 20 | list-style: none; 21 | float: left; 22 | position: relative; 23 | top: 0; 24 | margin: 1px .2em 0 0; 25 | border-bottom-width: 0; 26 | padding: 0; 27 | white-space: nowrap; 28 | } 29 | .ui-tabs .ui-tabs-nav .ui-tabs-anchor { 30 | float: left; 31 | padding: .5em 1em; 32 | text-decoration: none; 33 | } 34 | .ui-tabs .ui-tabs-nav li.ui-tabs-active { 35 | margin-bottom: -1px; 36 | padding-bottom: 1px; 37 | } 38 | .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, 39 | .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, 40 | .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { 41 | cursor: text; 42 | } 43 | .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { 44 | cursor: pointer; 45 | } 46 | .ui-tabs .ui-tabs-panel { 47 | display: block; 48 | border-width: 0; 49 | padding: 1em 1.4em; 50 | background: none; 51 | } 52 | -------------------------------------------------------------------------------- /Ollert/Views/Board/List/_AddModal.cshtml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Ollert 2 | ================== 3 | 4 | Trello like application with : 5 | 6 | **Backend** 7 | * C# 5.0 (using await/async paradigm) 8 | * MVC 5 with Web API 2 9 | * SignalR 2.0 10 | * Entity Framework 6 (code first and migrations) 11 | 12 | **FrontEnd** 13 | * TypeScript 1.4 14 | * SignalR 2.0 (HTML5 websocket) 15 | * Knockout 16 | * Chrome Notification 17 | 18 | ### Description 19 | Create rooms and boards and then organize your tasks by pinning cards on appriopriate board. 20 | 21 | Everything is replicated instantly on every connected user UI with websocket connections. 22 | 23 | ### Installation 24 | * In visual studio package manager console restore package files then run : 25 | 26 | >add-migration Init 27 | 28 | >update-database 29 | 30 | start the project. 31 | 32 | Login with david and 123456 33 | 34 | ### Developement 35 | - ./api folder contains most of the backend API code 36 | - ./Scripts/pages/Classes folder contains most of the javascript (typescript) frontend code 37 | - ./Hubs folder contains backend websocket (SignalR) code 38 | - ./Views folder contains html parts (Razor) 39 | - ./Controllers contains contains basic response to url request but most of the UI is generate through javascript/REST API 40 | 41 | 42 | ### Screenshot 43 | 44 | **Room view** 45 | ![GitHub Logo](/docs/Capture.PNG) 46 | 47 | **Boards with pinned cards** 48 | ![GitHub Logo](/docs/Capture2.PNG) 49 | 50 | **Card edition** 51 | ![GitHub Logo](/docs/Capture3.PNG) 52 | -------------------------------------------------------------------------------- /Ollert/Views/Board/Salle/_AddTableModal.cshtml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Ollert/Views/Board/Salle/_EditCardModal.cshtml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Ollert/Models/Message.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Text; 8 | 9 | namespace Ollert.Models 10 | { 11 | [DataContract] 12 | public class Message : Ollert.Models.IEntity 13 | { 14 | [Key] 15 | [DataMember] 16 | public int Id { get; set; } 17 | [DataMember] 18 | public string Texte { get; set; } 19 | [DataMember] 20 | public DateTime CreateOn { get; set; } 21 | [DataMember] 22 | public virtual OllertUser Utilisateur { get; set; } 23 | [Required] 24 | public virtual Carte Carte { get; set; } 25 | 26 | 27 | [NotMapped] 28 | [DataMember] 29 | public int CarteId 30 | { 31 | get 32 | { 33 | if (Carte != null) 34 | return Carte.Id; 35 | else 36 | return -1; 37 | } 38 | } 39 | 40 | [NotMapped] 41 | [DataMember] 42 | public DateTime DerniereVueCarte 43 | { 44 | get 45 | { 46 | if (Carte != null) 47 | return Carte.LastTimeViewed; 48 | else 49 | return DateTime.MinValue; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/spinner.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Spinner 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/spinner/#theming 10 | */ 11 | .ui-spinner { 12 | position: relative; 13 | display: inline-block; 14 | overflow: hidden; 15 | padding: 0; 16 | vertical-align: middle; 17 | } 18 | .ui-spinner-input { 19 | border: none; 20 | background: none; 21 | color: inherit; 22 | padding: 0; 23 | margin: .2em 0; 24 | vertical-align: middle; 25 | margin-left: .4em; 26 | margin-right: 22px; 27 | } 28 | .ui-spinner-button { 29 | width: 16px; 30 | height: 50%; 31 | font-size: .5em; 32 | padding: 0; 33 | margin: 0; 34 | text-align: center; 35 | position: absolute; 36 | cursor: default; 37 | display: block; 38 | overflow: hidden; 39 | right: 0; 40 | } 41 | /* more specificity required here to override default borders */ 42 | .ui-spinner a.ui-spinner-button { 43 | border-top: none; 44 | border-bottom: none; 45 | border-right: none; 46 | } 47 | /* vertically center icon */ 48 | .ui-spinner .ui-icon { 49 | position: absolute; 50 | margin-top: -8px; 51 | top: 50%; 52 | left: 0; 53 | } 54 | .ui-spinner-up { 55 | top: 0; 56 | } 57 | .ui-spinner-down { 58 | bottom: 0; 59 | } 60 | 61 | /* TR overrides */ 62 | .ui-spinner .ui-icon-triangle-1-s { 63 | /* need to fix icons sprite */ 64 | background-position: -65px -16px; 65 | } 66 | -------------------------------------------------------------------------------- /Ollert/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Ollert")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Ollert")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a91bac41-791b-42f1-a347-ddf223cd568f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Ollert.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Ollert.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Ollert.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bf741e62-1282-4442-b2b2-b17086947795")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Ollert/Views/Account/_ChangePasswordPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNet.Identity 2 | @model Ollert.Models.ManageUserViewModel 3 | 4 |

You're logged in as @User.Identity.GetUserName().

5 | 6 | @using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 7 | { 8 | @Html.AntiForgeryToken() 9 |

Change Password Form

10 |
11 | @Html.ValidationSummary() 12 |
13 | @Html.LabelFor(m => m.OldPassword, new { @class = "col-md-2 control-label" }) 14 |
15 | @Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" }) 16 |
17 |
18 |
19 | @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" }) 20 |
21 | @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" }) 22 |
23 |
24 |
25 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 26 |
27 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 28 |
29 |
30 | 31 |
32 |
33 | 34 |
35 |
36 | } 37 | -------------------------------------------------------------------------------- /Ollert/Views/Account/Register.cshtml: -------------------------------------------------------------------------------- 1 | @model Ollert.Models.RegisterViewModel 2 | @{ 3 | ViewBag.Title = "Register"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

Create a new account.

12 |
13 | @Html.ValidationSummary() 14 |
15 | @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) 16 |
17 | @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) 18 |
19 |
20 |
21 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 22 |
23 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 24 |
25 |
26 |
27 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 28 |
29 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 30 |
31 |
32 |
33 |
34 | 35 |
36 |
37 | } 38 | 39 | @section Scripts { 40 | @Scripts.Render("~/bundles/jqueryval") 41 | } 42 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Notification.ts: -------------------------------------------------------------------------------- 1 | interface INotification{ 2 | id: number; 3 | type: string; 4 | title: string; 5 | text: string; 6 | date: moment.Moment; 7 | lastUserViewed: moment.Moment; 8 | creator: User; 9 | } 10 | 11 | class Notification { 12 | id: number; 13 | type: string; 14 | title: string; 15 | text: string; 16 | date: moment.Moment; 17 | lastUserViewed: moment.Moment; 18 | creator: User; 19 | 20 | isNotifViewed: KnockoutComputed; 21 | formattedDate: KnockoutComputed; 22 | notificationImgUrl: KnockoutComputed; 23 | 24 | constructor(data: INotification) { 25 | var self = this; 26 | 27 | this.id = data.id; 28 | this.type = data.type 29 | this.title = data.title; 30 | this.text = data.text; 31 | this.date = data.date; 32 | this.lastUserViewed = data.lastUserViewed; 33 | this.creator = data.creator; 34 | 35 | this.isNotifViewed = ko.computed(function () { 36 | if (self.lastUserViewed != null) { 37 | return self.date > self.lastUserViewed; 38 | } 39 | else 40 | return true; 41 | }, self); 42 | this.formattedDate = ko.computed(function () { 43 | return self.date.calendar(); 44 | }, self); 45 | this.notificationImgUrl = ko.computed(function () { 46 | var imgUrl = Global.getNotifyIconUrl(self.type); 47 | return imgUrl; 48 | }, self); 49 | } 50 | } -------------------------------------------------------------------------------- /Ollert/App_Start/Startup.Auth.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Identity; 2 | using Microsoft.Owin; 3 | using Microsoft.Owin.Security.Cookies; 4 | using Owin; 5 | 6 | namespace Ollert 7 | { 8 | public partial class Startup 9 | { 10 | // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 11 | public void ConfigureAuth(IAppBuilder app) 12 | { 13 | // Enable the application to use a cookie to store information for the signed in user 14 | app.UseCookieAuthentication(new CookieAuthenticationOptions 15 | { 16 | AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 17 | LoginPath = new PathString("/Account/Login") 18 | }); 19 | // Use a cookie to temporarily store information about a user logging in with a third party login provider 20 | app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 21 | 22 | // Uncomment the following lines to enable logging in with third party login providers 23 | //app.UseMicrosoftAccountAuthentication( 24 | // clientId: "", 25 | // clientSecret: ""); 26 | 27 | //app.UseTwitterAuthentication( 28 | // consumerKey: "", 29 | // consumerSecret: ""); 30 | 31 | //app.UseFacebookAuthentication( 32 | // appId: "", 33 | // appSecret: ""); 34 | 35 | //app.UseGoogleAuthentication(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Ollert/DAL/RepositoryFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Ollert.DAL 5 | { 6 | public class RepositoryFactory : IDisposable 7 | { 8 | private OllertDbContext _context; 9 | public OllertDbContext Context 10 | { 11 | get 12 | { 13 | if (_context == null) 14 | _context = new OllertDbContext(); 15 | 16 | return _context; 17 | } 18 | } 19 | 20 | //private AccountRepository _AccountRepository; 21 | //public AccountRepository AccountRepository 22 | //{ 23 | // get 24 | // { 25 | // if (_AccountRepository == null) 26 | // _AccountRepository = new AccountRepository(this.Context); 27 | // return _AccountRepository; 28 | // } 29 | //} 30 | 31 | 32 | public async Task SaveAsync() 33 | { 34 | await Context.SaveChangesAsync(); 35 | } 36 | 37 | private bool disposed = false; 38 | 39 | protected virtual void Dispose(bool disposing) 40 | { 41 | if (!this.disposed) 42 | { 43 | if (disposing) 44 | { 45 | Context.Dispose(); 46 | } 47 | } 48 | this.disposed = true; 49 | } 50 | 51 | public void Dispose() 52 | { 53 | Dispose(true); 54 | GC.SuppressFinalize(this); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Ollert/Models/OllertUser.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Identity.EntityFramework; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Ollert.Models 7 | { 8 | [DataContract] 9 | // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. 10 | public class OllertUser : IdentityUser 11 | { 12 | public OllertUser() 13 | { 14 | this.Messages = new List(); 15 | } 16 | 17 | [DataMember] 18 | public override string Id { get; set; } 19 | [DataMember] 20 | public override string UserName { get; set; } 21 | public byte[] Avatar { get; set; } 22 | [DataMember] 23 | public Nullable LastViewed { get; set; } 24 | public override string Email { get; set; } 25 | [DataMember] 26 | public string EmailMd5 27 | { 28 | get 29 | { 30 | if(!string.IsNullOrWhiteSpace(this.Email)) 31 | { 32 | return this.Email.Trim().ToLower().Md5(); 33 | } 34 | 35 | return string.Empty; 36 | 37 | } 38 | } 39 | [DataMember] 40 | public bool UseGravatar { get; set; } 41 | 42 | 43 | public virtual ICollection Messages { get; set; } 44 | 45 | public ICollection Participants { get; set; } 46 | } 47 | } -------------------------------------------------------------------------------- /Ollert/Content/themes/base/resizable.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Resizable 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | */ 9 | .ui-resizable { 10 | position: relative; 11 | } 12 | .ui-resizable-handle { 13 | position: absolute; 14 | font-size: 0.1px; 15 | display: block; 16 | -ms-touch-action: none; 17 | touch-action: none; 18 | } 19 | .ui-resizable-disabled .ui-resizable-handle, 20 | .ui-resizable-autohide .ui-resizable-handle { 21 | display: none; 22 | } 23 | .ui-resizable-n { 24 | cursor: n-resize; 25 | height: 7px; 26 | width: 100%; 27 | top: -5px; 28 | left: 0; 29 | } 30 | .ui-resizable-s { 31 | cursor: s-resize; 32 | height: 7px; 33 | width: 100%; 34 | bottom: -5px; 35 | left: 0; 36 | } 37 | .ui-resizable-e { 38 | cursor: e-resize; 39 | width: 7px; 40 | right: -5px; 41 | top: 0; 42 | height: 100%; 43 | } 44 | .ui-resizable-w { 45 | cursor: w-resize; 46 | width: 7px; 47 | left: -5px; 48 | top: 0; 49 | height: 100%; 50 | } 51 | .ui-resizable-se { 52 | cursor: se-resize; 53 | width: 12px; 54 | height: 12px; 55 | right: 1px; 56 | bottom: 1px; 57 | } 58 | .ui-resizable-sw { 59 | cursor: sw-resize; 60 | width: 9px; 61 | height: 9px; 62 | left: -5px; 63 | bottom: -5px; 64 | } 65 | .ui-resizable-nw { 66 | cursor: nw-resize; 67 | width: 9px; 68 | height: 9px; 69 | left: -5px; 70 | top: -5px; 71 | } 72 | .ui-resizable-ne { 73 | cursor: ne-resize; 74 | width: 9px; 75 | height: 9px; 76 | right: -5px; 77 | top: -5px; 78 | } 79 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/dialog.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Dialog 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/dialog/#theming 10 | */ 11 | .ui-dialog { 12 | overflow: hidden; 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | padding: .2em; 17 | outline: 0; 18 | } 19 | .ui-dialog .ui-dialog-titlebar { 20 | padding: .4em 1em; 21 | position: relative; 22 | } 23 | .ui-dialog .ui-dialog-title { 24 | float: left; 25 | margin: .1em 0; 26 | white-space: nowrap; 27 | width: 90%; 28 | overflow: hidden; 29 | text-overflow: ellipsis; 30 | } 31 | .ui-dialog .ui-dialog-titlebar-close { 32 | position: absolute; 33 | right: .3em; 34 | top: 50%; 35 | width: 20px; 36 | margin: -10px 0 0 0; 37 | padding: 1px; 38 | height: 20px; 39 | } 40 | .ui-dialog .ui-dialog-content { 41 | position: relative; 42 | border: 0; 43 | padding: .5em 1em; 44 | background: none; 45 | overflow: auto; 46 | } 47 | .ui-dialog .ui-dialog-buttonpane { 48 | text-align: left; 49 | border-width: 1px 0 0 0; 50 | background-image: none; 51 | margin-top: .5em; 52 | padding: .3em 1em .5em .4em; 53 | } 54 | .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { 55 | float: right; 56 | } 57 | .ui-dialog .ui-dialog-buttonpane button { 58 | margin: .5em .4em .5em 0; 59 | cursor: pointer; 60 | } 61 | .ui-dialog .ui-resizable-se { 62 | width: 12px; 63 | height: 12px; 64 | right: -5px; 65 | bottom: -5px; 66 | background-position: 16px 16px; 67 | } 68 | .ui-draggable .ui-dialog-titlebar { 69 | cursor: move; 70 | } 71 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/BoardsList.js: -------------------------------------------------------------------------------- 1 | var BoardsList = (function () { 2 | function BoardsList(boards, currentUser, users) { 3 | var self = this; 4 | this.boards = ko.observableArray(boards); 5 | this.currentUser = currentUser; 6 | this.users = users; 7 | this.dialogNewBoard = ko.observable(new BoardDetails(-1, '', null, self.currentUser, self.users, 0, 0, 0)); 8 | // Methods 9 | this.modalAddSalle = function () { 10 | $('#modal-ajout').modal('show'); 11 | }; 12 | this.addSalle = function () { 13 | OllertApi.addBoard(self.dialogNewBoard(), self.currentUser, function (jsonData) { 14 | // AJAX CALLBACK 15 | self.dialogNewBoard().id = jsonData.Id; 16 | self.boards.push(self.dialogNewBoard()); 17 | self.dialogNewBoard(new BoardDetails(-1, '', null, self.currentUser, self.users, 0, 0, 0)); 18 | }); 19 | $('#modal-ajout').modal('hide'); 20 | }; 21 | this.deleteSalle = function (data) { 22 | OllertApi.deleteBoard(data.id, function () { 23 | // AJAX CALLBACK 24 | var indexSalle = -1; 25 | $.each(self.boards(), function (index, salle) { 26 | if (salle.id == data.id) 27 | indexSalle = index; 28 | }); 29 | if (indexSalle >= 0) 30 | self.boards.splice(indexSalle, 1); 31 | }); 32 | return false; 33 | }; 34 | } 35 | return BoardsList; 36 | })(); 37 | //# sourceMappingURL=BoardsList.js.map -------------------------------------------------------------------------------- /Ollert/Content/themes/base/slider.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Slider 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/slider/#theming 10 | */ 11 | .ui-slider { 12 | position: relative; 13 | text-align: left; 14 | } 15 | .ui-slider .ui-slider-handle { 16 | position: absolute; 17 | z-index: 2; 18 | width: 1.2em; 19 | height: 1.2em; 20 | cursor: default; 21 | -ms-touch-action: none; 22 | touch-action: none; 23 | } 24 | .ui-slider .ui-slider-range { 25 | position: absolute; 26 | z-index: 1; 27 | font-size: .7em; 28 | display: block; 29 | border: 0; 30 | background-position: 0 0; 31 | } 32 | 33 | /* support: IE8 - See #6727 */ 34 | .ui-slider.ui-state-disabled .ui-slider-handle, 35 | .ui-slider.ui-state-disabled .ui-slider-range { 36 | filter: inherit; 37 | } 38 | 39 | .ui-slider-horizontal { 40 | height: .8em; 41 | } 42 | .ui-slider-horizontal .ui-slider-handle { 43 | top: -.3em; 44 | margin-left: -.6em; 45 | } 46 | .ui-slider-horizontal .ui-slider-range { 47 | top: 0; 48 | height: 100%; 49 | } 50 | .ui-slider-horizontal .ui-slider-range-min { 51 | left: 0; 52 | } 53 | .ui-slider-horizontal .ui-slider-range-max { 54 | right: 0; 55 | } 56 | 57 | .ui-slider-vertical { 58 | width: .8em; 59 | height: 100px; 60 | } 61 | .ui-slider-vertical .ui-slider-handle { 62 | left: -.3em; 63 | margin-left: 0; 64 | margin-bottom: -.6em; 65 | } 66 | .ui-slider-vertical .ui-slider-range { 67 | left: 0; 68 | width: 100%; 69 | } 70 | .ui-slider-vertical .ui-slider-range-min { 71 | bottom: 0; 72 | } 73 | .ui-slider-vertical .ui-slider-range-max { 74 | top: 0; 75 | } 76 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/extensions.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | if (typeof Object.defineProperty === 'function') { 3 | try { Object.defineProperty(Array.prototype, 'sortBy', { value: sb }); } catch (e) { } 4 | } 5 | if (!Array.prototype.sortBy) Array.prototype.sortBy = sb; 6 | 7 | function sb(f) { 8 | for (var i = this.length; i;) { 9 | var o = this[--i]; 10 | this[i] = [].concat(f.call(o, o, i), o); 11 | } 12 | this.sort(function (a, b) { 13 | for (var i = 0, len = a.length; i < len; ++i) { 14 | if (a[i] != b[i]) return a[i] > b[i] ? -1 : 1; 15 | } 16 | return 0; 17 | }); 18 | for (var i = this.length; i;) { 19 | this[--i] = this[i][this[i].length - 1]; 20 | } 21 | return this; 22 | } 23 | 24 | var $loading = $('#global-spinner').hide(); 25 | $(document) 26 | .ajaxStart(function () { 27 | $loading.show(); 28 | }) 29 | .ajaxStop(function () { 30 | $loading.hide(); 31 | }); 32 | })(); 33 | 34 | function arrayCompare(a1, a2) { 35 | if (a1.length != a2.length) return false; 36 | var length = a2.length; 37 | for (var i = 0; i < length; i++) { 38 | if (a1[i] !== a2[i]) return false; 39 | } 40 | return true; 41 | } 42 | 43 | function inArray(needle, haystack) { 44 | var length = haystack.length; 45 | for (var i = 0; i < length; i++) { 46 | if (typeof haystack[i] == 'object') { 47 | if (arrayCompare(haystack[i], needle)) return true; 48 | } else { 49 | if (haystack[i] == needle) return true; 50 | } 51 | } 52 | return false; 53 | } -------------------------------------------------------------------------------- /Ollert/Views/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/BoardsList.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"BoardsList.js","sourceRoot":"","sources":["BoardsList.ts"],"names":["BoardsList","BoardsList.constructor"],"mappings":"AAAA,IAAM,UAAU;IAYZA,SAZEA,UAAUA,CAYAA,MAA2BA,EAAEA,WAAiBA,EAAEA,KAAkBA;QAC1EC,IAAIA,IAAIA,GAAGA,IAAIA,CAACA;QAEhBA,IAAIA,CAACA,MAAMA,GAAGA,EAAEA,CAACA,eAAeA,CAACA,MAAMA,CAACA,CAACA;QACzCA,IAAIA,CAACA,WAAWA,GAAGA,WAAWA,CAACA;QAC/BA,IAAIA,CAACA,KAAKA,GAAGA,KAAKA,CAACA;QAEnBA,IAAIA,CAACA,cAAcA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,IAAIA,YAAYA,CAACA,CAACA,CAACA,EAAEA,EAAEA,EAAEA,IAAIA,EAAEA,IAAIA,CAACA,WAAWA,EAAEA,IAAIA,CAACA,KAAKA,EAAEA,CAACA,EAAEA,CAACA,EAAEA,CAACA,CAACA,CAACA,CAACA;QAG3GA,AADAA,UAAUA;QACVA,IAAIA,CAACA,aAAaA,GAAGA;YACjBA,CAACA,CAACA,cAAcA,CAACA,CAACA,KAAKA,CAACA,MAAMA,CAACA,CAACA;QACpCA,CAACA,CAAAA;QACDA,IAAIA,CAACA,QAAQA,GAAGA;YACZA,SAASA,CAACA,QAAQA,CAACA,IAAIA,CAACA,cAAcA,EAAEA,EAAEA,IAAIA,CAACA,WAAWA,EAAEA,UAAUA,QAAQA;gBAE1E,AADA,gBAAgB;gBAChB,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;gBACvC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;gBACxC,IAAI,CAAC,cAAc,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/F,CAAC,CAACA,CAACA;YACHA,CAACA,CAACA,cAAcA,CAACA,CAACA,KAAKA,CAACA,MAAMA,CAACA,CAACA;QACpCA,CAACA,CAAAA;QACDA,IAAIA,CAACA,WAAWA,GAAGA,UAACA,IAAkBA;YAClCA,SAASA,CAACA,WAAWA,CAACA,IAAIA,CAACA,EAAEA,EAAEA;gBAE3B,AADA,gBAAgB;oBACZ,UAAU,GAAG,CAAC,CAAC,CAAC;gBACpB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,KAAK,EAAE,KAAK;oBACxC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;wBACpB,UAAU,GAAG,KAAK,CAAC;gBAC3B,CAAC,CAAC,CAAC;gBACH,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;oBAChB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAC1C,CAAC,CAACA,CAACA;YACHA,MAAMA,CAACA,KAAKA,CAACA;QACjBA,CAACA,CAAAA;IACLA,CAACA;IACLD,iBAACA;AAADA,CAACA,AAhDD,IAgDC"} -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Step.js: -------------------------------------------------------------------------------- 1 | var Step = (function () { 2 | function Step(id, title, estimation, isDone) { 3 | var _this = this; 4 | this.id = id; 5 | this.title = ko.observable(title); 6 | this.estimation = ko.observable(estimation); 7 | this.isDone = ko.observable(isDone); 8 | // Computed 9 | this.listCss = ko.computed(function () { 10 | return this.isDone() ? 'item-green selected' : 'item-pink'; 11 | }, this); 12 | // Methods 13 | this.toggleDone = function () { 14 | if (_this.isDone()) 15 | _this.isDone(false); 16 | else 17 | _this.isDone(true); 18 | _this.editStep(); 19 | }; 20 | this.toggleInputDone = function () { 21 | _this.editStep(); 22 | return true; 23 | }; 24 | this.toReadableTime = function () { 25 | var seconds = _this.estimation(); 26 | var numyears = Math.floor(seconds / 31536000); 27 | var numdays = Math.floor((seconds % 31536000) / 86400); 28 | var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600); 29 | var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); 30 | var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60; 31 | var output = (numyears > 0 ? numyears + " y " : '') + (numdays > 0 ? numdays + " d" : '') + (numhours > 0 ? numhours + " h" : '') + (numminutes > 0 ? numminutes + " m" : '') + (numseconds > 0 ? numseconds + " s" : ''); 32 | return output.length == 0 ? '' : output; 33 | }; 34 | // SAUVEGARDE SERVEUR 35 | this.editStep = function () { 36 | OllertApi.updateStep(_this, -1); 37 | }; 38 | } 39 | return Step; 40 | })(); 41 | //# sourceMappingURL=Step.js.map -------------------------------------------------------------------------------- /Ollert/Views/Shared/_LayoutPublic.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | Connexion - Ollert 22 | 23 | @Styles.Render("~/css/bootstrap") 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | @RenderBody() 32 |
33 | 35 | @Scripts.Render("~/bundles/jquery") 36 | @Scripts.Render("~/bundles/bootstrap") 37 | @RenderSection("scripts", required: false) 38 | 39 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/core.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | */ 11 | 12 | /* Layout helpers 13 | ----------------------------------*/ 14 | .ui-helper-hidden { 15 | display: none; 16 | } 17 | .ui-helper-hidden-accessible { 18 | border: 0; 19 | clip: rect(0 0 0 0); 20 | height: 1px; 21 | margin: -1px; 22 | overflow: hidden; 23 | padding: 0; 24 | position: absolute; 25 | width: 1px; 26 | } 27 | .ui-helper-reset { 28 | margin: 0; 29 | padding: 0; 30 | border: 0; 31 | outline: 0; 32 | line-height: 1.3; 33 | text-decoration: none; 34 | font-size: 100%; 35 | list-style: none; 36 | } 37 | .ui-helper-clearfix:before, 38 | .ui-helper-clearfix:after { 39 | content: ""; 40 | display: table; 41 | border-collapse: collapse; 42 | } 43 | .ui-helper-clearfix:after { 44 | clear: both; 45 | } 46 | .ui-helper-clearfix { 47 | min-height: 0; /* support: IE7 */ 48 | } 49 | .ui-helper-zfix { 50 | width: 100%; 51 | height: 100%; 52 | top: 0; 53 | left: 0; 54 | position: absolute; 55 | opacity: 0; 56 | filter:Alpha(Opacity=0); /* support: IE8 */ 57 | } 58 | 59 | .ui-front { 60 | z-index: 100; 61 | } 62 | 63 | 64 | /* Interaction Cues 65 | ----------------------------------*/ 66 | .ui-state-disabled { 67 | cursor: default !important; 68 | } 69 | 70 | 71 | /* Icons 72 | ----------------------------------*/ 73 | 74 | /* states and images */ 75 | .ui-icon { 76 | display: block; 77 | text-indent: -99999px; 78 | overflow: hidden; 79 | background-repeat: no-repeat; 80 | } 81 | 82 | 83 | /* Misc visuals 84 | ----------------------------------*/ 85 | 86 | /* Overlays */ 87 | .ui-widget-overlay { 88 | position: fixed; 89 | top: 0; 90 | left: 0; 91 | width: 100%; 92 | height: 100%; 93 | } 94 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/BoardsList.ts: -------------------------------------------------------------------------------- 1 | class BoardsList { 2 | boards: KnockoutObservableArray; 3 | currentUser: User; 4 | users: Array; 5 | 6 | dialogNewBoard: KnockoutObservable; 7 | 8 | // Method 9 | modalAddSalle: () => void; 10 | addSalle: () => void; 11 | deleteSalle: (data: BoardDetails) => boolean; 12 | 13 | constructor(boards: Array, currentUser: User, users: Array) { 14 | var self = this; 15 | 16 | this.boards = ko.observableArray(boards); 17 | this.currentUser = currentUser; 18 | this.users = users; 19 | 20 | this.dialogNewBoard = ko.observable(new BoardDetails(-1, '', null, self.currentUser, self.users, 0, 0, 0)); 21 | 22 | // Methods 23 | this.modalAddSalle = () => { 24 | $('#modal-ajout').modal('show'); 25 | } 26 | this.addSalle = () => { 27 | OllertApi.addBoard(self.dialogNewBoard(), self.currentUser, function (jsonData) { 28 | // AJAX CALLBACK 29 | self.dialogNewBoard().id = jsonData.Id; 30 | self.boards.push(self.dialogNewBoard()); 31 | self.dialogNewBoard(new BoardDetails(-1, '', null, self.currentUser, self.users, 0, 0, 0)); 32 | }); 33 | $('#modal-ajout').modal('hide'); 34 | } 35 | this.deleteSalle = (data: BoardDetails) => { 36 | OllertApi.deleteBoard(data.id, function () { 37 | // AJAX CALLBACK 38 | var indexSalle = -1; 39 | $.each(self.boards(), function (index, salle) { 40 | if (salle.id == data.id) 41 | indexSalle = index; 42 | }); 43 | if (indexSalle >= 0) 44 | self.boards.splice(indexSalle, 1); 45 | }); 46 | return false; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Ollert.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ollert", "Ollert\Ollert.csproj", "{845DE619-06B3-4299-B978-3C6DD2006392}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ollert.Tests", "Ollert.Tests\Ollert.Tests.csproj", "{7C99E4FD-5DE0-49FC-87E3-AFE7BBC97860}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{EF0A59CE-C095-4F92-8773-8FF463ADB5FD}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{848242DA-3488-442F-80EF-76E964BB7F66}" 13 | ProjectSection(SolutionItems) = preProject 14 | docs\TypeScript Language Specification.pdf = docs\TypeScript Language Specification.pdf 15 | EndProjectSection 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Any CPU = Debug|Any CPU 20 | Release|Any CPU = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {845DE619-06B3-4299-B978-3C6DD2006392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {845DE619-06B3-4299-B978-3C6DD2006392}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {845DE619-06B3-4299-B978-3C6DD2006392}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {845DE619-06B3-4299-B978-3C6DD2006392}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {7C99E4FD-5DE0-49FC-87E3-AFE7BBC97860}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {7C99E4FD-5DE0-49FC-87E3-AFE7BBC97860}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {7C99E4FD-5DE0-49FC-87E3-AFE7BBC97860}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {7C99E4FD-5DE0-49FC-87E3-AFE7BBC97860}.Release|Any CPU.Build.0 = Release|Any CPU 31 | EndGlobalSection 32 | GlobalSection(SolutionProperties) = preSolution 33 | HideSolutionNode = FALSE 34 | EndGlobalSection 35 | EndGlobal 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.log 36 | *.vspscc 37 | *.vssscc 38 | .builds 39 | 40 | # Visual C++ cache files 41 | ipch/ 42 | *.aps 43 | *.ncb 44 | *.opensdf 45 | *.sdf 46 | 47 | # Visual Studio profiler 48 | *.psess 49 | *.vsp 50 | *.vspx 51 | 52 | # Guidance Automation Toolkit 53 | *.gpState 54 | 55 | # ReSharper is a .NET coding add-in 56 | _ReSharper* 57 | 58 | # NCrunch 59 | *.ncrunch* 60 | .*crunch*.local.xml 61 | 62 | # Installshield output folder 63 | [Ee]xpress 64 | 65 | # DocProject is a documentation generator add-in 66 | DocProject/buildhelp/ 67 | DocProject/Help/*.HxT 68 | DocProject/Help/*.HxC 69 | DocProject/Help/*.hhc 70 | DocProject/Help/*.hhk 71 | DocProject/Help/*.hhp 72 | DocProject/Help/Html2 73 | DocProject/Help/html 74 | 75 | # Click-Once directory 76 | publish 77 | 78 | # Publish Web Output 79 | *.Publish.xml 80 | 81 | # NuGet Packages Directory 82 | packages 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | *.mdf 110 | *.ldf 111 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Step.ts: -------------------------------------------------------------------------------- 1 | class Step { 2 | id: number; 3 | title: KnockoutObservable; 4 | estimation: KnockoutObservable; 5 | isDone: KnockoutObservable; 6 | 7 | listCss: KnockoutComputed; 8 | 9 | // Methods 10 | toggleDone: () => void; 11 | toggleInputDone: () => void; 12 | toReadableTime: () => string; 13 | editStep: () => void; 14 | 15 | constructor(id: number, title: string, estimation: number, isDone: boolean) { 16 | this.id = id; 17 | this.title = ko.observable(title); 18 | this.estimation = ko.observable(estimation); 19 | this.isDone = ko.observable(isDone); 20 | 21 | // Computed 22 | this.listCss = ko.computed(function () { 23 | return this.isDone() ? 'item-green selected' : 'item-pink'; 24 | }, this); 25 | 26 | // Methods 27 | this.toggleDone = () => { 28 | if (this.isDone()) 29 | this.isDone(false); 30 | else 31 | this.isDone(true); 32 | 33 | this.editStep(); 34 | } 35 | 36 | this.toggleInputDone = () => { 37 | this.editStep(); 38 | return true; 39 | } 40 | 41 | this.toReadableTime = () => { 42 | var seconds = this.estimation(); 43 | var numyears = Math.floor(seconds / 31536000); 44 | var numdays = Math.floor((seconds % 31536000) / 86400); 45 | var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600); 46 | var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); 47 | var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60; 48 | var output = (numyears > 0 ? numyears + " y " : '') + (numdays > 0 ? numdays + " d" : '') + (numhours > 0 ? numhours + " h" : '') + (numminutes > 0 ? numminutes + " m" : '') + (numseconds > 0 ? numseconds + " s" : ''); 49 | return output.length == 0 ? '' : output; 50 | } 51 | 52 | // SAUVEGARDE SERVEUR 53 | this.editStep = () => { 54 | OllertApi.updateStep(this, -1); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Ollert/Properties/PublishProfiles/ServerspamWebDeploy.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | MSDeploy 9 | Release 10 | Any CPU 11 | http://ollert.web-alliance.fr 12 | True 13 | False 14 | https://SERVERSPAM:8172/msdeploy.axd 15 | Ollert 16 | 17 | True 18 | WMSVC 19 | True 20 | Administrateur 21 | <_SavePWD>False 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Data Source=localhost;Initial Catalog=Ollert;User ID=sa;Password=Nh4ib4bb 36 | 37 | 38 | -------------------------------------------------------------------------------- /Ollert/Models/AccountViewModels.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Ollert.Models 4 | { 5 | public class ExternalLoginConfirmationViewModel 6 | { 7 | [Required] 8 | [Display(Name = "User name")] 9 | public string UserName { get; set; } 10 | } 11 | 12 | public class ManageUserViewModel 13 | { 14 | [Required] 15 | [DataType(DataType.Password)] 16 | [Display(Name = "Current password")] 17 | public string OldPassword { get; set; } 18 | 19 | [Required] 20 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 21 | [DataType(DataType.Password)] 22 | [Display(Name = "New password")] 23 | public string NewPassword { get; set; } 24 | 25 | [DataType(DataType.Password)] 26 | [Display(Name = "Confirm new password")] 27 | [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 28 | public string ConfirmPassword { get; set; } 29 | } 30 | 31 | public class LoginViewModel 32 | { 33 | [Required] 34 | [Display(Name = "User name")] 35 | public string UserName { get; set; } 36 | 37 | [Required] 38 | [DataType(DataType.Password)] 39 | [Display(Name = "Password")] 40 | public string Password { get; set; } 41 | 42 | [Display(Name = "Remember me?")] 43 | public bool RememberMe { get; set; } 44 | } 45 | 46 | public class RegisterViewModel 47 | { 48 | [Required] 49 | [Display(Name = "User name")] 50 | public string UserName { get; set; } 51 | 52 | [Required] 53 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 54 | [DataType(DataType.Password)] 55 | [Display(Name = "Password")] 56 | public string Password { get; set; } 57 | 58 | [DataType(DataType.Password)] 59 | [Display(Name = "Confirm password")] 60 | [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 61 | public string ConfirmPassword { get; set; } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Ollert/Views/Board/Salle/_MessagesList.cshtml: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 | User Avatar 8 |
9 | 10 |
11 |
12 | 13 | 14 |
15 | 16 |
17 | 18 |
19 |
20 | 21 |
22 | 23 | 24 | 25 |
26 |
27 |
28 |
29 | 30 |
31 |
32 |
33 | 34 | 35 | 39 | 40 |
41 |
42 |
43 |
44 |
45 |
-------------------------------------------------------------------------------- /Ollert/Views/Board/Salle.cshtml: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | @Html.Hidden("SalleId", (int)ViewBag.SalleId) 15 | 16 | @Html.Partial("Salle/_Tables") 17 | 18 | 19 | @Html.Partial("Salle/_AddCardModal") 20 | @Html.Partial("Salle/_AddTableModal") 21 | 22 | 23 | @Html.Partial("Salle/_EditCardModal") 24 | 25 |
26 |
27 | 28 |
29 |
30 | 31 | 32 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
33 | 37 | Display Archive
  Add board
45 |
46 |
47 |
48 | 49 | @section Scripts { 50 | 62 | } -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/Step.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Step.js","sourceRoot":"","sources":["Step.ts"],"names":["Step","Step.constructor"],"mappings":"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"} -------------------------------------------------------------------------------- /Ollert/Views/Board/Salle/_AddCardModal.cshtml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Ollert/DAL/OllertDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Identity.EntityFramework; 2 | using Ollert.Migrations; 3 | using Ollert.Models; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Data.Entity; 7 | using System.Data.Entity.ModelConfiguration.Conventions; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace Ollert.DAL 13 | { 14 | public class OllertDbContext : IdentityDbContext 15 | { 16 | public DbSet Cartes { get; set; } 17 | public DbSet Fichiers { get; set; } 18 | public DbSet Messages { get; set; } 19 | public DbSet Notifications { get; set; } 20 | public DbSet Tableaux { get; set; } 21 | public DbSet CartesVues { get; set; } 22 | public DbSet Salles { get; set; } 23 | public DbSet ParticipantsSalles { get; set; } 24 | 25 | public OllertDbContext() : base("DefaultConnection") 26 | { 27 | this.Configuration.ProxyCreationEnabled = false; 28 | } 29 | 30 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 31 | { 32 | //modelBuilder.Conventions.Remove(); 33 | 34 | //modelBuilder.Entity() 35 | // .HasMany(c => c.Instructors).WithMany(i => i.Courses) 36 | // .Map(t => t.MapLeftKey("CourseID") 37 | // .MapRightKey("InstructorID") 38 | // .ToTable("CourseInstructor")); 39 | //var conv = new OneToManyCascadeDeleteConvention(); 40 | //conv.Apply(System.Data.Entity.Core.Metadata.Edm.AssociationType.Create()) 41 | 42 | 43 | //modelBuilder.Entity().HasMany(a => a.Fichiers).WithRequired().WillCascadeOnDelete(true); 44 | //modelBuilder.Entity().HasMany(a => a.Messages).WithRequired().WillCascadeOnDelete(true); 45 | //modelBuilder.Entity().HasMany(a => a.CartesVues).WithRequired().WillCascadeOnDelete(true); 46 | 47 | base.OnModelCreating(modelBuilder); 48 | //System.Data.Entity.Database.SetInitializer(new MigrateDatabaseToLatestVersion()); 49 | } 50 | 51 | public System.Data.Entity.DbSet CarteEtapes { get; set; } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Ollert/Models/Salle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Text; 8 | using Microsoft.AspNet.Identity; 9 | using Microsoft.AspNet.Identity.EntityFramework; 10 | using Ollert.DAL; 11 | using System.Web; 12 | using Newtonsoft.Json; 13 | 14 | namespace Ollert.Models 15 | { 16 | public class Salle : Ollert.Models.IEntity 17 | { 18 | public Salle() 19 | { 20 | this.Tableaux = new List(); 21 | this.ParticipantsSalle = new List(); 22 | } 23 | 24 | [Key] 25 | public int Id { get; set; } 26 | public string Nom { get; set; } 27 | [JsonIgnore] 28 | public virtual ICollection Tableaux { get; set; } 29 | [Required] 30 | public virtual OllertUser Proprietaire { get; set; } 31 | [JsonIgnore] 32 | public ICollection ParticipantsSalle { get; set; } 33 | 34 | 35 | [NotMapped] 36 | public ICollection Participants 37 | { 38 | get 39 | { 40 | return this.ParticipantsSalle.Select(p => p.Participant).ToList(); 41 | } 42 | } 43 | [NotMapped] 44 | public int MessageNonLu 45 | { 46 | get 47 | { 48 | return this.Tableaux.Sum(t => t.Cartes.Sum(c => c.Messages.Count(m => c.LastTimeViewed < m.CreateOn))); 49 | } 50 | } 51 | [NotMapped] 52 | public int TempsRestant 53 | { 54 | get 55 | { 56 | return this.Tableaux.Sum(t => t.Cartes.Sum(c => c.Etapes.Where(e => !e.Terminee).Sum(e => e.Estimation))); 57 | } 58 | } 59 | [NotMapped] 60 | public int FichierNonVu 61 | { 62 | get 63 | { 64 | return this.Tableaux.Sum(t => t.Cartes.Sum(c => c.Fichiers.Count(m => c.LastTimeViewed < m.DateEnvoi))); 65 | } 66 | } 67 | //[NotMapped] 68 | //public int EvenementsNonVu 69 | //{ 70 | // get 71 | // { 72 | // return this.Cartes.Sum(c => c.Fichiers.Count(m => c.LastTimeViewed < m.DateEnvoi)); 73 | // } 74 | //} 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Ollert/Views/Board/Salle/_Steps.cshtml: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | 7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 |
15 |
16 | 20 |
21 |
22 |
23 | 24 | 25 | 26 |
27 |
28 | -------------------------------------------------------------------------------- /Ollert/Content/jquery.gritter.css: -------------------------------------------------------------------------------- 1 | /* the norm */ 2 | #gritter-notice-wrapper { 3 | position:fixed; 4 | top:20px; 5 | right:20px; 6 | width:301px; 7 | z-index:9999; 8 | } 9 | #gritter-notice-wrapper.top-left { 10 | left: 20px; 11 | right: auto; 12 | } 13 | #gritter-notice-wrapper.bottom-right { 14 | top: auto; 15 | left: auto; 16 | bottom: 20px; 17 | right: 20px; 18 | } 19 | #gritter-notice-wrapper.bottom-left { 20 | top: auto; 21 | right: auto; 22 | bottom: 20px; 23 | left: 20px; 24 | } 25 | .gritter-item-wrapper { 26 | position:relative; 27 | margin:0 0 10px 0; 28 | background:url('img/ie-spacer.gif'); /* ie7/8 fix */ 29 | } 30 | .gritter-top { 31 | background:url(img/gritter.png) no-repeat left -30px; 32 | height:10px; 33 | } 34 | .hover .gritter-top { 35 | background-position:right -30px; 36 | } 37 | .gritter-bottom { 38 | background:url(img/gritter.png) no-repeat left bottom; 39 | height:8px; 40 | margin:0; 41 | } 42 | .hover .gritter-bottom { 43 | background-position: bottom right; 44 | } 45 | .gritter-item { 46 | display:block; 47 | background:url(img/gritter.png) no-repeat left -40px; 48 | color:#eee; 49 | padding:2px 11px 8px 11px; 50 | font-size: 11px; 51 | font-family:verdana; 52 | } 53 | .hover .gritter-item { 54 | background-position:right -40px; 55 | } 56 | .gritter-item p { 57 | padding:0; 58 | margin:0; 59 | word-wrap:break-word; 60 | } 61 | .gritter-close { 62 | display:none; 63 | position:absolute; 64 | top:5px; 65 | left:3px; 66 | background:url(img/gritter.png) no-repeat left top; 67 | cursor:pointer; 68 | width:30px; 69 | height:30px; 70 | } 71 | .gritter-title { 72 | font-size:14px; 73 | font-weight:bold; 74 | padding:0 0 7px 0; 75 | display:block; 76 | text-shadow:1px 1px 0 #000; /* Not supported by IE :( */ 77 | } 78 | .gritter-image { 79 | width:48px; 80 | height:48px; 81 | float:left; 82 | } 83 | .gritter-with-image, 84 | .gritter-without-image { 85 | padding:0; 86 | } 87 | .gritter-with-image { 88 | width:220px; 89 | float:right; 90 | } 91 | /* for the light (white) version of the gritter notice */ 92 | .gritter-light .gritter-item, 93 | .gritter-light .gritter-bottom, 94 | .gritter-light .gritter-top, 95 | .gritter-light .gritter-close { 96 | background-image: url(img/gritter-light.png); 97 | color: #222; 98 | } 99 | .gritter-light .gritter-title { 100 | text-shadow: none; 101 | } 102 | -------------------------------------------------------------------------------- /Ollert/Scripts/typings/knockout.mapping/knockout.mapping.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for Knockout.Mapping 2.0 2 | // Project: https://github.com/SteveSanderson/knockout.mapping 3 | // Definitions by: Boris Yankov 4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped 5 | 6 | /// 7 | 8 | interface KnockoutMappingCreateOptions { 9 | data: any; 10 | parent: any; 11 | } 12 | 13 | interface KnockoutMappingUpdateOptions { 14 | data: any; 15 | parent: any; 16 | observable: KnockoutObservable; 17 | } 18 | 19 | interface KnockoutMappingOptions { 20 | ignore?: string[]; 21 | include?: string[]; 22 | copy?: string[]; 23 | mappedProperties?: string[]; 24 | deferEvaluation?: boolean; 25 | create?: (options: KnockoutMappingCreateOptions) => void; 26 | update?: (options: KnockoutMappingUpdateOptions) => void; 27 | key?: (data: any) => any; 28 | } 29 | 30 | interface KnockoutMapping { 31 | isMapped(viewModel: any): boolean; 32 | fromJS(jsObject: any): any; 33 | fromJS(jsObject: any, targetOrOptions: any): any; 34 | fromJS(jsObject: any, inputOptions: any, target: any): any; 35 | fromJSON(jsonString: string): any; 36 | fromJSON(jsonString: string, targetOrOptions: any): any; 37 | fromJSON(jsonString: string, inputOptions: any, target: any): any; 38 | toJS(rootObject: any, options?: KnockoutMappingOptions): any; 39 | toJSON(rootObject: any, options?: KnockoutMappingOptions): any; 40 | defaultOptions(): KnockoutMappingOptions; 41 | resetDefaultOptions(): void; 42 | getType(x: any): any; 43 | visitModel(rootObject: any, callback: Function, options?: { visitedObjects?: any; parentName?: string; ignore?: string[]; copy?: string[]; include?: string[]; }): any; 44 | } 45 | 46 | interface KnockoutObservableArrayFunctions { 47 | mappedCreate(item: T): T; 48 | 49 | mappedRemove(item: T): T[]; 50 | mappedRemove(removeFunction: (item: T) => boolean): T[]; 51 | mappedRemoveAll(items: T[]): T[]; 52 | mappedRemoveAll(): T[]; 53 | 54 | mappedDestroy(item: T): void; 55 | mappedDestroy(destroyFunction: (item: T) => boolean): void; 56 | mappedDestroyAll(items: T[]): void; 57 | mappedDestroyAll(): void; 58 | } 59 | 60 | interface KnockoutStatic { 61 | mapping: KnockoutMapping; 62 | } 63 | 64 | declare module "knockout.mapping" { 65 | export = mapping; 66 | } 67 | declare var mapping: KnockoutMapping; 68 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/List.js: -------------------------------------------------------------------------------- 1 | var List = (function () { 2 | function List(data) { 3 | var _this = this; 4 | var self = this; 5 | this.id = data.id; 6 | this.name = data.name; 7 | this.allCards = ko.observableArray(data.cards); 8 | this.boardId = data.boardId; 9 | this.parent = ko.observable(data.parent); 10 | this.cards = ko.observableArray(new Array()); 11 | this.allCards.id = data.id; 12 | this.cards.id = data.id; 13 | this.listCards = ko.computed(function () { 14 | var cartes = new Array(); 15 | if (self.parent() != null) { 16 | $.each(self.allCards(), function (index, card) { 17 | if (self.parent().displayArchive() && card.isArchive()) 18 | cartes.push(card); 19 | else if (!self.parent().displayArchive() && !card.isArchive()) 20 | cartes.push(card); 21 | }); 22 | } 23 | self.cards(cartes); 24 | //return cartes; 25 | }, self); 26 | this.hasCards = ko.computed(function () { 27 | return self.cards().length > 0; 28 | }, self); 29 | this.totalTime = ko.computed(function () { 30 | var total = 0; 31 | $.each(self.cards(), function (index, el) { 32 | total += el.estimation(); 33 | }); 34 | var seconds = total; 35 | var numyears = Math.floor(seconds / 31536000); 36 | var numdays = Math.floor((seconds % 31536000) / 86400); 37 | var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600); 38 | var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); 39 | var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60; 40 | return (numyears > 0 ? numyears + " y " : '') + (numdays > 0 ? numdays + " d" : '') + (numhours > 0 ? numhours + " h" : '') + (numminutes > 0 ? numminutes + " m" : '') + (numseconds > 0 ? numseconds + " s" : ''); 41 | }, self); 42 | // SERVER 43 | this.deleteCard = function (data, event) { 44 | var self = _this; 45 | event.stopImmediatePropagation(); 46 | OllertApi.deleteCard(data.id, function () { 47 | // AJAX CALLBACK 48 | self.cards.remove(data); 49 | }); 50 | return false; 51 | }; 52 | } 53 | return List; 54 | })(); 55 | //# sourceMappingURL=List.js.map -------------------------------------------------------------------------------- /Ollert/Tools/TypeScript/Microsoft.TypeScript.jsproj.targets: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | $([System.Globalization.CultureInfo]::CurrentUICulture.LCID) 18 | 19 | $([System.Globalization.CultureInfo]::CurrentUICulture.TwoLetterISOLanguageName) 20 | zh-Hant 21 | zh-Hans 22 | pt-BR 23 | 24 | 25 | 26 | 27 | true 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | Project;BrowseObject 37 | 38 | 39 | 40 | 41 | 42 | File;BrowseObject 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Ollert/Scripts/typings/dropzone/dropzone.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for Dropzone 3.7.1 2 | // Project: http://www.dropzonejs.com/ 3 | // Definitions: https://github.com/borisyankov/DefinitelyTyped 4 | 5 | /// 6 | 7 | interface DropzoneFile extends File { 8 | previewElement: HTMLElement; 9 | previewTemplate: HTMLElement; 10 | previewsContainer: HTMLElement; 11 | status: string; 12 | accepted: boolean; 13 | } 14 | 15 | interface DropzoneOptions { 16 | url?: string; 17 | method?: string; 18 | withCredentials?: boolean; 19 | parallelUploads?: number; 20 | maxFilesize?: number; 21 | paramName?: string; 22 | uploadMultiple?: boolean; 23 | headers?: any; 24 | addRemoveLinks?: boolean; 25 | previewsContainer?: string; 26 | clickable?: boolean; 27 | createImageThumbnails?: boolean; 28 | maxThumbnailFilesize?: number; 29 | thumbnailWidth?: number; 30 | thumbnailHeight?: number; 31 | maxFiles?: number; 32 | resize?: (file?: any) => any; 33 | init?: () => void; 34 | acceptedFiles?: string; 35 | accept?: (file: DropzoneFile, doneCallback: (...args) => void) => void; 36 | autoProcessQueue?: boolean; 37 | previewTemplate?: string; 38 | forceFallback?: boolean; 39 | fallback?: () => void; 40 | 41 | // dictionary options 42 | dictDefaultMessage?: string; 43 | dictFallbackMessage?: string; 44 | dictFallbackText?: string; 45 | dictInvalidFileType?: string; 46 | dictFileTooBig?: string; 47 | dictResponseError?: string; 48 | dictCancelUpload?: string; 49 | dictCancelUploadConfirmation?: string; 50 | dictRemoveFile?: string; 51 | dictRemoveFileConfirmation?: string; 52 | dictMaxFilesExceeded?: string; 53 | } 54 | 55 | declare class Dropzone { 56 | constructor(container: string, options?: DropzoneOptions); 57 | static autoDiscover: boolean; 58 | static options: any; 59 | static confirm: (question: string, accepted: () => void, rejected?: () => void) => void; 60 | 61 | files: DropzoneFile[]; 62 | 63 | on(eventName, callback: (...args) => any); 64 | off(eventName): void; 65 | 66 | emit(eventName, file:any, thumbUrl?: string): void; 67 | 68 | removeFile(file: DropzoneFile): void; 69 | removeAllFiles(): void; 70 | processQueue(): void; 71 | getAcceptedFiles(): DropzoneFile[]; 72 | getRejectedFiles(): DropzoneFile[]; 73 | getQueuedFiles(): DropzoneFile[]; 74 | getUploadingFiles(): DropzoneFile[]; 75 | } 76 | 77 | interface JQuery { 78 | dropzone(options: DropzoneOptions): Dropzone; 79 | } -------------------------------------------------------------------------------- /Ollert.Tests/App.config: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Ollert/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace Ollert 5 | { 6 | public class BundleConfig 7 | { 8 | public static void RegisterBundles(BundleCollection bundles) 9 | { 10 | // SCRIPTS 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.js")); 12 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include("~/Scripts/jquery.validate*")); 13 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include("~/Scripts/modernizr-*")); 14 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include("~/Scripts/bootstrap.js")); 15 | bundles.Add(new ScriptBundle("~/bundles/libraries").Include( 16 | "~/Scripts/knockout-{version}.js", 17 | "~/Scripts/jquery-ui-{version}.js", 18 | "~/Scripts/knockout-sortable.js", 19 | "~/Scripts/jquery.slimscroll.js", 20 | "~/Scripts/jquery.signalR-{version}.js", 21 | "~/Scripts/jquery.cookie.js", 22 | "~/Scripts/moment-with-locales.js", 23 | "~/Scripts/dropzone.js", 24 | "~/Scripts/jquery.gritter.js", 25 | "~/Scripts/respond.js", 26 | "~/Scripts/pages/extensions.js")); 27 | bundles.Add(new ScriptBundle("~/bundles/ollert-engine").Include( 28 | "~/Scripts/pages/Classes/Global.js", 29 | 30 | "~/Scripts/pages/Classes/Attachment.js", 31 | "~/Scripts/pages/Classes/Card.js", 32 | "~/Scripts/pages/Classes/List.js", 33 | "~/Scripts/pages/Classes/Message.js", 34 | "~/Scripts/pages/Classes/Notification.js", 35 | "~/Scripts/pages/Classes/Step.js", 36 | "~/Scripts/pages/Classes/User.js", 37 | "~/Scripts/pages/Classes/BoardDetails.js", 38 | 39 | "~/Scripts/pages/Classes/Converter.js", 40 | "~/Scripts/pages/Classes/OllertApi.js", 41 | "~/Scripts/pages/Classes/Ollert.js", 42 | 43 | "~/Scripts/pages/Classes/Layout.js", 44 | "~/Scripts/pages/Classes/Board.js", 45 | "~/Scripts/pages/Classes/BoardsList.js" 46 | )); 47 | 48 | // CSS 49 | bundles.Add(new StyleBundle("~/css/global").Include( 50 | "~/Content/site.css", 51 | "~/Content/font-awesome.css", 52 | "~/Content/dropzone.css", 53 | "~/Content/jquery.gritter.css", 54 | "~/Content/ace.css")); 55 | 56 | bundles.Add(new StyleBundle("~/css/bootstrap").Include("~/Content/bootstrap.css")); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/List.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"List.js","sourceRoot":"","sources":["List.ts"],"names":["List","List.constructor"],"mappings":"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"} -------------------------------------------------------------------------------- /Ollert/Scripts/typings/bootstrap/bootstrap.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for Bootstrap 2.2 2 | // Project: http://twitter.github.com/bootstrap/ 3 | // Definitions by: Boris Yankov 4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped 5 | 6 | 7 | /// 8 | 9 | interface ModalOptions { 10 | backdrop?: boolean; 11 | keyboard?: boolean; 12 | show?: boolean; 13 | remote?: string; 14 | } 15 | 16 | interface ModalOptionsBackdropString { 17 | backdrop?: string; // for "static" 18 | keyboard?: boolean; 19 | show?: boolean; 20 | remote?: string; 21 | } 22 | 23 | interface ScrollSpyOptions { 24 | offset?: number; 25 | } 26 | 27 | interface TooltipOptions { 28 | animation?: boolean; 29 | html?: boolean; 30 | placement?: any; 31 | selector?: string; 32 | title?: any; 33 | trigger?: string; 34 | delay?: any; 35 | container?: any; 36 | } 37 | 38 | interface PopoverOptions { 39 | animation?: boolean; 40 | html?: boolean; 41 | placement?: any; 42 | selector?: string; 43 | trigger?: string; 44 | title?: any; 45 | content?: any; 46 | delay?: any; 47 | container?: any; 48 | } 49 | 50 | interface CollapseOptions { 51 | parent?: any; 52 | toggle?: boolean; 53 | } 54 | 55 | interface CarouselOptions { 56 | interval?: number; 57 | pause?: string; 58 | } 59 | 60 | interface TypeaheadOptions { 61 | source?: any; 62 | items?: number; 63 | minLength?: number; 64 | matcher?: (item: any) => boolean; 65 | sorter?: (items: any[]) => any[]; 66 | updater?: (item: any) => any; 67 | highlighter?: (item: any) => string; 68 | } 69 | 70 | interface AffixOptions { 71 | offset?: any; 72 | } 73 | 74 | interface JQuery { 75 | modal(options?: ModalOptions): JQuery; 76 | modal(options?: ModalOptionsBackdropString): JQuery; 77 | modal(command: string): JQuery; 78 | 79 | dropdown(): JQuery; 80 | dropdown(command: string): JQuery; 81 | 82 | scrollspy(command: string): JQuery; 83 | scrollspy(options?: ScrollSpyOptions): JQuery; 84 | 85 | tab(): JQuery; 86 | tab(command: string): JQuery; 87 | 88 | tooltip(options?: TooltipOptions): JQuery; 89 | tooltip(command: string): JQuery; 90 | 91 | popover(options?: PopoverOptions): JQuery; 92 | popover(command: string): JQuery; 93 | 94 | alert(): JQuery; 95 | alert(command: string): JQuery; 96 | 97 | button(): JQuery; 98 | button(command: string): JQuery; 99 | 100 | collapse(options?: CollapseOptions): JQuery; 101 | collapse(command: string): JQuery; 102 | 103 | carousel(options?: CarouselOptions): JQuery; 104 | carousel(command: string): JQuery; 105 | 106 | typeahead(options?: TypeaheadOptions): JQuery; 107 | 108 | affix(options?: AffixOptions): JQuery; 109 | } 110 | 111 | declare module "bootstrap" { 112 | } 113 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/progressbar.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Progressbar 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/progressbar/#theming 10 | */ 11 | .ui-progressbar { 12 | height: 2em; 13 | text-align: left; 14 | overflow: hidden; 15 | } 16 | .ui-progressbar .ui-progressbar-value { 17 | margin: -1px; 18 | height: 100%; 19 | } 20 | .ui-progressbar .ui-progressbar-overlay { 21 | background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw=="); 22 | height: 100%; 23 | filter: alpha(opacity=25); /* support: IE8 */ 24 | opacity: 0.25; 25 | } 26 | .ui-progressbar-indeterminate .ui-progressbar-value { 27 | background-image: none; 28 | } 29 | -------------------------------------------------------------------------------- /Ollert/DAL/GenericRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Data; 5 | using System.Data.Entity; 6 | using System.Linq.Expressions; 7 | using System.Threading.Tasks; 8 | 9 | namespace Ollert.DAL 10 | { 11 | public class GenericRepository where TEntity : class 12 | { 13 | internal OllertDbContext context; 14 | internal DbSet dbSet; 15 | 16 | public GenericRepository(OllertDbContext context) 17 | { 18 | this.context = context; 19 | this.dbSet = context.Set(); 20 | } 21 | 22 | //public virtual IEnumerable GetWithRawSql(string query, params object[] parameters) 23 | //{ 24 | // return dbSet.SqlQuery(query, parameters).ToList(); 25 | //} 26 | 27 | public virtual async Task> Get( 28 | Expression> filter = null, 29 | Func, IQueryable> orderBy = null, 30 | Func, IQueryable> limitBy = null, 31 | string includeProperties = "") 32 | { 33 | IQueryable query = dbSet; 34 | 35 | if (filter != null) 36 | { 37 | query = query.Where(filter); 38 | } 39 | 40 | foreach (var includeProperty in includeProperties.Split 41 | (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) 42 | { 43 | query = query.Include(includeProperty); 44 | } 45 | 46 | if (limitBy != null) 47 | { 48 | query = limitBy(query); 49 | } 50 | 51 | if (orderBy != null) 52 | { 53 | query = orderBy(query); 54 | } 55 | 56 | return await query.ToListAsync(); 57 | 58 | } 59 | 60 | public virtual int Count() 61 | { 62 | return dbSet.Count(); 63 | } 64 | 65 | public virtual async Task GetByID(object id) 66 | { 67 | return await dbSet.FindAsync(id); 68 | } 69 | 70 | public virtual void Insert(TEntity entity) 71 | { 72 | dbSet.Add(entity); 73 | } 74 | 75 | public virtual async Task Delete(object id) 76 | { 77 | TEntity entityToDelete = await dbSet.FindAsync(id); 78 | Delete(entityToDelete); 79 | } 80 | 81 | public virtual void Delete(TEntity entityToDelete) 82 | { 83 | if (context.Entry(entityToDelete).State == EntityState.Detached) 84 | { 85 | dbSet.Attach(entityToDelete); 86 | } 87 | dbSet.Remove(entityToDelete); 88 | } 89 | 90 | public virtual void Update(TEntity entityToUpdate) 91 | { 92 | dbSet.Attach(entityToUpdate); 93 | context.Entry(entityToUpdate).State = EntityState.Modified; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/List.ts: -------------------------------------------------------------------------------- 1 | interface IList { 2 | id: number; 3 | name: string; 4 | boardId: number; 5 | parent: Board; 6 | cards: Array; 7 | } 8 | 9 | class List { 10 | id: number; 11 | name: string; 12 | boardId: number; 13 | parent: KnockoutObservable; 14 | allCards: KnockoutObservableArray; 15 | cards: KnockoutObservableArray; 16 | 17 | listCards: KnockoutComputed; 18 | hasCards: KnockoutComputed; 19 | totalTime: KnockoutComputed; 20 | 21 | deleteCard: (data, event) => boolean; 22 | 23 | constructor(data: IList) { 24 | var self = this; 25 | 26 | this.id = data.id; 27 | this.name = data.name; 28 | this.allCards = ko.observableArray(data.cards); 29 | this.boardId = data.boardId; 30 | this.parent = ko.observable(data.parent); 31 | this.cards = ko.observableArray(new Array()); 32 | 33 | this.allCards.id = data.id; 34 | this.cards.id = data.id; 35 | 36 | this.listCards = ko.computed(function () { 37 | var cartes = new Array(); 38 | 39 | if (self.parent() != null) { 40 | $.each(self.allCards(), function (index, card) { 41 | if (self.parent().displayArchive() && card.isArchive()) 42 | cartes.push(card); 43 | else if (!self.parent().displayArchive() && !card.isArchive()) 44 | cartes.push(card); 45 | }); 46 | } 47 | 48 | self.cards(cartes); 49 | //return cartes; 50 | }, self); 51 | 52 | this.hasCards = ko.computed(function () { 53 | return self.cards().length > 0; 54 | }, self); 55 | 56 | this.totalTime = ko.computed(function () { 57 | var total = 0; 58 | $.each(self.cards(), function (index, el) { 59 | total += el.estimation(); 60 | }); 61 | 62 | var seconds = total; 63 | var numyears = Math.floor(seconds / 31536000); 64 | var numdays = Math.floor((seconds % 31536000) / 86400); 65 | var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600); 66 | var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); 67 | var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60; 68 | return (numyears > 0 ? numyears + " y " : '') + (numdays > 0 ? numdays + " d" : '') + (numhours > 0 ? numhours + " h" : '') + (numminutes > 0 ? numminutes + " m" : '') + (numseconds > 0 ? numseconds + " s" : ''); 69 | }, self); 70 | 71 | // SERVER 72 | this.deleteCard = (data, event) => { 73 | var self = this; 74 | event.stopImmediatePropagation(); 75 | 76 | OllertApi.deleteCard(data.id, function () { 77 | // AJAX CALLBACK 78 | self.cards.remove(data); 79 | }); 80 | 81 | return false; 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/BoardDetails.js: -------------------------------------------------------------------------------- 1 | var BoardDetails = (function () { 2 | function BoardDetails(id, nom, participants, proprietaire, users, unseenMessage, unseenFiles, timeLeft) { 3 | var _this = this; 4 | var self = this; 5 | this.id = id; 6 | this.name = nom; 7 | this.users = ko.observableArray(users); 8 | this.proprietaire = ko.observable(proprietaire); 9 | this.participants = ko.observableArray(participants); 10 | this.isShow = ko.observable(false); 11 | this.unseenMessage = ko.observable(unseenMessage); 12 | this.unseenFiles = ko.observable(unseenFiles); 13 | this.timeLeft = ko.observable(timeLeft); 14 | // Computed 15 | this.salleUrl = ko.computed(function () { 16 | return "/Board/Salle/" + self.id.toString(); 17 | }, self); 18 | // Methods 19 | this.showUsers = function () { 20 | _this.isShow(!_this.isShow()); 21 | }; 22 | this.timeLeftHumanReadable = function () { 23 | var seconds = _this.timeLeft(); 24 | var numyears = Math.floor(seconds / 31536000); 25 | var numdays = Math.floor((seconds % 31536000) / 86400); 26 | var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600); 27 | var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); 28 | var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60; 29 | var output = (numyears > 0 ? numyears + " y " : '') + (numdays > 0 ? numdays + " d" : '') + (numhours > 0 ? numhours + " h" : '') + (numminutes > 0 ? numminutes + " m" : '') + (numseconds > 0 ? numseconds + " s" : ''); 30 | return output; 31 | }; 32 | // SERVEUR 33 | this.addParticipant = function (data) { 34 | // Ajoute aux participants 35 | self.participants.push(data); 36 | // Retire au dispoibles 37 | var indexUser = -1; 38 | $.each(self.users(), function (index, user) { 39 | if (user.id == data.id) 40 | indexUser = index; 41 | }); 42 | if (indexUser >= 0) 43 | self.users.splice(indexUser, 1); 44 | self.isShow(false); 45 | // Ajoute au serveur 46 | OllertApi.updateBoard(self); 47 | }; 48 | this.removeParticipant = function (data) { 49 | // Retire aux participants 50 | var indexParticipant = -1; 51 | $.each(self.participants(), function (index, participant) { 52 | if (participant.id == data.id) 53 | indexParticipant = index; 54 | }); 55 | if (indexParticipant >= 0) 56 | self.participants.splice(indexParticipant, 1); 57 | // Ajoute aux disponibles 58 | self.users.push(data); 59 | // MAJ serveur 60 | OllertApi.updateBoard(_this); 61 | return false; 62 | }; 63 | } 64 | return BoardDetails; 65 | })(); 66 | //# sourceMappingURL=BoardDetails.js.map -------------------------------------------------------------------------------- /Ollert/Tools/TypeScript/en/TypeScriptCompile.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 41 | 42 | 43 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Ollert/Content/themes/base/button.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Button 1.11.4 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/button/#theming 10 | */ 11 | .ui-button { 12 | display: inline-block; 13 | position: relative; 14 | padding: 0; 15 | line-height: normal; 16 | margin-right: .1em; 17 | cursor: pointer; 18 | vertical-align: middle; 19 | text-align: center; 20 | overflow: visible; /* removes extra width in IE */ 21 | } 22 | .ui-button, 23 | .ui-button:link, 24 | .ui-button:visited, 25 | .ui-button:hover, 26 | .ui-button:active { 27 | text-decoration: none; 28 | } 29 | /* to make room for the icon, a width needs to be set here */ 30 | .ui-button-icon-only { 31 | width: 2.2em; 32 | } 33 | /* button elements seem to need a little more width */ 34 | button.ui-button-icon-only { 35 | width: 2.4em; 36 | } 37 | .ui-button-icons-only { 38 | width: 3.4em; 39 | } 40 | button.ui-button-icons-only { 41 | width: 3.7em; 42 | } 43 | 44 | /* button text element */ 45 | .ui-button .ui-button-text { 46 | display: block; 47 | line-height: normal; 48 | } 49 | .ui-button-text-only .ui-button-text { 50 | padding: .4em 1em; 51 | } 52 | .ui-button-icon-only .ui-button-text, 53 | .ui-button-icons-only .ui-button-text { 54 | padding: .4em; 55 | text-indent: -9999999px; 56 | } 57 | .ui-button-text-icon-primary .ui-button-text, 58 | .ui-button-text-icons .ui-button-text { 59 | padding: .4em 1em .4em 2.1em; 60 | } 61 | .ui-button-text-icon-secondary .ui-button-text, 62 | .ui-button-text-icons .ui-button-text { 63 | padding: .4em 2.1em .4em 1em; 64 | } 65 | .ui-button-text-icons .ui-button-text { 66 | padding-left: 2.1em; 67 | padding-right: 2.1em; 68 | } 69 | /* no icon support for input elements, provide padding by default */ 70 | input.ui-button { 71 | padding: .4em 1em; 72 | } 73 | 74 | /* button icon element(s) */ 75 | .ui-button-icon-only .ui-icon, 76 | .ui-button-text-icon-primary .ui-icon, 77 | .ui-button-text-icon-secondary .ui-icon, 78 | .ui-button-text-icons .ui-icon, 79 | .ui-button-icons-only .ui-icon { 80 | position: absolute; 81 | top: 50%; 82 | margin-top: -8px; 83 | } 84 | .ui-button-icon-only .ui-icon { 85 | left: 50%; 86 | margin-left: -8px; 87 | } 88 | .ui-button-text-icon-primary .ui-button-icon-primary, 89 | .ui-button-text-icons .ui-button-icon-primary, 90 | .ui-button-icons-only .ui-button-icon-primary { 91 | left: .5em; 92 | } 93 | .ui-button-text-icon-secondary .ui-button-icon-secondary, 94 | .ui-button-text-icons .ui-button-icon-secondary, 95 | .ui-button-icons-only .ui-button-icon-secondary { 96 | right: .5em; 97 | } 98 | 99 | /* button sets */ 100 | .ui-buttonset { 101 | margin-right: 7px; 102 | } 103 | .ui-buttonset .ui-button { 104 | margin-left: 0; 105 | margin-right: -.3em; 106 | } 107 | 108 | /* workarounds */ 109 | /* reset extra padding in Firefox, see h5bp.com/l */ 110 | input.ui-button::-moz-focus-inner, 111 | button.ui-button::-moz-focus-inner { 112 | border: 0; 113 | padding: 0; 114 | } 115 | -------------------------------------------------------------------------------- /Ollert/Hubs/OllertHub.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using Microsoft.AspNet.SignalR; 6 | using System.Threading.Tasks; 7 | using System.Collections.Concurrent; 8 | using System.Threading; 9 | using Newtonsoft.Json; 10 | using Ollert.Models; 11 | using Microsoft.AspNet.Identity; 12 | using Microsoft.AspNet.Identity.EntityFramework; 13 | using System.Data.Entity; 14 | 15 | namespace Ollert.Hubs 16 | { 17 | public class User 18 | { 19 | public string UserName { get; set; } 20 | public string EmailMd5 { get; set; } 21 | public bool UseGravatar { get; set; } 22 | public string UserId { get; set; } 23 | public HashSet ConnectionIds { get; set; } 24 | } 25 | 26 | [Authorize] 27 | public class OllertHub : Hub 28 | { 29 | internal static readonly ConcurrentDictionary ConnectedUsers = new ConcurrentDictionary(); 30 | public override Task OnConnected() 31 | { 32 | string userId = Guid.Empty.ToString(); 33 | OllertUser currentUser = null; 34 | if (Context.User != null) 35 | { 36 | var db = new Ollert.DAL.OllertDbContext(); 37 | userId = Context.User.Identity.GetUserId(); 38 | currentUser = db.Users.First(u => u.Id == userId); 39 | } 40 | 41 | 42 | string connectionId = Context.ConnectionId; 43 | 44 | var user = ConnectedUsers.GetOrAdd(userId, _ => new User 45 | { 46 | UserName = Context.User != null ? Context.User.Identity.Name : "", 47 | UserId = userId, 48 | UseGravatar = currentUser != null ? currentUser.UseGravatar : false, 49 | EmailMd5 = currentUser != null ? currentUser.EmailMd5 : string.Empty, 50 | ConnectionIds = new HashSet() 51 | }); 52 | 53 | lock (user.ConnectionIds) 54 | { 55 | user.ConnectionIds.Add(connectionId); 56 | } 57 | 58 | this.Clients.All.onConnected(ConnectedUsers.Select(u => u.Value)); 59 | 60 | return base.OnConnected(); 61 | } 62 | 63 | public override Task OnDisconnected(bool stopCalled) 64 | { 65 | // Retire l'id de la liste 66 | foreach (var connectedUser in ConnectedUsers) 67 | { 68 | lock (connectedUser.Value.ConnectionIds) 69 | { 70 | connectedUser.Value.ConnectionIds = connectedUser.Value.ConnectionIds.Where(c => !c.Equals(Context.ConnectionId)).ToHashSet(); 71 | } 72 | 73 | if (!connectedUser.Value.ConnectionIds.Any()) 74 | { 75 | User removedUser; 76 | ConnectedUsers.TryRemove(connectedUser.Key, out removedUser); 77 | } 78 | } 79 | 80 | // Send to js client 81 | Clients.Others.onDisconnected(ConnectedUsers.Select(u => u.Value)); 82 | 83 | return base.OnDisconnected(stopCalled); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Ollert/Extensions/ObjectQueryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity.Core.Objects; 4 | using System.Data.Entity.Core.Objects.DataClasses; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | using System.Text; 9 | using System.Web; 10 | 11 | namespace Ollert 12 | { 13 | public static class ObjectQueryExtensions 14 | { 15 | public static ObjectQuery Includes(this ObjectQuery query, Action> action) 16 | { 17 | var sb = new StringBuilder(); 18 | var queryBuilder = new IncludeObjectQuery(query, sb); 19 | action(queryBuilder); 20 | return queryBuilder.Query; 21 | } 22 | 23 | public static ObjectQuery Include(this ObjectQuery query, Expression> expression) 24 | { 25 | var sb = new StringBuilder(); 26 | return IncludeAllLevels(expression, sb, query); 27 | } 28 | 29 | static ObjectQuery IncludeAllLevels(Expression> expression, StringBuilder sb, ObjectQuery query) 30 | { 31 | foreach (var name in expression.GetPropertyLevels()) 32 | { 33 | sb.Append(name); 34 | query = query.Include(sb.ToString()); 35 | //Debug.WriteLine(string.Format("Include(\"{0}\")", sb)); 36 | sb.Append('.'); 37 | } 38 | return query; 39 | } 40 | 41 | static IEnumerable GetPropertyLevels(this Expression> expression) 42 | { 43 | var namesInReverse = new List(); 44 | 45 | var unaryExpression = expression as UnaryExpression; 46 | var body = unaryExpression != null ? unaryExpression.Operand : expression.Body; 47 | 48 | while (body != null) 49 | { 50 | var memberExpression = body as MemberExpression; 51 | if (memberExpression == null) 52 | break; 53 | 54 | namesInReverse.Add(memberExpression.Member.Name); 55 | body = memberExpression.Expression; 56 | } 57 | 58 | namesInReverse.Reverse(); 59 | return namesInReverse; 60 | } 61 | 62 | public class IncludeObjectQuery 63 | { 64 | readonly StringBuilder _pathBuilder; 65 | public ObjectQuery Query { get; private set; } 66 | 67 | public IncludeObjectQuery(ObjectQuery query, StringBuilder builder) 68 | { 69 | _pathBuilder = builder; 70 | Query = query; 71 | } 72 | 73 | public IncludeObjectQuery Include(Expression> expression) 74 | { 75 | Query = ObjectQueryExtensions.IncludeAllLevels(expression, _pathBuilder, Query); 76 | return new IncludeObjectQuery(Query, _pathBuilder); 77 | } 78 | 79 | public IncludeObjectQuery Include(Expression>> expression) where U : class 80 | { 81 | Query = ObjectQueryExtensions.IncludeAllLevels(expression, _pathBuilder, Query); 82 | return new IncludeObjectQuery(Query, _pathBuilder); 83 | } 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/BoardDetails.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"BoardDetails.js","sourceRoot":"","sources":["BoardDetails.ts"],"names":["BoardDetails","BoardDetails.constructor"],"mappings":"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"} -------------------------------------------------------------------------------- /Ollert/Scripts/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cookie Plugin v1.4.0 3 | * https://github.com/carhartl/jquery-cookie 4 | * 5 | * Copyright 2013 Klaus Hartl 6 | * Released under the MIT license 7 | */ 8 | (function (factory) { 9 | if (typeof define === 'function' && define.amd) { 10 | // AMD. Register as anonymous module. 11 | define(['jquery'], factory); 12 | } else { 13 | // Browser globals. 14 | factory(jQuery); 15 | } 16 | }(function ($) { 17 | 18 | var pluses = /\+/g; 19 | 20 | function encode(s) { 21 | return config.raw ? s : encodeURIComponent(s); 22 | } 23 | 24 | function decode(s) { 25 | return config.raw ? s : decodeURIComponent(s); 26 | } 27 | 28 | function stringifyCookieValue(value) { 29 | return encode(config.json ? JSON.stringify(value) : String(value)); 30 | } 31 | 32 | function parseCookieValue(s) { 33 | if (s.indexOf('"') === 0) { 34 | // This is a quoted cookie as according to RFC2068, unescape... 35 | s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 36 | } 37 | 38 | try { 39 | // Replace server-side written pluses with spaces. 40 | // If we can't decode the cookie, ignore it, it's unusable. 41 | s = decodeURIComponent(s.replace(pluses, ' ')); 42 | } catch(e) { 43 | return; 44 | } 45 | 46 | try { 47 | // If we can't parse the cookie, ignore it, it's unusable. 48 | return config.json ? JSON.parse(s) : s; 49 | } catch(e) {} 50 | } 51 | 52 | function read(s, converter) { 53 | var value = config.raw ? s : parseCookieValue(s); 54 | return $.isFunction(converter) ? converter(value) : value; 55 | } 56 | 57 | var config = $.cookie = function (key, value, options) { 58 | 59 | // Write 60 | if (value !== undefined && !$.isFunction(value)) { 61 | options = $.extend({}, config.defaults, options); 62 | 63 | if (typeof options.expires === 'number') { 64 | var days = options.expires, t = options.expires = new Date(); 65 | t.setDate(t.getDate() + days); 66 | } 67 | 68 | return (document.cookie = [ 69 | encode(key), '=', stringifyCookieValue(value), 70 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 71 | options.path ? '; path=' + options.path : '', 72 | options.domain ? '; domain=' + options.domain : '', 73 | options.secure ? '; secure' : '' 74 | ].join('')); 75 | } 76 | 77 | // Read 78 | 79 | var result = key ? undefined : {}; 80 | 81 | // To prevent the for loop in the first place assign an empty array 82 | // in case there are no cookies at all. Also prevents odd result when 83 | // calling $.cookie(). 84 | var cookies = document.cookie ? document.cookie.split('; ') : []; 85 | 86 | for (var i = 0, l = cookies.length; i < l; i++) { 87 | var parts = cookies[i].split('='); 88 | var name = decode(parts.shift()); 89 | var cookie = parts.join('='); 90 | 91 | if (key && key === name) { 92 | // If second argument (value) is a function it's a converter... 93 | result = read(cookie, value); 94 | break; 95 | } 96 | 97 | // Prevent storing a cookie that we couldn't decode. 98 | if (!key && (cookie = read(cookie)) !== undefined) { 99 | result[name] = cookie; 100 | } 101 | } 102 | 103 | return result; 104 | }; 105 | 106 | config.defaults = {}; 107 | 108 | $.removeCookie = function (key, options) { 109 | if ($.cookie(key) !== undefined) { 110 | // Must not alter options, thus extending a fresh object... 111 | $.cookie(key, '', $.extend({}, options, { expires: -1 })); 112 | return true; 113 | } 114 | return false; 115 | }; 116 | 117 | })); 118 | -------------------------------------------------------------------------------- /Ollert/Scripts/typings/signalr/signalr.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for SignalR 1.0 2 | // Project: http://www.asp.net/signalr 3 | // Definitions by: Boris Yankov 4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped 5 | 6 | 7 | /// 8 | 9 | interface HubMethod { 10 | (callback: (data: string) => void ); 11 | } 12 | 13 | interface SignalREvents { 14 | onStart: string; 15 | onStarting: string; 16 | onReceived: string; 17 | onError: string; 18 | onConnectionSlow: string; 19 | onReconnect: string; 20 | onStateChanged: string; 21 | onDisconnect: string; 22 | } 23 | 24 | interface SignalRStateChange { 25 | oldState: number; 26 | newState: number; 27 | } 28 | 29 | interface SignalR { 30 | events: SignalREvents; 31 | connectionState: any; 32 | transports: any; 33 | 34 | hub: HubConnection; 35 | id: string; 36 | logging: boolean; 37 | messageId: string; 38 | url: string; 39 | 40 | (url: string, queryString?: any, logging?: boolean): SignalR; 41 | hubConnection(url?: string): SignalR; 42 | 43 | log(msg: string, logging: boolean): void; 44 | isCrossDomain(url: string): boolean; 45 | changeState(connection: SignalR, expectedState: number, newState: number): boolean; 46 | isDisconnecting(connection: SignalR): boolean; 47 | 48 | // createHubProxy(hubName: string): SignalR; 49 | 50 | start(): JQueryPromise; 51 | start(callback: () => void ): JQueryPromise; 52 | start(settings: ConnectionSettings): JQueryPromise; 53 | start(settings: ConnectionSettings, callback: () => void ): JQueryPromise; 54 | 55 | 56 | send(data: string): void; 57 | stop(async?: boolean, notifyServer?: boolean): void; 58 | 59 | starting(handler: () => void ): SignalR; 60 | received(handler: (data: any) => void ): SignalR; 61 | error(handler: (error: string) => void ): SignalR; 62 | stateChanged(handler: (change: SignalRStateChange) => void ): SignalR; 63 | disconnected(handler: () => void ): SignalR; 64 | connectionSlow(handler: () => void ): SignalR; 65 | sending(handler: () => void ): SignalR; 66 | reconnecting(handler: () => void): SignalR; 67 | reconnected(handler: () => void): SignalR; 68 | } 69 | 70 | interface HubProxy { 71 | (connection: HubConnection, hubName: string): HubProxy; 72 | state: any; 73 | connection: HubConnection; 74 | hubName: string; 75 | init(connection: HubConnection, hubName: string): void; 76 | hasSubscriptions(): boolean; 77 | on(eventName: string, callback: (...msg) => void ): HubProxy; 78 | off(eventName: string, callback: (msg) => void ): HubProxy; 79 | invoke(methodName: string, ...args: any[]): JQueryDeferred; 80 | } 81 | 82 | interface HubConnectionSettings { 83 | queryString?: string; 84 | logging?: boolean; 85 | useDefaultPath?: boolean; 86 | } 87 | 88 | interface HubConnection extends SignalR { 89 | //(url?: string, queryString?: any, logging?: boolean): HubConnection; 90 | proxies; 91 | received(callback: (data: { Id; Method; Hub; State; Args; }) => void ): HubConnection; 92 | createHubProxy(hubName: string): HubProxy; 93 | } 94 | 95 | interface SignalRfn { 96 | init(url, qs, logging); 97 | } 98 | 99 | interface ConnectionSettings { 100 | transport?; 101 | callback?; 102 | waitForPageLoad?: boolean; 103 | jsonp?: boolean; 104 | } 105 | 106 | interface JQueryStatic { 107 | signalR: SignalR; 108 | connection: SignalR; 109 | hubConnection(url?: string, queryString?: any, logging?: boolean): HubConnection; 110 | } 111 | -------------------------------------------------------------------------------- /Ollert/Scripts/pages/Classes/BoardDetails.ts: -------------------------------------------------------------------------------- 1 | class BoardDetails { 2 | id: number; 3 | name: string; 4 | isShow: KnockoutObservable; 5 | proprietaire: KnockoutObservable; 6 | users: KnockoutObservableArray; 7 | participants: KnockoutObservableArray; 8 | 9 | 10 | unseenMessage: KnockoutObservable; 11 | unseenFiles: KnockoutObservable; 12 | timeLeft: KnockoutObservable; 13 | 14 | // Computed 15 | salleUrl: KnockoutComputed; 16 | 17 | // Methods 18 | showUsers: () => void; 19 | timeLeftHumanReadable: () => string; 20 | addParticipant: (data: User) => void; 21 | removeParticipant: (data: User) => void; 22 | 23 | constructor(id: number, nom: string, participants: Array, proprietaire: User, users: Array, unseenMessage: number, unseenFiles: number, timeLeft: number) { 24 | var self = this; 25 | this.id = id; 26 | this.name = nom; 27 | this.users = ko.observableArray(users); 28 | this.proprietaire = ko.observable(proprietaire); 29 | this.participants = ko.observableArray(participants); 30 | this.isShow = ko.observable(false); 31 | 32 | this.unseenMessage = ko.observable(unseenMessage); 33 | this.unseenFiles = ko.observable(unseenFiles); 34 | this.timeLeft = ko.observable(timeLeft); 35 | 36 | // Computed 37 | this.salleUrl = ko.computed(function () { 38 | return "/Board/Salle/" + self.id.toString(); 39 | }, self); 40 | 41 | // Methods 42 | this.showUsers = () => { 43 | this.isShow(!this.isShow()); 44 | } 45 | this.timeLeftHumanReadable = () => { 46 | var seconds = this.timeLeft(); 47 | var numyears = Math.floor(seconds / 31536000); 48 | var numdays = Math.floor((seconds % 31536000) / 86400); 49 | var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600); 50 | var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); 51 | var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60; 52 | var output = (numyears > 0 ? numyears + " y " : '') + (numdays > 0 ? numdays + " d" : '') + (numhours > 0 ? numhours + " h" : '') + (numminutes > 0 ? numminutes + " m" : '') + (numseconds > 0 ? numseconds + " s" : ''); 53 | return output; 54 | }; 55 | 56 | // SERVEUR 57 | this.addParticipant = (data) => { 58 | // Ajoute aux participants 59 | self.participants.push(data); 60 | 61 | // Retire au dispoibles 62 | var indexUser = -1; 63 | $.each(self.users(), function (index, user) { 64 | if (user.id == data.id) 65 | indexUser = index; 66 | }); 67 | if (indexUser >= 0) 68 | self.users.splice(indexUser, 1); 69 | 70 | self.isShow(false); 71 | 72 | // Ajoute au serveur 73 | OllertApi.updateBoard(self); 74 | 75 | }; 76 | 77 | this.removeParticipant = (data) => { 78 | // Retire aux participants 79 | var indexParticipant = -1; 80 | $.each(self.participants(), function (index, participant) { 81 | if (participant.id == data.id) 82 | indexParticipant = index; 83 | }); 84 | if (indexParticipant >= 0) 85 | self.participants.splice(indexParticipant, 1); 86 | 87 | // Ajoute aux disponibles 88 | self.users.push(data); 89 | 90 | // MAJ serveur 91 | OllertApi.updateBoard(this); 92 | 93 | return false; 94 | }; 95 | } 96 | } -------------------------------------------------------------------------------- /Ollert/Views/Member/Profil.cshtml: -------------------------------------------------------------------------------- 1 | @model Ollert.Models.OllertUser 2 | 3 | 11 | 12 |
13 |
14 |
15 | 16 | 17 |
18 | 19 |
20 | 83 |
84 | 85 |
86 |
87 |
-------------------------------------------------------------------------------- /Ollert/Api/NotificationController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Entity; 5 | using System.Data.Entity.Infrastructure; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Net.Http; 9 | using System.Threading.Tasks; 10 | using System.Web.Http; 11 | using System.Web.Http.Description; 12 | using Ollert.Models; 13 | using Ollert.DAL; 14 | 15 | namespace Ollert.Api 16 | { 17 | [Authorize] 18 | public class NotificationController : ApiController 19 | { 20 | private OllertDbContext db = new OllertDbContext(); 21 | 22 | // GET api/Notification 23 | public IQueryable GetNotifications() 24 | { 25 | return db.Notifications.Include(n => n.Createur).OrderByDescending(n => n.Date).Take(50); 26 | } 27 | 28 | // GET api/Notification/5 29 | [ResponseType(typeof(Notification))] 30 | public async Task GetNotification(int id) 31 | { 32 | Notification notification = await db.Notifications.FindAsync(id); 33 | if (notification == null) 34 | { 35 | return NotFound(); 36 | } 37 | 38 | return Ok(notification); 39 | } 40 | 41 | // PUT api/Notification/5 42 | public async Task PutNotification(int id, Notification notification) 43 | { 44 | if (!ModelState.IsValid) 45 | { 46 | return BadRequest(ModelState); 47 | } 48 | 49 | if (id != notification.Id) 50 | { 51 | return BadRequest(); 52 | } 53 | 54 | db.Entry(notification).State = EntityState.Modified; 55 | 56 | try 57 | { 58 | await db.SaveChangesAsync(); 59 | } 60 | catch (DbUpdateConcurrencyException) 61 | { 62 | if (!NotificationExists(id)) 63 | { 64 | return NotFound(); 65 | } 66 | else 67 | { 68 | throw; 69 | } 70 | } 71 | 72 | return StatusCode(HttpStatusCode.NoContent); 73 | } 74 | 75 | // POST api/Notification 76 | [ResponseType(typeof(Notification))] 77 | public async Task PostNotification(Notification notification) 78 | { 79 | if (!ModelState.IsValid) 80 | { 81 | return BadRequest(ModelState); 82 | } 83 | 84 | db.Notifications.Add(notification); 85 | await db.SaveChangesAsync(); 86 | 87 | return CreatedAtRoute("DefaultApi", new { id = notification.Id }, notification); 88 | } 89 | 90 | // DELETE api/Notification/5 91 | [ResponseType(typeof(Notification))] 92 | public async Task DeleteNotification(int id) 93 | { 94 | Notification notification = await db.Notifications.FindAsync(id); 95 | if (notification == null) 96 | { 97 | return NotFound(); 98 | } 99 | 100 | db.Notifications.Remove(notification); 101 | await db.SaveChangesAsync(); 102 | 103 | return Ok(notification); 104 | } 105 | 106 | protected override void Dispose(bool disposing) 107 | { 108 | if (disposing) 109 | { 110 | db.Dispose(); 111 | } 112 | base.Dispose(disposing); 113 | } 114 | 115 | private bool NotificationExists(int id) 116 | { 117 | return db.Notifications.Count(e => e.Id == id) > 0; 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /Ollert/Models/Carte.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Runtime.Serialization; 7 | using System.Text; 8 | using Microsoft.AspNet.Identity; 9 | using Microsoft.AspNet.Identity.EntityFramework; 10 | using Ollert.DAL; 11 | using System.Web; 12 | 13 | namespace Ollert.Models 14 | { 15 | [DataContract] 16 | public class Carte : Ollert.Models.IEntity 17 | { 18 | public Carte() 19 | { 20 | this.Messages = new List(); 21 | this.Fichiers = new List(); 22 | this.CartesVues = new List(); 23 | this.Etapes = new List(); 24 | } 25 | 26 | [Key] 27 | [DataMember] 28 | public int Id { get; set; } 29 | [DataMember] 30 | public int NumeroDemande { get; set; } 31 | [DataMember] 32 | public string Titre { get; set; } 33 | [DataMember] 34 | public string Description { get; set; } 35 | [DataMember] 36 | public DateTime DateCreation { get; set; } 37 | [DataMember] 38 | public int Position { get; set; } 39 | [DataMember] 40 | public bool Archive { get; set; } 41 | [DataMember] 42 | public virtual ICollection Messages { get; set; } 43 | [DataMember] 44 | public virtual ICollection Fichiers { get; set; } 45 | public virtual ICollection CartesVues { get; set; } 46 | [DataMember] 47 | public virtual ICollection Etapes { get; set; } 48 | [Required] 49 | public virtual Tableau Tableau { get; set; } 50 | //[DataMember] 51 | //public virtual ICollection Tags { get; set; } 52 | 53 | [NotMapped] 54 | [DataMember] 55 | public DateTime LastTimeViewed 56 | { 57 | get 58 | { 59 | var carteVue = CartesVues.FirstOrDefault(c => c.Utilisateur.Id == System.Web.HttpContext.Current.User.Identity.GetUserId()); 60 | if (carteVue != null) 61 | { 62 | return carteVue.DerniereConsultation; 63 | } 64 | 65 | return DateTime.MinValue; 66 | } 67 | set 68 | { 69 | var carteVue = CartesVues.FirstOrDefault(c => c.Utilisateur.Id == System.Web.HttpContext.Current.User.Identity.GetUserId()); 70 | if (carteVue != null) 71 | { 72 | carteVue.DerniereConsultation = value; 73 | } 74 | else 75 | { 76 | carteVue = new CarteVue 77 | { 78 | DerniereConsultation = value, 79 | Utilisateur = new OllertUser { Id = System.Web.HttpContext.Current.User.Identity.GetUserId() } 80 | }; 81 | } 82 | 83 | this.CartesVues.Add(carteVue); 84 | } 85 | } 86 | [NotMapped] 87 | [DataMember] 88 | public int TableauId 89 | { 90 | get 91 | { 92 | if (Tableau != null) 93 | return Tableau.Id; 94 | else 95 | return -1; 96 | } 97 | } 98 | [DataMember] 99 | [NotMapped] 100 | public Nullable Estimation 101 | { 102 | get 103 | { 104 | if (Etapes != null) 105 | return this.Etapes.Sum(e => e.Estimation); 106 | else 107 | return 0; 108 | } 109 | } 110 | } 111 | 112 | public enum TagCarte 113 | { 114 | Vert, 115 | Jaune, 116 | Orange, 117 | Rouge, 118 | Violet 119 | } 120 | } 121 | --------------------------------------------------------------------------------