├── .build └── MSBuild.Community.Tasks.targets ├── .gitignore ├── .vs └── config │ └── applicationhost.config ├── 01.02.00.txt ├── App_LocalResources └── ClientResources.resx ├── Build.proj ├── BuildScripts ├── MSBuild.Community.Tasks.Targets └── ModulePackage.targets ├── Calvary_VideoCourse.dnn ├── Calvary_VideoCourse.sln ├── Calvary_VideoCourse.zip ├── Components ├── Calvary_VideoCourseModuleBase.cs ├── Calvary_VideoCourseModuleSettingsBase.cs └── FeatureController.cs ├── Content ├── angular-ui.css ├── angular-ui.min.css ├── bootstrap-flat-extras.css ├── bootstrap-flat-extras.min.css ├── bootstrap-flat.css ├── bootstrap-flat.min.css ├── bootstrap-theme.css ├── bootstrap-theme.css.map ├── bootstrap-theme.min.css ├── bootstrap.css ├── bootstrap.css.map ├── bootstrap.min.css ├── img │ ├── logo.png │ └── logo_min.png ├── select2.css ├── select2.png ├── select2x2.png ├── spinner.gif ├── themes │ └── base │ │ ├── accordion.css │ │ ├── all.css │ │ ├── autocomplete.css │ │ ├── base.css │ │ ├── button.css │ │ ├── core.css │ │ ├── datepicker.css │ │ ├── dialog.css │ │ ├── draggable.css │ │ ├── images │ │ ├── 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 │ │ ├── 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 │ │ ├── menu.css │ │ ├── progressbar.css │ │ ├── resizable.css │ │ ├── selectable.css │ │ ├── selectmenu.css │ │ ├── slider.css │ │ ├── sortable.css │ │ ├── spinner.css │ │ ├── tabs.css │ │ ├── theme.css │ │ └── tooltip.css └── ui-bootstrap-csp.css ├── Controllers ├── AnswerController.cs ├── QuestionController.cs ├── RoleController.cs └── VideoController.cs ├── DNNVideoCourse.csproj ├── Entities ├── AnswerInfo.cs ├── NewAnswerDTO.cs ├── NewQuestionDTO.cs ├── NewRoleDTO.cs ├── NewRoleGroupDTO.cs ├── NewVideoDTO.cs ├── QuestionInfo.cs ├── RoleGroupsInListDTO.cs ├── RolesInListDTO.cs ├── SubjLineDTO.cs ├── UsersInRoleDTO.cs ├── VideoInfo.cs └── VideosCompletedDTO.cs ├── Images ├── jetbrains-logo.png └── logo_min.png ├── LICENSE.txt ├── License.md ├── Models ├── RouteMapper.cs └── Webservices.cs ├── Properties └── AssemblyInfo.cs ├── Providers └── DataProviders │ └── SqlDataProvider │ ├── 00.00.01.SqlDataProvider │ ├── 01.01.00.SqlDataProvider │ ├── 01.02.00.SqlDataProvider │ └── Uninstall.SqlDataProvider ├── README.md ├── ReleaseNotes.txt ├── Resources.zip.manifest ├── Scripts ├── angular-animate.js ├── angular-animate.min.js ├── angular-animate.min.js.map ├── angular-message-format.js ├── angular-message-format.min.js ├── angular-message-format.min.js.map ├── angular-messages.js ├── angular-messages.min.js ├── angular-messages.min.js.map ├── angular-mocks.js ├── angular-route.js ├── angular-route.min.js ├── angular-route.min.js.map ├── angular-sanitize.min.js ├── angular-touch.js ├── angular-touch.min.js ├── angular-touch.min.js.map ├── angular-ui-ieshiv.js ├── angular-ui-ieshiv.min.js ├── angular-ui.js ├── angular-ui.min.js ├── angular-ui │ ├── sortable.js │ ├── ui-bootstrap-tpls.js │ ├── ui-bootstrap-tpls.min.js │ ├── ui-bootstrap.js │ └── ui-bootstrap.min.js ├── angular.js ├── angular.min.js ├── angular.min.js.map ├── bootstrap.js ├── bootstrap.min.js ├── data.json ├── errors.json ├── froogaloop2.min.js ├── jquery-2.1.4.intellisense.js ├── jquery-2.1.4.js ├── jquery-2.1.4.min.js ├── jquery-2.1.4.min.map ├── jquery-ui-1.11.4.js ├── jquery-ui-1.11.4.min.js ├── npm.js ├── scripts.js ├── select2.js ├── select2.min.js └── version.json ├── View.html ├── fonts ├── BebasNeue.otf ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff ├── glyphicons-halflings-regular.woff2 ├── icomoon.eot ├── icomoon.svg ├── icomoon.ttf └── icomoon.woff ├── module.css ├── ng ├── Controllers │ ├── answerListCtrl.js │ ├── editCategoriesCtrl.js │ ├── editCourseCtrl.js │ ├── editQuestionsCtrl.js │ ├── statusCtrl.js │ ├── videoCtrl.js │ └── videoPlayerCtrl.js ├── Views │ ├── answerListView.html │ ├── editCategories.html │ ├── editCourseView.html │ ├── editQuestionsView.html │ ├── statusView.html │ ├── templates │ │ ├── accordion-group.html │ │ └── accordion.html │ ├── videoListView.html │ └── videoPlayerView.html ├── app.js ├── controller.js └── factories.js ├── packages.config ├── packages ├── MSBuildTasks.1.4.0.88 │ ├── MSBuildTasks.1.4.0.88.nupkg │ ├── content │ │ └── MSBuild.Community.Tasks.ReadMe.md │ └── tools │ │ ├── Build.proj │ │ ├── Install.ps1 │ │ ├── MSBuild.Community.Tasks.Targets │ │ ├── MSBuild.Community.Tasks.dll │ │ ├── MSBuild.Community.Tasks.xml │ │ ├── MSBuild.Community.Tasks.xsd │ │ └── MSBuild.psm1 └── repositories.config └── web.Debug.config /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by http://www.gitignore.io 2 | 3 | ### VisualStudio ### 4 | ## Ignore Visual Studio temporary files, build results, and 5 | ## files generated by popular Visual Studio add-ons. 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.sln.docstates 11 | 12 | # Build results 13 | [Dd]ebug/ 14 | [Dd]ebugPublic/ 15 | [Rr]elease/ 16 | [Rr]eleases/ 17 | x64/ 18 | x86/ 19 | #build/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | 24 | # Cleanup project results 25 | *.[Ff]ile[Ll]ist[Aa]bsolute.txt 26 | 27 | # Roslyn cache directories 28 | *.ide/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | #NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | *_i.c 44 | *_p.c 45 | *_i.h 46 | *.ilk 47 | *.meta 48 | *.obj 49 | *.pch 50 | *.pdb 51 | *.pgc 52 | *.pgd 53 | *.rsp 54 | *.sbr 55 | *.tlb 56 | *.tli 57 | *.tlh 58 | *.tmp 59 | *.tmp_proj 60 | *.log 61 | *.vspscc 62 | *.vssscc 63 | .builds 64 | *.pidb 65 | *.svclog 66 | *.scc 67 | 68 | # Chutzpah Test files 69 | _Chutzpah* 70 | 71 | # Visual C++ cache files 72 | ipch/ 73 | *.aps 74 | *.ncb 75 | *.opensdf 76 | *.sdf 77 | *.cachefile 78 | 79 | # Visual Studio profiler 80 | *.psess 81 | *.vsp 82 | *.vspx 83 | 84 | # TFS 2012 Local Workspace 85 | $tf/ 86 | 87 | # Guidance Automation Toolkit 88 | *.gpState 89 | 90 | # ReSharper is a .NET coding add-in 91 | _ReSharper*/ 92 | *.[Rr]e[Ss]harper 93 | *.DotSettings.user 94 | 95 | # JustCode is a .NET coding addin-in 96 | .JustCode 97 | 98 | # TeamCity is a build add-in 99 | _TeamCity* 100 | 101 | # DotCover is a Code Coverage Tool 102 | *.dotCover 103 | 104 | # NCrunch 105 | _NCrunch_* 106 | .*crunch*.local.xml 107 | 108 | # MightyMoose 109 | *.mm.* 110 | AutoTest.Net/ 111 | 112 | #GhostDoc 113 | *.[Gg]host[Dd]oc.xml 114 | 115 | # Web workbench (sass) 116 | .sass-cache/ 117 | 118 | # Installshield output folder 119 | [Ee]xpress/ 120 | 121 | # DocProject is a documentation generator add-in 122 | DocProject/buildhelp/ 123 | DocProject/Help/*.HxT 124 | DocProject/Help/*.HxC 125 | DocProject/Help/*.hhc 126 | DocProject/Help/*.hhk 127 | DocProject/Help/*.hhp 128 | DocProject/Help/Html2 129 | DocProject/Help/html 130 | 131 | # Click-Once directory 132 | publish/ 133 | 134 | # Publish Web Output 135 | *.[Pp]ublish.xml 136 | *.azurePubxml 137 | # TODO: Comment the next line if you want to checkin your web deploy settings 138 | # but database connection strings (with potential passwords) will be unencrypted 139 | *.pubxml 140 | *.publishproj 141 | 142 | # NuGet Packages 143 | *.nupkg 144 | # The packages folder can be ignored because of Package Restore 145 | **/packages/* 146 | # except build/, which is used as an MSBuild target. 147 | !**/packages/build/ 148 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 149 | #!**/packages/repositories.config 150 | 151 | # Windows Azure Build Output 152 | csx/ 153 | *.build.csdef 154 | 155 | # Windows Store app package directory 156 | AppPackages/ 157 | 158 | # Others 159 | sql/ 160 | *.Cache 161 | ClientBin/ 162 | [Ss]tyle[Cc]op.* 163 | ~$* 164 | *~ 165 | *.dbmdl 166 | *.dbproj.schemaview 167 | *.pfx 168 | *.publishsettings 169 | node_modules/ 170 | 171 | # RIA/Silverlight projects 172 | Generated_Code/ 173 | 174 | # Backup & report files from converting an old project file 175 | # to a newer Visual Studio version. Backup files are not needed, 176 | # because we have git ;-) 177 | _UpgradeReport_Files/ 178 | Backup*/ 179 | UpgradeLog*.XML 180 | UpgradeLog*.htm 181 | 182 | # SQL Server files 183 | *.mdf 184 | *.ldf 185 | 186 | # Business Intelligence projects 187 | *.rdl.data 188 | *.bim.layout 189 | *.bim_*.settings 190 | 191 | # Microsoft Fakes 192 | FakesAssemblies/ 193 | 194 | 195 | ### Windows ### 196 | # Windows image file caches 197 | Thumbs.db 198 | ehthumbs.db 199 | 200 | # Folder config file 201 | Desktop.ini 202 | 203 | # Recycle Bin used on file shares 204 | $RECYCLE.BIN/ 205 | 206 | # Windows Installer files 207 | *.cab 208 | *.msi 209 | *.msm 210 | *.msp 211 | 212 | # prevent the generated installation packages from being checked in to source control 213 | [Ii]nstall/ 214 | -------------------------------------------------------------------------------- /01.02.00.txt: -------------------------------------------------------------------------------- 1 | Bin/DNNVideoCourse.dll -------------------------------------------------------------------------------- /Build.proj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildProjectDirectory)\.build 5 | 6 | 7 | 8 | 9 | 10 | 11 | 1.0.0.0 12 | 1.0.0.0 13 | 1.0.0.0 14 | 15 | 16 | 17 | 18 | 1.0.0.0 19 | $(BUILD_NUMBER) 20 | $(BUILD_NUMBER) 21 | 22 | 23 | 24 | Release 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | 40 | 48 | 49 | 50 | 51 | 52 | 53 | Configuration=$(BuildConfiguration) 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /BuildScripts/ModulePackage.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 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 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /Calvary_VideoCourse.dnn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DNN Video Course 5 | DNN Video Course module 6 | Images/logo_min.png 7 | 8 | Ralph Williams 9 | Ralph Williams 10 | http://www.ralphwilliams.com 11 | me@ralphwilliams.com 12 | 13 | 14 | 15 | 16 | 08.00.00 17 | 18 | 19 | 20 | 21 | 22 | DesktopModules\DNNVideoCourse 23 | 28 | 33 | 34 | 35 | 36 | 37 | 38 | DesktopModules/DNNVideoCourse 39 | 40 | Resources.zip 41 | 42 | 43 | 44 | 45 | 46 | 47 | DNNVideoCourse 48 | DNNVideoCourse 49 | RalphWilliams.Modules.DNNVideoCourse.Components.FeatureController, RalphWilliams.DNNVideoCourse 50 | 51 | 52 | 53 | DNNVideoCourse 54 | 0 55 | 56 | 57 | 58 | DesktopModules/DNNVideoCourse/View.html 59 | False 60 | 61 | View 62 | 63 | 64 | 0 65 | 66 | 67 | 68 | 69 | 70 | 71 | DotNetNuke.Entities.Modules.EventMessageProcessor, DotNetNuke 72 | UpgradeModule 73 | 74 | RalphWilliams.Modules.DNNVideoCourse.Components.FeatureController 75 | [DESKTOPMODULEID] 76 | 01.02.00 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | RalphWilliams.DNNVideoCourse.dll 85 | bin 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /Calvary_VideoCourse.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DNNVideoCourse", "DNNVideoCourse.csproj", "{7D61A32C-0F21-453F-A981-BD8E5A3A5304}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".build", ".build", "{203CE168-440C-49DA-B125-F2FA1E5535B0}" 9 | ProjectSection(SolutionItems) = preProject 10 | Build.proj = Build.proj 11 | .build\MSBuild.Community.Tasks.dll = .build\MSBuild.Community.Tasks.dll 12 | .build\MSBuild.Community.Tasks.targets = .build\MSBuild.Community.Tasks.targets 13 | EndProjectSection 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|Any CPU = Debug|Any CPU 18 | Release|Any CPU = Release|Any CPU 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}.Release|Any CPU.Build.0 = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(SolutionProperties) = preSolution 27 | HideSolutionNode = FALSE 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /Calvary_VideoCourse.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Calvary_VideoCourse.zip -------------------------------------------------------------------------------- /Components/Calvary_VideoCourseModuleBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | using DotNetNuke.Entities.Modules; 15 | 16 | namespace RalphWilliams.Modules.DNNVideoCourse.Components 17 | { 18 | public class DNNVideoCourseCourseModuleBase : PortalModuleBase 19 | { 20 | public int videoId 21 | { 22 | get 23 | { 24 | var qs = Request.QueryString["tid"]; 25 | if (qs != null) 26 | return Convert.ToInt32(qs); 27 | return -1; 28 | } 29 | 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Components/Calvary_VideoCourseModuleSettingsBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using DotNetNuke.Entities.Modules; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Components 16 | { 17 | public class DNNVideoCourseModuleSettingsBase : ModuleSettingsBase 18 | { 19 | } 20 | } -------------------------------------------------------------------------------- /Content/angular-ui.css: -------------------------------------------------------------------------------- 1 | /** 2 | * import components to builds angular-ui.css 3 | */ 4 | 5 | /* ui-reset */ 6 | 7 | .ui-resetwrap { 8 | position: relative; 9 | display: inline-block; 10 | } 11 | 12 | .ui-reset { 13 | position: absolute; 14 | top: 0; 15 | right: 0; 16 | z-index: 2; 17 | display: none; 18 | height: 100%; 19 | cursor: pointer; 20 | } 21 | 22 | .ui-resetwrap:hover .ui-reset { 23 | display: block; 24 | } 25 | 26 | /* ui-currency */ 27 | 28 | .ui-currency-pos { 29 | color: green; 30 | } 31 | 32 | .ui-currency-neg { 33 | color: red; 34 | } 35 | 36 | .ui-currency-zero { 37 | color: blue; 38 | } 39 | 40 | .ui-currency-pos.ui-bignum, 41 | .ui-currency-neg.ui-smallnum { 42 | font-size: 110%; 43 | } 44 | 45 | /* highlight */ 46 | 47 | .ui-match { 48 | background: yellow; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Content/angular-ui.min.css: -------------------------------------------------------------------------------- 1 | .ui-resetwrap{position:relative;display:inline-block}.ui-reset{position:absolute;top:0;right:0;z-index:2;display:none;height:100%;cursor:pointer}.ui-resetwrap:hover .ui-reset{display:block}.ui-currency-pos{color:green}.ui-currency-neg{color:red}.ui-currency-zero{color:blue}.ui-currency-pos.ui-bignum,.ui-currency-neg.ui-smallnum{font-size:110%}.ui-match{background:yellow} -------------------------------------------------------------------------------- /Content/bootstrap-flat.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Flat styles for Bootstrap v3.0.0 3 | * 4 | * Copyright 2013 Scott Dorman 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world by @sdorman. 9 | */ 10 | .img-thumbnail{border-radius:0}code,pre{border-radius:0}kbd{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.form-control{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.form-control:focus{border-color:#66afe9;outline:thin dotted #777;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;-webkit-box-shadow:none;box-shadow:none}.form-group-sm .form-control,.form-group-lg .form-control{border-radius:0}.has-success .form-control,.has-warning .form-control,.has-error .form-control{-webkit-box-shadow:none;box-shadow:none}.has-success .form-control:focus,.has-warning .form-control:focus,.has-error .form-control:focus{outline:thin dotted #777;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;-webkit-box-shadow:none;box-shadow:none}.input-sm,.input-lg{border-radius:0}.btn{border-radius:0}.btn:active,.btn.active{-webkit-box-shadow:none;box-shadow:none}.btn-lg,.btn-sm,.btn-xs{border-radius:0}.btn-group-lg>.btn,.btn-group-sm>.btn,.btn-group-xs>.btn{border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:0}.btn-group.open .dropdown-toggle{-webkit-box-shadow:none;box-shadow:none}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn,.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{border-radius:0}.input-group-addon{border-radius:0}.input-group-addon.input-sm,.input-group-addon.input-lg{border-radius:0}.dropdown-menu{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.nav-tabs>li>a{border-radius:0}@media(min-width:768px){.nav-tabs.nav-justified>li>a{border-radius:0}.nav-tabs-justified>li>a{border-radius:0}.navbar{border-radius:0}.modal-content{-webkit-box-shadow:none;box-shadow:none}}.nav-pills>li>a{border-radius:0}.navbar-collapse{-webkit-box-shadow:none;box-shadow:none}.navbar-toggle{border-radius:0}.navbar-toggle .icon-bar{border-radius:0}.navbar-form{-webkit-box-shadow:none;box-shadow:none}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-top-left-radius:0;border-top-right-radius:0}.breadcrumb{border-radius:0}.pagination{border-radius:0}.pagination>li:first-child>a,.pagination>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span,.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span,.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pager li>a,.pager li>span{border-radius:0}.label{border-radius:0}.badge{border-radius:0}.container .jumbotron{border-radius:0}.thumbnail{border-radius:0}.alert{border-radius:0}.progress{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.progress-bar{-webkit-box-shadow:none;box-shadow:none}.list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.list-group-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.panel{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel-heading{border-top-right-radius:0;border-top-left-radius:0}.panel-footer{border-bottom-right-radius:0;border-bottom-left-radius:0}.panel-group .panel{border-radius:0}.well{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.well-lg,.well-sm{border-radius:0}.close{text-shadow:none}.modal-content{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.tooltip-inner{border-radius:0}.popover{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.popover-title{border-radius:0}.carousel-control{text-shadow:none}.carousel-indicators li{border-radius:0}.carousel-caption{text-shadow:none} -------------------------------------------------------------------------------- /Content/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/img/logo.png -------------------------------------------------------------------------------- /Content/img/logo_min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/img/logo_min.png -------------------------------------------------------------------------------- /Content/select2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/select2.png -------------------------------------------------------------------------------- /Content/select2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/select2x2.png -------------------------------------------------------------------------------- /Content/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/spinner.gif -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Content/themes/base/datepicker.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI Datepicker 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/datepicker/#theming 10 | */ 11 | .ui-datepicker { 12 | width: 17em; 13 | padding: .2em .2em 0; 14 | display: none; 15 | } 16 | .ui-datepicker .ui-datepicker-header { 17 | position: relative; 18 | padding: .2em 0; 19 | } 20 | .ui-datepicker .ui-datepicker-prev, 21 | .ui-datepicker .ui-datepicker-next { 22 | position: absolute; 23 | top: 2px; 24 | width: 1.8em; 25 | height: 1.8em; 26 | } 27 | .ui-datepicker .ui-datepicker-prev-hover, 28 | .ui-datepicker .ui-datepicker-next-hover { 29 | top: 1px; 30 | } 31 | .ui-datepicker .ui-datepicker-prev { 32 | left: 2px; 33 | } 34 | .ui-datepicker .ui-datepicker-next { 35 | right: 2px; 36 | } 37 | .ui-datepicker .ui-datepicker-prev-hover { 38 | left: 1px; 39 | } 40 | .ui-datepicker .ui-datepicker-next-hover { 41 | right: 1px; 42 | } 43 | .ui-datepicker .ui-datepicker-prev span, 44 | .ui-datepicker .ui-datepicker-next span { 45 | display: block; 46 | position: absolute; 47 | left: 50%; 48 | margin-left: -8px; 49 | top: 50%; 50 | margin-top: -8px; 51 | } 52 | .ui-datepicker .ui-datepicker-title { 53 | margin: 0 2.3em; 54 | line-height: 1.8em; 55 | text-align: center; 56 | } 57 | .ui-datepicker .ui-datepicker-title select { 58 | font-size: 1em; 59 | margin: 1px 0; 60 | } 61 | .ui-datepicker select.ui-datepicker-month, 62 | .ui-datepicker select.ui-datepicker-year { 63 | width: 45%; 64 | } 65 | .ui-datepicker table { 66 | width: 100%; 67 | font-size: .9em; 68 | border-collapse: collapse; 69 | margin: 0 0 .4em; 70 | } 71 | .ui-datepicker th { 72 | padding: .7em .3em; 73 | text-align: center; 74 | font-weight: bold; 75 | border: 0; 76 | } 77 | .ui-datepicker td { 78 | border: 0; 79 | padding: 1px; 80 | } 81 | .ui-datepicker td span, 82 | .ui-datepicker td a { 83 | display: block; 84 | padding: .2em; 85 | text-align: right; 86 | text-decoration: none; 87 | } 88 | .ui-datepicker .ui-datepicker-buttonpane { 89 | background-image: none; 90 | margin: .7em 0 0 0; 91 | padding: 0 .2em; 92 | border-left: 0; 93 | border-right: 0; 94 | border-bottom: 0; 95 | } 96 | .ui-datepicker .ui-datepicker-buttonpane button { 97 | float: right; 98 | margin: .5em .2em .4em; 99 | cursor: pointer; 100 | padding: .2em .6em .3em .6em; 101 | width: auto; 102 | overflow: visible; 103 | } 104 | .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { 105 | float: left; 106 | } 107 | 108 | /* with multiple calendars */ 109 | .ui-datepicker.ui-datepicker-multi { 110 | width: auto; 111 | } 112 | .ui-datepicker-multi .ui-datepicker-group { 113 | float: left; 114 | } 115 | .ui-datepicker-multi .ui-datepicker-group table { 116 | width: 95%; 117 | margin: 0 auto .4em; 118 | } 119 | .ui-datepicker-multi-2 .ui-datepicker-group { 120 | width: 50%; 121 | } 122 | .ui-datepicker-multi-3 .ui-datepicker-group { 123 | width: 33.3%; 124 | } 125 | .ui-datepicker-multi-4 .ui-datepicker-group { 126 | width: 25%; 127 | } 128 | .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, 129 | .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { 130 | border-left-width: 0; 131 | } 132 | .ui-datepicker-multi .ui-datepicker-buttonpane { 133 | clear: left; 134 | } 135 | .ui-datepicker-row-break { 136 | clear: both; 137 | width: 100%; 138 | font-size: 0; 139 | } 140 | 141 | /* RTL support */ 142 | .ui-datepicker-rtl { 143 | direction: rtl; 144 | } 145 | .ui-datepicker-rtl .ui-datepicker-prev { 146 | right: 2px; 147 | left: auto; 148 | } 149 | .ui-datepicker-rtl .ui-datepicker-next { 150 | left: 2px; 151 | right: auto; 152 | } 153 | .ui-datepicker-rtl .ui-datepicker-prev:hover { 154 | right: 1px; 155 | left: auto; 156 | } 157 | .ui-datepicker-rtl .ui-datepicker-next:hover { 158 | left: 1px; 159 | right: auto; 160 | } 161 | .ui-datepicker-rtl .ui-datepicker-buttonpane { 162 | clear: right; 163 | } 164 | .ui-datepicker-rtl .ui-datepicker-buttonpane button { 165 | float: left; 166 | } 167 | .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, 168 | .ui-datepicker-rtl .ui-datepicker-group { 169 | float: right; 170 | } 171 | .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, 172 | .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { 173 | border-right-width: 0; 174 | border-left-width: 1px; 175 | } 176 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /Content/themes/base/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Content/themes/base/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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,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"); 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Content/ui-bootstrap-csp.css: -------------------------------------------------------------------------------- 1 | /* Include this file in your html if you are using the CSP mode. */ 2 | 3 | .ng-animate.item:not(.left):not(.right) { 4 | -webkit-transition: 0s ease-in-out left; 5 | transition: 0s ease-in-out left 6 | } 7 | .uib-tab > div { 8 | position: relative; 9 | display: block; 10 | padding: 10px 15px; 11 | outline: 0; 12 | color: #337ab7; 13 | } 14 | .uib-tab > div:focus, 15 | .uib-tab > div:hover { 16 | background-color: #eee; 17 | color: #23527c; 18 | } 19 | .uib-tab.disabled > div { 20 | color: #777; 21 | } 22 | .uib-tab.disabled > div:focus, 23 | .uib-tab.disabled > div:hover { 24 | color: #777; 25 | cursor: not-allowed; 26 | background-color: transparent; 27 | } 28 | .nav-tabs > .uib-tab > div { 29 | margin-right: 2px; 30 | line-height: 1.42857143; 31 | border: 1px solid transparent; 32 | border-radius: 4px 4px 0 0; 33 | } 34 | .nav-tabs > .uib-tab > div:hover { 35 | border-color: #eee #eee #ddd; 36 | } 37 | .nav-tabs > .uib-tab.active > div, 38 | .nav-tabs > .uib-tab.active > div:focus, 39 | .nav-tabs > .uib-tab.active > div:hover { 40 | color: #555; 41 | cursor: default; 42 | background-color: #fff; 43 | border-color: #ddd #ddd transparent #ddd; 44 | } 45 | .nav-pills > .uib-tab > div { 46 | border-radius: 4px; 47 | } 48 | .nav-pills > .uib-tab.active > div, 49 | .nav-pills > .uib-tab.active > div:focus, 50 | .nav-pills > .uib-tab.active > div:hover { 51 | color: #fff; 52 | background-color: #337ab7; 53 | } -------------------------------------------------------------------------------- /Controllers/AnswerController.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System.Collections.Generic; 14 | using DotNetNuke.Data; 15 | using RalphWilliams.Modules.DNNVideoCourse.Entities; 16 | 17 | namespace RalphWilliams.Modules.DNNVideoCourse.Controllers 18 | { 19 | class AnswerController 20 | { 21 | public void CreateAnswer(AnswerInfo a) 22 | { 23 | using (IDataContext ctx = DataContext.Instance()) 24 | { 25 | var rep = ctx.GetRepository(); 26 | rep.Insert(a); 27 | } 28 | } 29 | 30 | public void DeleteAnswer(int answerId, int moduleId) 31 | { 32 | var a = GetAnswer(answerId, moduleId); 33 | DeleteAnswer(a); 34 | } 35 | 36 | public void DeleteAnswer(AnswerInfo a) 37 | { 38 | using (IDataContext ctx = DataContext.Instance()) 39 | { 40 | var rep = ctx.GetRepository(); 41 | rep.Delete(a); 42 | } 43 | } 44 | 45 | public IEnumerable GetAnswers(int moduleId) 46 | { 47 | IEnumerable a; 48 | using (IDataContext ctx = DataContext.Instance()) 49 | { 50 | var rep = ctx.GetRepository(); 51 | a = rep.Get(moduleId); 52 | } 53 | return a; 54 | } 55 | public AnswerInfo GetAnswer(int answerId, int moduleId) 56 | { 57 | AnswerInfo a = null; 58 | using (IDataContext ctx = DataContext.Instance()) 59 | { 60 | var rep = ctx.GetRepository(); 61 | a = rep.GetById(answerId, moduleId); 62 | } 63 | return a; 64 | } 65 | public void UpdateAnswer(AnswerInfo a) 66 | { 67 | using (IDataContext ctx = DataContext.Instance()) 68 | { 69 | var rep = ctx.GetRepository(); 70 | rep.Update(a); 71 | } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /Controllers/QuestionController.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System.Collections.Generic; 14 | using DotNetNuke.Data; 15 | using RalphWilliams.Modules.DNNVideoCourse.Entities; 16 | 17 | namespace RalphWilliams.Modules.DNNVideoCourse.Controllers 18 | { 19 | class QuestionController 20 | { 21 | public void CreateQuestion(QuestionInfo q) 22 | { 23 | using (IDataContext ctx = DataContext.Instance()) 24 | { 25 | var rep = ctx.GetRepository(); 26 | rep.Insert(q); 27 | } 28 | } 29 | 30 | public void DeleteQuestion(int questionId, int moduleId) 31 | { 32 | var q = GetQuestion(questionId, moduleId); 33 | DeleteQuestion(q); 34 | } 35 | 36 | public void DeleteQuestion(QuestionInfo q) 37 | { 38 | using (IDataContext ctx = DataContext.Instance()) 39 | { 40 | var rep = ctx.GetRepository(); 41 | rep.Delete(q); 42 | } 43 | } 44 | 45 | public IEnumerable GetQuestions(int moduleId) 46 | { 47 | IEnumerable q; 48 | using (IDataContext ctx = DataContext.Instance()) 49 | { 50 | var rep = ctx.GetRepository(); 51 | q = rep.Get(moduleId); 52 | } 53 | return q; 54 | } 55 | 56 | public QuestionInfo GetQuestion(int questionId, int moduleId) 57 | { 58 | QuestionInfo q = null; 59 | using (IDataContext ctx = DataContext.Instance()) 60 | { 61 | var rep = ctx.GetRepository(); 62 | q = rep.GetById(questionId, moduleId); 63 | } 64 | return q; 65 | } 66 | 67 | public void UpdateQuestion(QuestionInfo q) 68 | { 69 | using (IDataContext ctx = DataContext.Instance()) 70 | { 71 | var rep = ctx.GetRepository(); 72 | rep.Update(q); 73 | } 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /Controllers/RoleController.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System.Collections.Generic; 14 | using System.Linq; 15 | using DotNetNuke.Common.Utilities; 16 | using DotNetNuke.Entities.Users; 17 | using DotNetNuke.Security.Roles; 18 | 19 | namespace RalphWilliams.Modules.DNNVideoCourse.Controllers 20 | { 21 | public class RoleController 22 | { 23 | private const string ROLE_GROUP_PREFIX = "DVC_"; 24 | 25 | /// 26 | /// Gets the role groups. 27 | /// 28 | /// The portal identifier. 29 | /// 30 | public static List GetRoleGroups(int portalId) 31 | { 32 | // This is necessary because the DNN core will cache a different version of the Roles property for various requests, affecting other users. 33 | DataCache.ClearCache(string.Format(DataCache.RoleGroupsCacheKey, portalId)); 34 | 35 | var roleGroups = DotNetNuke.Security.Roles.RoleController.GetRoleGroups(portalId).Cast().Where(r => r.RoleGroupName.Contains(ROLE_GROUP_PREFIX)).ToList(); 36 | 37 | return roleGroups; 38 | } 39 | 40 | /// 41 | /// Gets the user roles. 42 | /// 43 | /// The user information. 44 | /// 45 | public static List GetUserRoles(UserInfo userInfo) 46 | { 47 | return DotNetNuke.Security.Roles.RoleController.Instance.GetUserRoles(userInfo, true).ToList(); 48 | } 49 | 50 | /// 51 | /// Gets the name of the role group by. 52 | /// 53 | /// The portal identifier. 54 | /// Name of the role group. 55 | /// 56 | public static RoleGroupInfo GetRoleGroupByName(int portalId, string roleGroupName) 57 | { 58 | return DotNetNuke.Security.Roles.RoleController.GetRoleGroupByName(portalId, roleGroupName); 59 | } 60 | 61 | /// 62 | /// Gets the users by role. 63 | /// 64 | /// The portal identifier. 65 | /// Name of the role. 66 | /// 67 | public static List GetUsersByRole(int portalId, string roleName) 68 | { 69 | return DotNetNuke.Security.Roles.RoleController.Instance.GetUsersByRole(portalId, roleName).ToList(); 70 | } 71 | 72 | /// 73 | /// Gets the roles by role group identifier. 74 | /// 75 | /// The portal identifier. 76 | /// The role group identifier. 77 | /// 78 | public static List GetRolesByRoleGroupID(int portalId, int roleGroupId) 79 | { 80 | return DotNetNuke.Security.Roles.RoleController.Instance.GetRoles(portalId).Where(r => r.RoleGroupID == roleGroupId).ToList(); 81 | } 82 | 83 | } 84 | } -------------------------------------------------------------------------------- /Controllers/VideoController.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System.Collections.Generic; 14 | using DotNetNuke.Data; 15 | using RalphWilliams.Modules.DNNVideoCourse.Entities; 16 | 17 | namespace RalphWilliams.Modules.DNNVideoCourse.Controllers 18 | { 19 | class VideoController 20 | { 21 | public void CreateVideo(VideoInfo v) 22 | { 23 | using (IDataContext ctx = DataContext.Instance()) 24 | { 25 | var rep = ctx.GetRepository(); 26 | rep.Insert(v); 27 | } 28 | } 29 | 30 | public void DeleteVideo(int videoId, int moduleId) 31 | { 32 | var v = GetVideo(videoId, moduleId); 33 | DeleteVideo(v); 34 | } 35 | 36 | public void DeleteVideo(VideoInfo v) 37 | { 38 | using (IDataContext ctx = DataContext.Instance()) 39 | { 40 | var rep = ctx.GetRepository(); 41 | rep.Delete(v); 42 | } 43 | } 44 | 45 | public IEnumerable GetVideos(int moduleId) 46 | { 47 | IEnumerable v; 48 | using (IDataContext ctx = DataContext.Instance()) 49 | { 50 | var rep = ctx.GetRepository(); 51 | v = rep.Get(moduleId); 52 | } 53 | return v; 54 | } 55 | 56 | public VideoInfo GetVideo(int videoId, int moduleId) 57 | { 58 | VideoInfo v = null; 59 | using (IDataContext ctx = DataContext.Instance()) 60 | { 61 | var rep = ctx.GetRepository(); 62 | v = rep.GetById(videoId, moduleId); 63 | } 64 | return v; 65 | } 66 | 67 | public void UpdateVideo(VideoInfo v) 68 | { 69 | using (IDataContext ctx = DataContext.Instance()) 70 | { 71 | var rep = ctx.GetRepository(); 72 | rep.Update(v); 73 | } 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /Entities/AnswerInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | using System.Web.Caching; 15 | using DotNetNuke.ComponentModel.DataAnnotations; 16 | 17 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 18 | { 19 | [TableName("DNNVideoCourse_Answers")] 20 | //setup the primary key for table 21 | [PrimaryKey("AnswerId", AutoIncrement = true)] 22 | //configure caching using PetaPoco 23 | [Cacheable("Answers", CacheItemPriority.Default, 20)] 24 | //scope the objects to the ModuleId of a module on a page (or copy of a module on a page) 25 | [Scope("ModuleId")] 26 | public class AnswerInfo 27 | { 28 | /// 29 | /// The ID of your object with the name of the VideoName 30 | /// 31 | public int AnswerId { get; set; } 32 | /// 33 | /// A string with the name of the VideoName 34 | /// 35 | public int QuestionId { get; set; } 36 | 37 | public int OrderIndex { get; set; } 38 | 39 | public string AnswerText { get; set; } 40 | 41 | /// 42 | /// An integer with the user id of the assigned user for the object 43 | /// 44 | public int AssignedUserId { get; set; } 45 | 46 | /// 47 | /// The ModuleId of where the object was created and gets displayed 48 | /// 49 | public int ModuleId { get; set; } 50 | 51 | /// 52 | /// An integer for the user id of the user who created the object 53 | /// 54 | public int CreatedByUserId { get; set; } 55 | 56 | /// 57 | /// An integer for the user id of the user who last updated the object 58 | /// 59 | public int LastModifiedByUserId { get; set; } 60 | 61 | /// 62 | /// The date the object was created 63 | /// 64 | public DateTime CreatedOnDate { get; set; } 65 | 66 | /// 67 | /// The date the object was updated 68 | /// 69 | public DateTime LastModifiedOnDate { get; set; } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Entities/NewAnswerDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 16 | { 17 | // [Serializable] 18 | public class NewAnswerDTO 19 | { 20 | public int AnswerId { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Entities/NewQuestionDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 16 | { 17 | // [Serializable] 18 | public class NewQuestionDTO 19 | { 20 | public int QuestionId { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Entities/NewRoleDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 16 | { 17 | public class NewRoleDTO 18 | { 19 | public string Name { get; set; } 20 | public int RoleGroup { get; set; } 21 | public int RoleId { get; set; } 22 | public int Status { get; set; } 23 | 24 | public static implicit operator int(NewRoleDTO v) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Entities/NewRoleGroupDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 16 | { 17 | public class NewRoleGroupDTO 18 | { 19 | public string Name { get; set; } 20 | public int RoleGroupID { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Entities/NewVideoDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 16 | { 17 | // [Serializable] 18 | public class NewVideoDTO 19 | { 20 | public int VideoId { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Entities/QuestionInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | using System.Web.Caching; 15 | using DotNetNuke.ComponentModel.DataAnnotations; 16 | 17 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 18 | { 19 | [TableName("DNNVideoCourse_Questions")] 20 | //setup the primary key for table 21 | [PrimaryKey("QuestionId", AutoIncrement = true)] 22 | //configure caching using PetaPoco 23 | [Cacheable("Questions", CacheItemPriority.Default, 20)] 24 | //scope the objects to the ModuleId of a module on a page (or copy of a module on a page) 25 | [Scope("ModuleId")] 26 | public class QuestionInfo 27 | { 28 | /// 29 | /// The ID of your object with the name of the VideoName 30 | /// 31 | public int QuestionId { get; set; } 32 | /// 33 | /// A string with the name of the VideoName 34 | /// 35 | public int VideoId { get; set; } 36 | 37 | public int OrderIndex { get; set; } 38 | 39 | public string QuestionText { get; set; } 40 | 41 | /// 42 | /// An integer with the user id of the assigned user for the object 43 | /// 44 | public int AssignedUserId { get; set; } 45 | 46 | /// 47 | /// The ModuleId of where the object was created and gets displayed 48 | /// 49 | public int ModuleId { get; set; } 50 | 51 | /// 52 | /// An integer for the user id of the user who created the object 53 | /// 54 | public int CreatedByUserId { get; set; } 55 | 56 | /// 57 | /// An integer for the user id of the user who last updated the object 58 | /// 59 | public int LastModifiedByUserId { get; set; } 60 | 61 | /// 62 | /// The date the object was created 63 | /// 64 | public DateTime CreatedOnDate { get; set; } 65 | 66 | /// 67 | /// The date the object was updated 68 | /// 69 | public DateTime LastModifiedOnDate { get; set; } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Entities/RoleGroupsInListDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | using System.Collections.Generic; 15 | 16 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 17 | { 18 | [Serializable] 19 | public class RoleGroupsInListDTO 20 | { 21 | public string Name { get; set; } 22 | public int Id { get; set; } 23 | public List Roles { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /Entities/RolesInListDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | using System.Collections.Generic; 15 | 16 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 17 | { 18 | [Serializable] 19 | public class RolesInListDTO 20 | { 21 | public string Name { get; set; } 22 | public int Id { get; set; } 23 | public List Users { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /Entities/SubjLineDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 16 | { 17 | public class SubjLineDTO 18 | { 19 | public string Title { get; set; } 20 | public int RoleId { get; set; } 21 | public int CategoryId { get; set; } 22 | public string Body { get; set; } 23 | public string SubjectTitle { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /Entities/UsersInRoleDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 16 | { 17 | [Serializable] 18 | public class UsersInRoleDTO 19 | { 20 | public string FirstName { get; set; } 21 | public string LastName { get; set; } 22 | public string DisplayName { get; set; } 23 | public string Email { get; set; } 24 | public int UserId { get; set; } 25 | public string Videos { get; set; } 26 | } 27 | } -------------------------------------------------------------------------------- /Entities/VideoInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | using System.Web.Caching; 15 | using DotNetNuke.ComponentModel.DataAnnotations; 16 | 17 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 18 | { 19 | [TableName("DNNVideoCourse_Videos")] 20 | //setup the primary key for table 21 | [PrimaryKey("VideoId", AutoIncrement = true)] 22 | //configure caching using PetaPoco 23 | [Cacheable("Videos", CacheItemPriority.Default, 20)] 24 | //scope the objects to the ModuleId of a module on a page (or copy of a module on a page) 25 | [Scope("ModuleId")] 26 | public class VideoInfo 27 | { 28 | /// 29 | /// The ID of your object with the name of the VideoName 30 | /// 31 | public int VideoId { get; set; } 32 | /// 33 | /// A string with the name of the VideoName 34 | /// 35 | public int VimeoId { get; set; } 36 | 37 | public int OrderIndex { get; set; } 38 | 39 | public int CourseId { get; set; } 40 | 41 | /// 42 | /// An integer with the user id of the assigned user for the object 43 | /// 44 | public int AssignedUserId { get; set; } 45 | 46 | /// 47 | /// The ModuleId of where the object was created and gets displayed 48 | /// 49 | public int ModuleId { get; set; } 50 | 51 | /// 52 | /// An integer for the user id of the user who created the object 53 | /// 54 | public int CreatedByUserId { get; set; } 55 | 56 | /// 57 | /// An integer for the user id of the user who last updated the object 58 | /// 59 | public int LastModifiedByUserId { get; set; } 60 | 61 | /// 62 | /// The date the object was created 63 | /// 64 | public DateTime CreatedOnDate { get; set; } 65 | 66 | /// 67 | /// The date the object was updated 68 | /// 69 | public DateTime LastModifiedOnDate { get; set; } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Entities/VideosCompletedDTO.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using System; 14 | using System.Collections.Generic; 15 | 16 | namespace RalphWilliams.Modules.DNNVideoCourse.Entities 17 | { 18 | [Serializable] 19 | public class VideosCompletedDTO 20 | { 21 | public string Name { get; set; } 22 | public int Id { get; set; } 23 | public List Users { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /Images/jetbrains-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Images/jetbrains-logo.png -------------------------------------------------------------------------------- /Images/logo_min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/Images/logo_min.png -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Ralph Williams Consulting, LLC 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of DNNVideoCourseModule nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /License.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Ralph Williams, Jr. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of DNNVideoCourseModule nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Models/RouteMapper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ' Copyright (c) 2015 Ralph Williams (RalphWilliams.com) 3 | ' All rights reserved. 4 | ' 5 | ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 6 | ' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 7 | ' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 8 | ' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 9 | ' DEALINGS IN THE SOFTWARE. 10 | ' 11 | */ 12 | 13 | using DotNetNuke.Web.Api; 14 | 15 | namespace RalphWilliams.Modules.DNNVideoCourse.Models 16 | { 17 | public class RouteMapper : IServiceRouteMapper 18 | { 19 | public void RegisterRoutes(IMapRoute mapRouteManager) 20 | { 21 | mapRouteManager.MapHttpRoute("DNNVideoCourse", "default", "{controller}/{action}", new[] { "RalphWilliams.Modules.DNNVideoCourse.Models" }); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("DNNVideoCourse")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("DNNVideoCourse")] 12 | [assembly: AssemblyCopyright("Copyright © 2015 RalphWilliams.com")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("5ef01dd5-84a1-49f3-9232-067440288455")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Revision and Build Numbers 32 | // by using the '*' as shown below: 33 | [assembly: AssemblyVersion("01.00.05")] 34 | [assembly: AssemblyFileVersion("01.00.05")] 35 | -------------------------------------------------------------------------------- /Providers/DataProviders/SqlDataProvider/00.00.01.SqlDataProvider: -------------------------------------------------------------------------------- 1 | /************************************************************/ 2 | /***** SqlDataProvider *****/ 3 | /***** *****/ 4 | /***** *****/ 5 | /***** Note: To manually execute this script you must *****/ 6 | /***** perform a search and replace operation *****/ 7 | /***** for {databaseOwner} and {objectQualifier} *****/ 8 | /***** *****/ 9 | /************************************************************/ 10 | 11 | IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}DNNVideoCourse_Videos]') AND type in (N'U')) 12 | CREATE TABLE {databaseOwner}[{objectQualifier}DNNVideoCourse_Videos] 13 | ( 14 | videoId int NOT NULL IDENTITY (1, 1) 15 | CONSTRAINT [PK_{objectQualifier}DNNVideoCourse_Videos] PRIMARY KEY CLUSTERED, 16 | vimeoId int NOT NULL, 17 | orderIndex int NOT NULL, 18 | courseId int NOT NULL, 19 | AssignedUserId int NULL, 20 | ModuleId int NOT NULL, 21 | CreatedOnDate datetime NOT NULL, 22 | CreatedByUserId int NOT NULL, 23 | LastModifiedOnDate datetime NOT NULL, 24 | LastModifiedByUserId int NOT NULL 25 | ) 26 | GO 27 | 28 | 29 | /************************************************************/ 30 | /***** SqlDataProvider *****/ 31 | /************************************************************/ -------------------------------------------------------------------------------- /Providers/DataProviders/SqlDataProvider/01.01.00.SqlDataProvider: -------------------------------------------------------------------------------- 1 | /************************************************************/ 2 | /***** SqlDataProvider *****/ 3 | /***** *****/ 4 | /***** *****/ 5 | /***** Note: To manually execute this script you must *****/ 6 | /***** perform a search and replace operation *****/ 7 | /***** for {databaseOwner} and {objectQualifier} *****/ 8 | /***** *****/ 9 | /************************************************************/ 10 | 11 | IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}DNNVideoCourse_Videos]') AND type in (N'U')) 12 | ALTER TABLE {databaseOwner}[{objectQualifier}DNNVideoCourse_Videos] ADD CONSTRAINT 13 | [PK_{objectQualifier}DNNVideoCourse_Videos] PRIMARY KEY CLUSTERED 14 | ( 15 | videoId 16 | ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 17 | 18 | GO 19 | 20 | 21 | /************************************************************/ 22 | /***** SqlDataProvider *****/ 23 | /************************************************************/ -------------------------------------------------------------------------------- /Providers/DataProviders/SqlDataProvider/01.02.00.SqlDataProvider: -------------------------------------------------------------------------------- 1 | /************************************************************/ 2 | /***** SqlDataProvider *****/ 3 | /***** *****/ 4 | /***** *****/ 5 | /***** Note: To manually execute this script you must *****/ 6 | /***** perform a search and replace operation *****/ 7 | /***** for {databaseOwner} and {objectQualifier} *****/ 8 | /***** *****/ 9 | /************************************************************/ 10 | 11 | IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}DNNVideoCourse_Videos]') AND type in (N'U')) 12 | ALTER TABLE {databaseOwner}[{objectQualifier}DNNVideoCourse_Videos] ADD CONSTRAINT 13 | [PK_{objectQualifier}DNNVideoCourse_Videos] PRIMARY KEY CLUSTERED 14 | ( 15 | videoId 16 | ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 17 | 18 | GO 19 | 20 | IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}DNNVideoCourse_Questions]') AND type in (N'U')) 21 | CREATE TABLE {databaseOwner}[{objectQualifier}DNNVideoCourse_Questions] 22 | ( 23 | QuestionId int NOT NULL IDENTITY (1, 1) 24 | CONSTRAINT [PK_{objectQualifier}DNNVideoCourse_Questions] PRIMARY KEY CLUSTERED, 25 | OrderIndex int NOT NULL, 26 | VideoId int NOT NULL, 27 | QuestionText nvarchar(1000) NOT NULL, 28 | AssignedUserId int NULL, 29 | ModuleId int NOT NULL, 30 | CreatedOnDate datetime NOT NULL, 31 | CreatedByUserId int NOT NULL, 32 | LastModifiedOnDate datetime NOT NULL, 33 | LastModifiedByUserId int NOT NULL 34 | ) 35 | GO 36 | 37 | IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}DNNVideoCourse_Answers]') AND type in (N'U')) 38 | CREATE TABLE {databaseOwner}[{objectQualifier}DNNVideoCourse_Answers] 39 | ( 40 | AnswerId int NOT NULL IDENTITY (1, 1) 41 | CONSTRAINT [PK_{objectQualifier}DNNVideoCourse_Answers] PRIMARY KEY CLUSTERED, 42 | OrderIndex int NOT NULL, 43 | QuestionId int NOT NULL, 44 | AnswerText nvarchar(max) NOT NULL, 45 | AssignedUserId int NULL, 46 | ModuleId int NOT NULL, 47 | CreatedOnDate datetime NOT NULL, 48 | CreatedByUserId int NOT NULL, 49 | LastModifiedOnDate datetime NOT NULL, 50 | LastModifiedByUserId int NOT NULL 51 | ) 52 | GO 53 | 54 | /************************************************************/ 55 | /***** SqlDataProvider *****/ 56 | /************************************************************/ -------------------------------------------------------------------------------- /Providers/DataProviders/SqlDataProvider/Uninstall.SqlDataProvider: -------------------------------------------------------------------------------- 1 | IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}DNNVideoCourse_Videos]') AND type in (N'U')) 2 | DROP TABLE {databaseOwner}[{objectQualifier}DNNVideoCourse_Videos] 3 | IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}DNNVideoCourse_Questions]') AND type in (N'U')) 4 | DROP TABLE {databaseOwner}[{objectQualifier}DNNVideoCourse_Questions] 5 | IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}DNNVideoCourse_Answers]') AND type in (N'U')) 6 | DROP TABLE {databaseOwner}[{objectQualifier}DNNVideoCourse_Answers] 7 | GO 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Module instructions http://ralphwilliams.github.io/DNNVideoCourseModule/ 2 | 3 | # DNNVideoCourseModule 4 | DNN SPA module that uses DNN Security Roles and Security Groups to create dynamic Courses and Categories. The course videos are created with Vimeo videos. 5 | 6 | ## Special Thanks 7 | ![Jetbrains](/Images/jetbrains-logo.png "Jetbrains") **JetBrains** 8 | 9 | ### Known Issues 10 | This module currently supports DNN 8 only. DNN 9 has known issues with managing users from within the module. 11 | 12 | ## Getting Started with Development 13 | 14 | 1. Begin with DNN 8.0.0 15 | 2. Put the repository into the following folder in your site: ~\DesktopModules\DNNVideoCourse\ 16 | 3. Build 17 | 4. Make sure the RalphWilliams.DNNVideoCourse.dll file is generated in the website bin folder 18 | 5. Run the SQL data provider script(s) 19 | 6. "Install" the module in DNN 20 | 7. Make sure the module shows on a page without error 21 | 8. Pick and/or create an issue in GitHub 22 | 9. Code 23 | 10. Submit a pull request 24 | 25 | ## About the Module 26 | ### What is the module? 27 | The DNN Video Course Module provides a way to create courses using videos that allow only the users in specific roles to view the course. The user can only watch videos that have been previously watched or the next unwatched video. The progress of each user is saved to allow the user to watch portions of the course and return to the site to continue watching at a later time. The progress of all the users can be reviewed by a site administrator. Once a user has completed their course, an email will be sent to the site administrator. 28 | 29 | ### How it works 30 | ## Roles and Categories 31 | This module leverages the built in functionality of DNN’s Security Categories and Security Roles. When a new category is created through the module, a new Role Group is created with a string of text (“CCV_”) prepended to the name. This allows the module to filter and show only Role Groups associated to the video course module. All Courses added to the Category will be a Security Role within that specific Role Group. 32 | 33 | ### User Progress 34 | During installation of the module, a new hidden User Profile property is added to the User Profile. As a video has been marked as complete by reaching the end of the video (a listener for the Vimeo API is used) the user’s profile is updated with the id for that video. 35 | 36 | ## Module Administration 37 | ### Installing the module 38 | This module is installed as any other DNN module is installed. 39 | 40 | 1. Once logged into the site as a host, navigate to Host > Extensions. 41 | 2. Click the Add Extension button and follow the prompts to install your module. 42 | 43 | ## Setting up the module 44 | Once the module has been installed, add the module to a page. Categories and Courses must be added prior to adding a video. There are no module settings for this module. There are 4 views, however. Course List view (default view), Video Player view, User Status view, Edit Categories and Courses view. 45 | 46 | ### Creating Categories and Courses 47 | 1. Navigate to the Edit Categories and Courses view by clicking the Course Admin dropdown and selecting “Edit Categories & Courses”. 48 | 2. Click the “Add A New Category button”. 49 | 3. Enter a name for the Category and click the “Add Category” button. 50 | 4. Add Courses to the Category by clicking the “Add A New Course” button. 51 | 5. Then, enter a name for the Course and click the “Add Course” button. 52 | 6. Navigate to the Video List view by clicking the “Return to List” button in the top right of the module. 53 | 54 | ### Adding Users to Courses 55 | 1. Navigate to the Edit Categories and Courses view. 56 | 2. Once a course has been created, add existing users to the course by clicking the Users icon for the course where the user will be added. 57 | 3. In the popup window, select the user from the dropdown and click the “Add User to Role” button. 58 | 4. Continue adding users to the course as needed. 59 | 5. Once all needed users have been added to the course, click the Close button. 60 | 61 | ### Removing Users from Courses 62 | 1. Navigate to the Edit Categories and Courses view. 63 | 2. Click the Users icon for the course from which the user will be removed. 64 | 3. In the popup window, click the delete icon for the user that is to be removed. 65 | 4. Once all needed users have been removed from the course, click the close button. 66 | 67 | ### Renaming Categories and Courses 68 | 1. Navigate to the Edit Categories and Courses view. 69 | 2. Click the edit icon to the right of the Category or Course. 70 | 3. Make the edit to the name and click the “Edit Category/Course Name” button. 71 | 72 | ### Archiving Courses 73 | A course can be archived, however, it cannot be deleted. If the course needs to be deleted, the role can be removed through the Security Roles in DNN Admin. However, note that deleting a Security Role does fully remove the Role from the database. This means that they Role name will not be able to be reused. 74 | 1. Navigate to the Edit Categories and Courses view. 75 | 2. To archive a course toggle the switch for the specified course to grey. 76 | 3. A course can be reactivated by toggling the switch back to green. 77 | 78 | ### Adding Videos to a Course 79 | 1. On the Course List view, click the “Edit Videos in Course” button on the right for the course. 80 | 2. Add the URL for a Vimeo video in the text box in the “Add new Video to Course” section and click the check mark. 81 | 3. Continue adding videos for the course. 82 | 4. To change the sort order, click and drag the thumbnail to the desired location. 83 | 84 | ### Removing a Video from a course 85 | 1. On the Course List view, click the “Edit Videos in Course” button on the right for the course. 86 | 2. Click the Edit icon to the right of the video to be removed. 87 | 3. Click the Delete button for the video. 88 | -------------------------------------------------------------------------------- /ReleaseNotes.txt: -------------------------------------------------------------------------------- 1 | 

DNN Video Course Module

2 |

Ralph Williams
Ralph Williams Consulting, LLC
me@ralphwilliams.com
http://www.ralphwilliams.com


3 |

About the DNN Video Course Module

4 |

This modue allows you to have a LMS-style video gallery experience for your website visitors, based on security roles, and security role groups.

5 |

Version 01.02.00

6 |

This Release includes the following:

7 |
Enhancements
8 |
  • Added Questions and Answers to Videos
9 |

Version 01.01.00

10 |

This Release includes the following:

11 |
Enhancements:
12 |
    13 |
  • Converted to DNN8 SPA module
  • 14 |
  • Renamed module to DNN Video Course
  • 15 |
  • Adds Custom Profile Property for saving User's progress to DNN on install.
  • 16 |
  • Create Categories (DNN Role Groups) and Courses (DNN Roles) directly from the module.
  • 17 |
  • Expand/Collapse functionality for Course list
  • 18 |
  • Adds localization
  • 19 |
  • Update design to be flexible for multiple skins
  • 20 |
  • Added progress bars to Courses on Video List View
  • 21 |
  • Added Webservice to get userId.
  • 22 |
  • Remove any excess files and other file cleanup
  • 23 |
  • Update readme file with new instructions
  • 24 |
25 |
Bug Fixes
26 |
    27 |
  • Course does not show to user after the Course has been renamed.
  • 28 |
  • Clean and organize CSS
  • 29 |
  • Updated Edit Ctrl to redirect non admin user to Video List View.
  • 30 |
  • Removed some excess files.
  • 31 |
32 | 33 |

Version 01.00.05

34 |

This update fixes the following bugs and adds the following features.

35 |
    36 |
  • Resolved: Email subject line did not include course title.
  • 37 |
  • Enhanced: Marks course complete automatically after final course video completes.
  • 38 |
  • Enhanced: When session times out and video attempts to mark complete, redirect to home page.
  • 39 |
40 | 41 |

Version 01.00.04

42 |

This update fixes the following bugs and adds the following features.

43 |
    44 |
  • Removed: Update Vimeo Id for current video to remove confusion.
  • 45 |
  • Enhanced: Minor style update for progress view
  • 46 |
47 | 48 |

Version 01.00.03

49 |

This update fixes the following bugs and adds the following features.

50 |
    51 |
  • Added: User Progress View
  • 52 |
  • Enhanced: Security for accessing courses
  • 53 |
  • Enhanced: Changed module namespace and updated code and files to match common code standards.
  • 54 |
55 | 56 |

Version 01.00.02

57 |

This update fixes the following bugs and adds the following features.

58 |
    59 |
  • Fixed: Next button not working on consecutive watched video.
  • 60 |
  • Enhanced: Saves progress on video completion, instead of clicking next button, except for course completion as this is still on button click
  • 61 |
  • Enhanced: Increased security for adding and removing videos
  • 62 |
  • Enhanced: Minor styling updates 63 |
      64 |
    • DNN Standard buttons
    • 65 |
    • Minor layout issues
    • 66 |
    • Minor layout issues on mobile
    • 67 |
    68 |
  • 69 |
  • Added: Video count in video player (Video x of y)
  • 70 |
71 | 72 |

Version 01.00.01

73 |

This update adds new styling and better organization of code.

74 | 75 |

Version 01.00.00

76 |

This is the initial release of the module.

77 | 78 |
-------------------------------------------------------------------------------- /Scripts/angular-messages.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.4.3 3 | (c) 2010-2015 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(A,h,B){'use strict';function v(h){return["$animate",function(q){return{restrict:"AE",transclude:"element",terminal:!0,require:"^^ngMessages",link:function(m,e,a,g,k){var c=e[0],n,l=a.ngMessage||a.when;a=a.ngMessageExp||a.whenExp;var p=function(d){n=d?w(d)?d:d.split(/[\s,]+/):null;g.reRender()};a?(p(m.$eval(a)),m.$watchCollection(a,p)):p(l);var f,r;g.register(c,r={test:function(d){var b=n;d=b?w(b)?0<=b.indexOf(d):b.hasOwnProperty(d):void 0;return d},attach:function(){f||k(m,function(d){q.enter(d, 7 | null,e);f=d;f.on("$destroy",function(){f&&(g.deregister(c),r.detach())})})},detach:function(){if(f){var d=f;f=null;q.leave(d)}}})}}}]}var w=h.isArray,x=h.forEach,y=h.isString,z=h.element;h.module("ngMessages",[]).directive("ngMessages",["$animate",function(h){function q(e,a){return y(a)&&0===a.length||m(e.$eval(a))}function m(e){return y(e)?e.length:!!e}return{require:"ngMessages",restrict:"AE",controller:["$element","$scope","$attrs",function(e,a,g){function k(a,d){for(var b=d,e=[];b&&b!==a;){var c= 8 | b.$$ngMessageNode;if(c&&c.length)return l[c];b.childNodes.length&&-1==e.indexOf(b)?(e.push(b),b=b.childNodes[b.childNodes.length-1]):b=b.previousSibling||b.parentNode}}var c=this,n=0,l=this.messages={},p,f;this.render=function(r){r=r||{};p=!1;f=r;for(var d=q(a,g.ngMessagesMultiple)||q(a,g.multiple),b=[],n={},s=c.head,k=!1,l=0;null!=s;){l++;var t=s.message,u=!1;k||x(r,function(b,a){!u&&m(b)&&t.test(a)&&!n[a]&&(u=n[a]=!0,t.attach())});u?k=!d:b.push(t);s=s.next}x(b,function(b){b.detach()});b.length!== 9 | l?h.setClass(e,"ng-active","ng-inactive"):h.setClass(e,"ng-inactive","ng-active")};a.$watchCollection(g.ngMessages||g["for"],c.render);this.reRender=function(){p||(p=!0,a.$evalAsync(function(){p&&f&&c.render(f)}))};this.register=function(a,d){var b=n.toString();l[b]={message:d};var g=e[0],f=l[b];c.head?(g=k(g,a))?(f.next=g.next,g.next=f):(f.next=c.head,c.head=f):c.head=f;a.$$ngMessageNode=b;n++;c.reRender()};this.deregister=function(a){var d=a.$$ngMessageNode;delete a.$$ngMessageNode;var b=l[d];(a= 10 | k(e[0],a))?a.next=b.next:c.head=b.next;delete l[d];c.reRender()}}]}}]).directive("ngMessagesInclude",["$templateRequest","$document","$compile",function(h,q,m){return{restrict:"AE",require:"^^ngMessages",link:function(e,a,g){var k=g.ngMessagesInclude||g.src;h(k).then(function(c){m(c)(e,function(c){a.after(c);c=z(q[0].createComment(" ngMessagesInclude: "+k+" "));a.after(c);a.remove()})})}}}]).directive("ngMessage",v("AE")).directive("ngMessageExp",v("A"))})(window,window.angular); 11 | //# sourceMappingURL=angular-messages.min.js.map 12 | -------------------------------------------------------------------------------- /Scripts/angular-messages.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-messages.min.js", 4 | "lineCount":10, 5 | "mappings":"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", 6 | "sources":["angular-messages.js"], 7 | "names":["window","angular","undefined","ngMessageDirectiveFactory","restrict","$animate","transclude","terminal","require","link","scope","element","attrs","ngMessagesCtrl","$transclude","commentNode","records","staticExp","ngMessage","when","dynamicExp","ngMessageExp","whenExp","assignRecords","items","isArray","split","reRender","$eval","$watchCollection","currentElement","messageCtrl","register","test","name","collection","indexOf","hasOwnProperty","attach","elm","enter","on","deregister","detach","leave","forEach","isString","jqLite","module","directive","isAttrTruthy","attr","length","truthy","val","controller","$element","$scope","$attrs","findPreviousMessage","parent","comment","prevNode","parentLookup","prevKey","$$ngMessageNode","messages","childNodes","push","previousSibling","parentNode","ctrl","latestKey","renderLater","cachedCollection","render","this.render","multiple","ngMessagesMultiple","unmatchedMessages","matchedKeys","messageItem","head","messageFound","totalMessages","message","messageUsed","value","key","next","setClass","ACTIVE_CLASS","INACTIVE_CLASS","ngMessages","this.reRender","$evalAsync","this.register","nextKey","toString","messageNode","match","this.deregister","$templateRequest","$document","$compile","src","ngMessagesInclude","then","html","contents","after","anchor","createComment","remove"] 8 | } 9 | -------------------------------------------------------------------------------- /Scripts/angular-route.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.4.3 3 | (c) 2010-2015 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(p,c,C){'use strict';function v(r,h,g){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,f,b,d,y){function z(){k&&(g.cancel(k),k=null);l&&(l.$destroy(),l=null);m&&(k=g.leave(m),k.then(function(){k=null}),m=null)}function x(){var b=r.current&&r.current.locals;if(c.isDefined(b&&b.$template)){var b=a.$new(),d=r.current;m=y(b,function(b){g.enter(b,null,m||f).then(function(){!c.isDefined(t)||t&&!a.$eval(t)||h()});z()});l=d.scope=b;l.$emit("$viewContentLoaded"); 7 | l.$eval(w)}else z()}var l,m,k,t=b.autoscroll,w=b.onload||"";a.$on("$routeChangeSuccess",x);x()}}}function A(c,h,g){return{restrict:"ECA",priority:-400,link:function(a,f){var b=g.current,d=b.locals;f.html(d.$template);var y=c(f.contents());b.controller&&(d.$scope=a,d=h(b.controller,d),b.controllerAs&&(a[b.controllerAs]=d),f.data("$ngControllerController",d),f.children().data("$ngControllerController",d));y(a)}}}p=c.module("ngRoute",["ng"]).provider("$route",function(){function r(a,f){return c.extend(Object.create(a), 8 | f)}function h(a,c){var b=c.caseInsensitiveMatch,d={originalPath:a,regexp:a},g=d.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,c,b,d){a="?"===d?d:null;d="*"===d?d:null;g.push({name:b,optional:!!a});c=c||"";return""+(a?"":c)+"(?:"+(a?c:"")+(d&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");d.regexp=new RegExp("^"+a+"$",b?"i":"");return d}var g={};this.when=function(a,f){var b=c.copy(f);c.isUndefined(b.reloadOnSearch)&&(b.reloadOnSearch=!0); 9 | c.isUndefined(b.caseInsensitiveMatch)&&(b.caseInsensitiveMatch=this.caseInsensitiveMatch);g[a]=c.extend(b,a&&h(a,b));if(a){var d="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[d]=c.extend({redirectTo:a},h(d,b))}return this};this.caseInsensitiveMatch=!1;this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,f,b,d,h,p,x){function l(b){var e=s.current; 10 | (v=(n=k())&&e&&n.$$route===e.$$route&&c.equals(n.pathParams,e.pathParams)&&!n.reloadOnSearch&&!w)||!e&&!n||a.$broadcast("$routeChangeStart",n,e).defaultPrevented&&b&&b.preventDefault()}function m(){var u=s.current,e=n;if(v)u.params=e.params,c.copy(u.params,b),a.$broadcast("$routeUpdate",u);else if(e||u)w=!1,(s.current=e)&&e.redirectTo&&(c.isString(e.redirectTo)?f.path(t(e.redirectTo,e.params)).search(e.params).replace():f.url(e.redirectTo(e.pathParams,f.path(),f.search())).replace()),d.when(e).then(function(){if(e){var a= 11 | c.extend({},e.resolve),b,f;c.forEach(a,function(b,e){a[e]=c.isString(b)?h.get(b):h.invoke(b,null,null,e)});c.isDefined(b=e.template)?c.isFunction(b)&&(b=b(e.params)):c.isDefined(f=e.templateUrl)&&(c.isFunction(f)&&(f=f(e.params)),c.isDefined(f)&&(e.loadedTemplateUrl=x.valueOf(f),b=p(f)));c.isDefined(b)&&(a.$template=b);return d.all(a)}}).then(function(f){e==s.current&&(e&&(e.locals=f,c.copy(e.params,b)),a.$broadcast("$routeChangeSuccess",e,u))},function(b){e==s.current&&a.$broadcast("$routeChangeError", 12 | e,u,b)})}function k(){var a,b;c.forEach(g,function(d,g){var q;if(q=!b){var h=f.path();q=d.keys;var l={};if(d.regexp)if(h=d.regexp.exec(h)){for(var k=1,m=h.length;k=c;d--)f.end&&f.end(e[d]);e.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,e=[],m=a,l;for(e.last=function(){return e[e.length-1]};a;){l="";k=!0;if(e.last()&&w[e.last()])a=a.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*"+e.last()+"[^>]*>","i"),function(a,b){b=b.replace(H,"$1").replace(I,"$1");f.chars&&f.chars(q(b));return""}),c("",e.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e", 8 | b)===b&&(f.comment&&f.comment(a.substring(4,b)),a=a.substring(b+3),k=!1);else if(x.test(a)){if(b=a.match(x))a=a.replace(b[0],""),k=!1}else if(J.test(a)){if(b=a.match(y))a=a.substring(b[0].length),b[0].replace(y,c),k=!1}else K.test(a)&&((b=a.match(z))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(z,d)),k=!1):(l+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),l+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),f.chars&&f.chars(q(l)))}if(a==m)throw L("badparse",a);m=a}c()}function q(a){if(!a)return"";A.innerHTML= 9 | a.replace(//g,">")}function r(a,f){var d=!1,c=h.bind(a,a.push);return{start:function(a,k,e){a=h.lowercase(a);!d&&w[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(k,function(d,e){var k=h.lowercase(e),g="img"===a&&"src"===k|| 10 | "background"===k;!0!==O[k]||!0===D[k]&&!f(d,g)||(c(" "),c(e),c('="'),c(B(d)),c('"'))}),c(e?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c(""));a==d&&(d=!1)},chars:function(a){d||c(B(a))}}}var L=h.$$minErr("$sanitize"),z=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,y=/^<\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^]*?)>/i, 11 | I=/"\u201d\u2019]/i,d=/^mailto:/i;return function(c,b){function k(a){a&&g.push(E(a))}function e(a, 15 | c){g.push("');k(c);g.push("")}if(!c)return c;for(var m,l=c,g=[],n,p;m=l.match(f);)n=m[0],m[2]||m[4]||(n=(m[3]?"http://":"mailto:")+n),p=m.index,k(l.substr(0,p)),e(n,m[0].replace(d,"")),l=l.substring(p+m[0].length);k(l);return a(g.join(""))}}])})(window,window.angular); 16 | //# sourceMappingURL=angular-sanitize.min.js.map 17 | -------------------------------------------------------------------------------- /Scripts/angular-touch.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.4.3 3 | (c) 2010-2015 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(x,s,y){'use strict';function t(f,k,p){n.directive(f,["$parse","$swipe",function(c,e){return function(l,m,g){function h(a){if(!b)return!1;var d=Math.abs(a.y-b.y);a=(a.x-b.x)*k;return r&&75>d&&0d/a}var d=c(g[f]),b,r,a=["touch"];s.isDefined(g.ngSwipeDisableMouse)||a.push("mouse");e.bind(m,{start:function(a,d){b=a;r=!0},cancel:function(a){r=!1},end:function(a,b){h(a)&&l.$apply(function(){m.triggerHandler(p);d(l,{$event:b})})}},a)}}])}var n=s.module("ngTouch",[]);n.factory("$swipe", 7 | [function(){function f(c){c=c.originalEvent||c;var e=c.touches&&c.touches.length?c.touches:[c];c=c.changedTouches&&c.changedTouches[0]||e[0];return{x:c.clientX,y:c.clientY}}function k(c,e){var l=[];s.forEach(c,function(c){(c=p[c][e])&&l.push(c)});return l.join(" ")}var p={mouse:{start:"mousedown",move:"mousemove",end:"mouseup"},touch:{start:"touchstart",move:"touchmove",end:"touchend",cancel:"touchcancel"}};return{bind:function(c,e,l){var m,g,h,d,b=!1;l=l||["mouse","touch"];c.on(k(l,"start"),function(a){h= 8 | f(a);b=!0;g=m=0;d=h;e.start&&e.start(h,a)});var r=k(l,"cancel");if(r)c.on(r,function(a){b=!1;e.cancel&&e.cancel(a)});c.on(k(l,"move"),function(a){if(b&&h){var c=f(a);m+=Math.abs(c.x-d.x);g+=Math.abs(c.y-d.y);d=c;10>m&&10>g||(g>m?(b=!1,e.cancel&&e.cancel(a)):(a.preventDefault(),e.move&&e.move(c,a)))}});c.on(k(l,"end"),function(a){b&&(b=!1,e.end&&e.end(f(a),a))})}}}]);n.config(["$provide",function(f){f.decorator("ngClickDirective",["$delegate",function(k){k.shift();return k}])}]);n.directive("ngClick", 9 | ["$parse","$timeout","$rootElement",function(f,k,p){function c(d,b,c){for(var a=0;aMath.abs(d[a]-b)&&25>Math.abs(e-g))return d.splice(a,a+2),!0}return!1}function e(d){if(!(2500e&&1>b||h&&h[0]===e&&h[1]===b)){h&&(h=null);var a=d.target;"label"===s.lowercase(a.nodeName||a[0]&&a[0].nodeName)&&(h=[e,b]);c(g,e,b)||(d.stopPropagation(),d.preventDefault(),d.target&& 10 | d.target.blur&&d.target.blur())}}}function l(d){d=d.touches&&d.touches.length?d.touches:[d];var b=d[0].clientX,c=d[0].clientY;g.push(b,c);k(function(){for(var a=0;ad&&12>w&&(g||(p[0].addEventListener("click",e,!0),p[0].addEventListener("touchstart",l,!0),g=[]),m=Date.now(),c(g,f,u),q&&q.blur(),s.isDefined(h.disabled)&& 12 | !1!==h.disabled||b.triggerHandler("click",[a]));k=!1;b.removeClass("ng-click-active")});b.onclick=function(a){};b.on("click",function(b,c){d.$apply(function(){a(d,{$event:c||b})})});b.on("mousedown",function(a){b.addClass("ng-click-active")});b.on("mousemove mouseup",function(a){b.removeClass("ng-click-active")})}}]);t("ngSwipeLeft",-1,"swipeleft");t("ngSwipeRight",1,"swiperight")})(window,window.angular); 13 | //# sourceMappingURL=angular-touch.min.js.map 14 | -------------------------------------------------------------------------------- /Scripts/angular-ui-ieshiv.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AngularUI - The companion suite for AngularJS 3 | * @version v0.4.0 - 2013-02-15 4 | * @link http://angular-ui.github.com 5 | * @license MIT License, http://www.opensource.org/licenses/MIT 6 | */ 7 | 8 | // READ: http://docs-next.angularjs.org/guide/ie 9 | // element tags are statically defined in order to accommodate lazy-loading whereby directives are also unknown 10 | 11 | // The ieshiv takes care of our ui.directives and AngularJS's ng-view, ng-include, ng-pluralize, ng-switch. 12 | // However, IF you have custom directives that can be used as html tags (yours or someone else's) then 13 | // add list of directives into window.myCustomTags 14 | 15 | // 21 | 22 | (function (exports) { 23 | 24 | var debug = window.ieShivDebug || false, 25 | tags = [ "ngInclude", "ngPluralize", "ngView", "ngSwitch", "uiCurrency", "uiCodemirror", "uiDate", "uiEvent", 26 | "uiKeypress", "uiKeyup", "uiKeydown", "uiMask", "uiMapInfoWindow", "uiMapMarker", "uiMapPolyline", 27 | "uiMapPolygon", "uiMapRectangle", "uiMapCircle", "uiMapGroundOverlay", "uiModal", "uiReset", 28 | "uiScrollfix", "uiSelect2", "uiShow", "uiHide", "uiToggle", "uiSortable", "uiTinymce" 29 | ]; 30 | 31 | window.myCustomTags = window.myCustomTags || []; // externally defined by developer using angular-ui directives 32 | tags.push.apply(tags, window.myCustomTags); 33 | 34 | var toCustomElements = function (str) { 35 | var result = []; 36 | var dashed = str.replace(/([A-Z])/g, function ($1) { 37 | return " " + $1.toLowerCase(); 38 | }); 39 | var tokens = dashed.split(' '); 40 | var ns = tokens[0]; 41 | var dirname = tokens.slice(1).join('-'); 42 | 43 | // this is finite list and it seemed senseless to create a custom method 44 | result.push(ns + ":" + dirname); 45 | result.push(ns + "-" + dirname); 46 | result.push("x-" + ns + "-" + dirname); 47 | result.push("data-" + ns + "-" + dirname); 48 | return result; 49 | }; 50 | 51 | for (var i = 0, tlen = tags.length; i < tlen; i++) { 52 | var customElements = toCustomElements(tags[i]); 53 | for (var j = 0, clen = customElements.length; j < clen; j++) { 54 | var customElement = customElements[j]; 55 | document.createElement(customElement); 56 | } 57 | } 58 | 59 | })(window); -------------------------------------------------------------------------------- /Scripts/angular-ui-ieshiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AngularUI - The companion suite for AngularJS 3 | * @version v0.4.0 - 2013-02-15 4 | * @link http://angular-ui.github.com 5 | * @license MIT License, http://www.opensource.org/licenses/MIT 6 | */ 7 | (function(e){var t=window.ieShivDebug||!1,n=["ngInclude","ngPluralize","ngView","ngSwitch","uiCurrency","uiCodemirror","uiDate","uiEvent","uiKeypress","uiKeyup","uiKeydown","uiMask","uiMapInfoWindow","uiMapMarker","uiMapPolyline","uiMapPolygon","uiMapRectangle","uiMapCircle","uiMapGroundOverlay","uiModal","uiReset","uiScrollfix","uiSelect2","uiShow","uiHide","uiToggle","uiSortable","uiTinymce"];window.myCustomTags=window.myCustomTags||[],n.push.apply(n,window.myCustomTags);var r=function(e){var t=[],n=e.replace(/([A-Z])/g,function(e){return" "+e.toLowerCase()}),r=n.split(" "),i=r[0],s=r.slice(1).join("-");return t.push(i+":"+s),t.push(i+"-"+s),t.push("x-"+i+"-"+s),t.push("data-"+i+"-"+s),t};for(var i=0,s=n.length;i 22 | var d = new Date(); 23 | var moduleId = parseInt("[ModuleContext:ModuleId]"); 24 | var portalId = parseInt("[ModuleContext:PortalId]"); 25 | var sf = $.ServicesFramework(moduleId); 26 | var moduleName = "DNNVideoCourse"; 27 | if ("[ModuleContext:EditMode]" === 'True') var editMode = true; 28 | var currentDate = d; 29 | 30 |
31 |
-------------------------------------------------------------------------------- /fonts/BebasNeue.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/fonts/BebasNeue.otf -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/fonts/icomoon.eot -------------------------------------------------------------------------------- /fonts/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/fonts/icomoon.ttf -------------------------------------------------------------------------------- /fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralphwilliams/DNNVideoCourseModule/751c2352d15b5521b02d16a623d00608f133355c/fonts/icomoon.woff -------------------------------------------------------------------------------- /ng/Controllers/answerListCtrl.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | angular 5 | .module('videoControllers') 6 | .controller('answerListCtrl', 7 | [ 8 | '$scope', 9 | '$http', 10 | '$routeParams', 11 | 'answersFactory', 12 | 'questionsFactory', 13 | 'videosFactory', 14 | 'categoriesFactory', 15 | 'vimeoFactory', 16 | 'localizationFactory', 17 | '$location', 18 | function ( 19 | $scope, 20 | $http, 21 | $routeParams, 22 | answersFactory, 23 | questionsFactory, 24 | videosFactory, 25 | categoriesFactory, 26 | vimeoFactory, 27 | localizationFactory, 28 | $location 29 | ) { 30 | 31 | // #region Controller Global Variables 32 | $scope.viewMode; 33 | 34 | if (typeof editMode !== 'undefined' || $scope.editMode === true) { 35 | $scope.editMode = true; 36 | } else { 37 | $scope.editMode = false; 38 | } 39 | if ($scope.editMode) { 40 | $scope.returnText = 'Return to Course Progress'; 41 | } else { 42 | $scope.returnText = 'Return to Course List'; 43 | } 44 | // #region Get Data from sources 45 | var thisCourse = parseInt($routeParams.CourseId), 46 | thisUser = parseInt($routeParams.UserId); 47 | 48 | // Get user's Answers 49 | if ($scope.editMode) { 50 | answersFactory.callUserAnswersDataAdmin(thisUser) 51 | .then(function(data) { 52 | $scope.answers = angular.fromJson(data); 53 | angular.forEach($scope.userData, 54 | function(valueCategory) { 55 | valueCategory.Name = valueCategory.Name.replace('DVC_', ''); 56 | }); 57 | loadVids(); 58 | }, 59 | function(data) { 60 | console.log('Error Getting User Data'); 61 | console.log(data); 62 | }); 63 | } else { 64 | answersFactory.callUserAnswersData() 65 | .then(function (data) { 66 | $scope.answers = angular.fromJson(data); 67 | angular.forEach($scope.userData, function (valueCategory) { 68 | valueCategory.Name = valueCategory.Name.replace('DVC_', ''); 69 | }); 70 | loadVids(); 71 | }, function (data) { 72 | console.log('Error Getting User Data'); 73 | console.log(data); 74 | }); 75 | } 76 | 77 | // Get Vimeo Data 78 | function callVimeo(vimeoId, loadVimeoData) { 79 | vimeoFactory.callVimeoData(parseInt(vimeoId)) 80 | .then(function (data) { 81 | $scope.vimeo = data; 82 | loadVimeoData(data); 83 | }, function (data) { 84 | alert('vimeo Ajax Fail'); 85 | }); 86 | } 87 | 88 | // Get Categories 89 | categoriesFactory.callCategoriesData() 90 | .then(function (data) { 91 | $scope.categories = angular.fromJson(data); 92 | if (data === 0) { 93 | $scope.viewMode = true; 94 | } else 95 | { 96 | angular.forEach($scope.categories, 97 | function(vCategory) { 98 | angular.forEach(vCategory.Roles, 99 | function(vRoles) { 100 | if (vRoles.RoleID === thisCourse) { 101 | $scope.courseName = vRoles.RoleName; 102 | } 103 | }); 104 | vCategory.RoleGroupName = vCategory.RoleGroupName.replace('DVC_', ''); 105 | $("#dnn_dnnLOGO_hypLogo, #dnn_dnnLOGO_hypLogo img").addClass("print-me"); 106 | $(".print-me").parents().addClass("js-print-me"); 107 | }); 108 | } 109 | }, function (data) { 110 | console.log(data); 111 | }); 112 | 113 | // Get videos 114 | var loadVids = function () { 115 | videosFactory.callVideosData() 116 | .then(function (data) { 117 | $scope.videos = angular.fromJson(data); 118 | $scope.qandaList($scope.videos); 119 | }, function (data) { 120 | alert(data); 121 | }); 122 | } 123 | 124 | // Get Localization Resources 125 | localizationFactory.callResx() 126 | .then(function (data) { 127 | $scope.resx = angular.fromJson(data.ClientResources); 128 | }, function (data) { 129 | alert(data); 130 | }); 131 | 132 | // #endregion 133 | 134 | // Create Question and Answer List 135 | $scope.qandaList = function (videos) { 136 | 137 | // #region Create list of videos in category to get questions 138 | $scope.videoList = []; 139 | angular.forEach(videos, function (vVideo) { 140 | // Check to see that video is in the course 141 | if (vVideo.CourseId === thisCourse) { 142 | 143 | // Create list of updated videos 144 | $scope.videoList.push(vVideo); 145 | 146 | } 147 | }, $scope.videoList); 148 | // Sort the videos 149 | $scope.videoList.sort(function (a, b) { 150 | return a.OrderIndex > b.OrderIndex; 151 | }); 152 | 153 | // #endregion 154 | $scope.questions = []; 155 | // #region Create list of questions from videos 156 | angular.forEach($scope.videoList, function (vVideo) { 157 | var quesList = []; 158 | questionsFactory.callQuestionsData(vVideo.VideoId).then(function (service) { 159 | callVimeo(vVideo.VimeoId, loadVimeoData); 160 | 161 | function loadVimeoData(video) { 162 | vVideo.name = video.title; 163 | } 164 | var questionList = angular.fromJson(service); 165 | angular.forEach(questionList, function(vQuestion) { 166 | angular.forEach($scope.answers, function (vAnswer) { 167 | if (vAnswer.QuestionId === vQuestion.QuestionId) { 168 | vQuestion.answer = vAnswer; 169 | } 170 | }); 171 | $scope.questions.push(vQuestion); 172 | quesList.push(vQuestion); 173 | }); 174 | 175 | vVideo.questions = quesList; 176 | }); 177 | }); 178 | 179 | // #endregion 180 | console.log($scope.videoList); 181 | } 182 | 183 | 184 | $scope.printMe = function() { 185 | window.print(); 186 | } 187 | 188 | // #endregion 189 | 190 | 191 | // #endregion 192 | 193 | $scope.courseProgress = function () { 194 | if ($scope.editMode) { 195 | $location.path('/status/'); 196 | } else { 197 | $location.path('/videos/'); 198 | } 199 | } 200 | 201 | }]); -------------------------------------------------------------------------------- /ng/Controllers/editQuestionsCtrl.js: -------------------------------------------------------------------------------- 1 | /// 2 | angular 3 | .module('videoControllers') 4 | .controller('editQuestionsCtrl', 5 | ['$scope', 6 | '$routeParams', 7 | '$http', 8 | '$sce', 9 | '$window', 10 | 'vimeoFactory', 11 | '$location', 12 | 'localizationFactory', 13 | 'questionsFactory', 14 | 'videosFactory', 15 | function ($scope, 16 | $routeParams, 17 | $http, 18 | $sce, 19 | $window, 20 | vimeoFactory, 21 | $location, 22 | localizationFactory, 23 | questionsFactory, 24 | videosFactory) { 25 | 26 | // #region Test for Edit mode 27 | if (typeof editMode !== 'undefined' || editMode === false) { 28 | $scope.editMode = true; 29 | 30 | // #region Get Data from sources 31 | 32 | // Get Questions 33 | var videoId = parseInt($routeParams.VideoId); 34 | 35 | var loadQuestions = function (videoId) { 36 | questionsFactory.callQuestionsData(videoId) 37 | .then(function (data) { 38 | $scope.questions = angular.fromJson(data); 39 | }, function (data) { 40 | console.log(data); 41 | }); 42 | } 43 | 44 | // Add New Questions 45 | function editQuestion(NewQuestionDTO) { 46 | questionsFactory.setQuestions(NewQuestionDTO) 47 | .success(function () { 48 | loadQuestions(videoId); 49 | }). 50 | error(function (error) { 51 | $scope.status = 'Unable to insert question: ' + error.message; 52 | console.log(NewQuestionDTO); 53 | }); 54 | } 55 | 56 | // Get videos 57 | videosFactory.callVideosData() 58 | .then(function (data) { 59 | $scope.videos = angular.fromJson(data); 60 | loadVideo(); 61 | }, function (data) { 62 | alert(data); 63 | }); 64 | 65 | // Get Vimeo Data 66 | function callVimeo(vimeoId, loadVimeoData) { 67 | vimeoFactory.callVimeoData(parseInt(vimeoId)) 68 | .then(function (data) { 69 | $scope.vimeo = data; 70 | loadVimeoData(data); 71 | }, function (data) { 72 | alert('vimeo Ajax Fail'); 73 | }); 74 | } 75 | 76 | // Get Localization Resources 77 | localizationFactory.callResx() 78 | .then(function(data) { 79 | $scope.resx = angular.fromJson(data.ClientResources); 80 | }, function(data) { 81 | alert(data); 82 | }); 83 | 84 | // #endregion 85 | 86 | $scope.editQuestion = true; 87 | $scope.toggleeditQuestion = function () { 88 | $scope.editQuestion = $scope.editQuestion === false ? true : false; 89 | }; 90 | 91 | // #region Drag and Drop directive 92 | 93 | function assignOrder() { 94 | angular.forEach($scope.questions, function (value, key) { 95 | console.log(key); 96 | value.OrderIndex = key; 97 | console.log(value); 98 | $scope.EditQuestionOrder(value); 99 | }, $scope.questions); 100 | $(function () { 101 | 102 | //$.ui.sortable.refresh(); 103 | }); 104 | } 105 | 106 | // Sortable directive 107 | $scope.sortableOptions = { 108 | handle: '> .video-drag-handle', 109 | placeholder: "sortable-placeholder", 110 | helper: 'helper', 111 | forceHelperSize: true, 112 | 'ui-floating': true, 113 | update: function (e, ui) { 114 | console.log(e); 115 | console.log(ui); 116 | assignOrder(); }, 117 | stop: function (e, ui) { 118 | 119 | } 120 | }; 121 | 122 | // #endregion 123 | 124 | // #region Edit Question 125 | 126 | $scope.editQuestionText = function (QuestionText, QuestionId, VideoId, OrderIndex) { 127 | function editQuestionObject(QuestionText, QuestionId, VideoId, OrderIndex) { 128 | this.QuestionId = QuestionId, 129 | this.VideoId = VideoId, 130 | this.QuestionText = QuestionText, 131 | this.ModuleId = moduleId, 132 | this.OrderIndex = OrderIndex; 133 | } 134 | // Update Role Object 135 | var newQuestion = new editQuestionObject(QuestionText, QuestionId, VideoId, OrderIndex); 136 | editQuestion(newQuestion); 137 | $scope.editQuestion = true; 138 | $scope.QuestionText = ''; 139 | } 140 | 141 | // #endregion 142 | 143 | // #region Edit Question Order 144 | $scope.EditQuestionOrder = function(question) { 145 | // updated Video Class 146 | function UpdateQuestion(question) { 147 | this.QuestionId = question.QuestionId; 148 | this.VideoId = question.VideoId; 149 | this.QuestionText = question.QuestionText; 150 | this.OrderIndex = question.OrderIndex; 151 | this.ModuleId = moduleId; 152 | } 153 | 154 | // Create updated video object 155 | var updatedQuestion = new UpdateQuestion(question); 156 | console.log('updatedQuestion'); 157 | console.log(updatedQuestion); 158 | // Save question updated video object 159 | questionsFactory.setQuestions(updatedQuestion) 160 | .success(function () { 161 | loadQuestions(videoId); 162 | }). 163 | error(function (error) { 164 | $scope.status = 'Unable to insert question: ' + error.message; 165 | console.log(NewQuestionDTO); 166 | }); 167 | 168 | } 169 | 170 | // #region Add Question 171 | 172 | $scope.addNewQuestion = function (newQuestionText) { 173 | console.log('$scope.addNewQuestionText: ' + newQuestionText); 174 | function QuestionText(newQuestionText) { 175 | this.VideoId = videoId, 176 | this.QuestionText = newQuestionText, 177 | this.ModuleId = moduleId, 178 | this.OrderIndex = $scope.questions.length; 179 | } 180 | // Set New Role Object 181 | var newQuestion = new QuestionText(newQuestionText); 182 | editQuestion(newQuestion); 183 | $scope.editQuestion = true; 184 | $scope.question.addNewQuestionText = ''; 185 | } 186 | 187 | // #endregion 188 | 189 | // #region Remove Question 190 | 191 | $scope.removeQuestion = function (item) { 192 | var index = $scope.questions.indexOf(item); 193 | var questionToDelete = item; 194 | $scope.questions.splice(index, 1); 195 | questionsFactory.deleteQuestion(questionToDelete); 196 | 197 | // Sort the videos 198 | $scope.questions.sort(function (a, b) { 199 | return a.OrderIndex > b.OrderIndex; 200 | }); 201 | 202 | assignOrder(); 203 | } 204 | 205 | // #endregion 206 | 207 | // #region Create List of Questions 208 | loadQuestions(videoId); 209 | 210 | // #endregion 211 | 212 | function loadVideo() { 213 | angular.forEach($scope.videos, function (video, key) { 214 | if (video.VideoId === videoId) { 215 | $scope.thisVideo = video; 216 | } 217 | }); 218 | 219 | callVimeo($scope.thisVideo.VimeoId, loadVimeoData); 220 | function loadVimeoData(video) { 221 | $scope.thisVideo.name = video.title; 222 | } 223 | 224 | 225 | 226 | $scope.courseId = $scope.thisVideo.CourseId; 227 | 228 | console.log($scope.thisVideo); 229 | } 230 | 231 | $scope.courseList = function () { 232 | $location.path('/videos/'); 233 | } 234 | 235 | // #endregion 236 | 237 | } else { 238 | $scope.editMode = false; 239 | $location.path('/videos/'); 240 | $scope.courseList = function () { 241 | $location.path('/videos/'); 242 | } 243 | } 244 | 245 | // #endregion 246 | 247 | }]); -------------------------------------------------------------------------------- /ng/Controllers/statusCtrl.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | angular 5 | .module('videoControllers') 6 | .controller('statusCtrl', ['$scope', '$http', 'statusFactory', 'usersFactory', 'videosFactory', 'categoriesFactory', 'questionsFactory', 'localizationFactory', '$location', 7 | function ($scope, $http, statusFactory, usersFactory, videosFactory, categoriesFactory, questionsFactory, localizationFactory, $location) { 8 | 9 | // #region Controller Global Variables 10 | 11 | if (typeof editMode !== 'undefined') { 12 | $scope.editMode = true; 13 | 14 | // #region Get Data from sources 15 | 16 | // Get user's completed videos 17 | statusFactory.callUsersData() 18 | .then(function(data) { 19 | $scope.userData = angular.fromJson(data); 20 | angular.forEach($scope.userData, function (valueCategory) { 21 | valueCategory.Name = valueCategory.Name.replace('DVC_', ''); 22 | }); 23 | loadCats(); 24 | }, function(data) { 25 | console.log('Error Getting User Data'); 26 | console.log(data); 27 | }); 28 | 29 | 30 | // Get categories 31 | var loadCats = function () { 32 | categoriesFactory.callCategoriesData() 33 | .then(function(data) { 34 | $scope.categories = angular.fromJson(data); 35 | angular.forEach($scope.categories, function(valueCategory, keyCategory) { 36 | valueCategory.RoleGroupName = valueCategory.RoleGroupName.replace('DVC_', ''); 37 | }); 38 | loadVids(); 39 | }, function(data) { 40 | alert(data); 41 | }); 42 | } 43 | 44 | // Get videos 45 | var loadVids = function () { 46 | videosFactory.callVideosData() 47 | .then(function(data) { 48 | $scope.videos = angular.fromJson(data); 49 | $scope.videoList($scope.videos); 50 | }, function(data) { 51 | alert(data); 52 | }); 53 | } 54 | 55 | // Get Localization Resources 56 | localizationFactory.callResx() 57 | .then(function(data) { 58 | $scope.resx = angular.fromJson(data.ClientResources); 59 | }, function(data) { 60 | alert(data); 61 | }); 62 | 63 | // #endregion 64 | 65 | // Create Video List 66 | $scope.videoList = function () { 67 | 68 | // Iterate through each Category 69 | angular.forEach($scope.categories, function (valueCategory, keyCategory) { 70 | 71 | // Iterate through each Role 72 | angular.forEach($scope.categories[keyCategory].Roles, function (valueCourse, keyCourse) { 73 | 74 | // Set courseId to RoleID 75 | $scope.categories[keyCategory].Roles[keyCourse].CourseId = valueCourse.RoleID; 76 | $scope.categories[keyCategory].Roles[keyCourse].hasQuestions = false; 77 | 78 | angular.forEach($scope.userData, function (valueUserGroup) { 79 | if (valueUserGroup.Id === valueCategory.RoleGroupID) { 80 | angular.forEach(valueUserGroup.Roles, function(valueUserRole) { 81 | if (valueUserRole.Id === valueCourse.RoleID) { 82 | angular.forEach(valueUserRole.Users, function (valueUser) { 83 | var myCounter = 0; 84 | var videoCounter = 0; 85 | var videoList = []; 86 | angular.forEach($scope.videos, function (valueVideo) { 87 | // Check to see that video is in the course 88 | if (valueVideo.CourseId === valueCourse.RoleID) { 89 | if (valueUser.Videos === null) { 90 | myCounter = 0; 91 | } else if (valueUser.Videos.match(valueVideo.VideoId)) { 92 | myCounter++; 93 | } 94 | //console.log(valueUser); 95 | videoCounter++; 96 | // Create list of updated videos 97 | videoList.push(valueVideo); 98 | // Determine if course has questions associated with it 99 | questionsFactory.callQuestionsData(valueVideo.VideoId).then(function (service) { 100 | $scope.questionList = angular.fromJson(service); 101 | angular.forEach($scope.questionList, function (vQuestion) { 102 | if (vQuestion.VideoId === valueVideo.VideoId) { 103 | valueUser.hasQuestions = true; 104 | } 105 | }); 106 | }); 107 | } 108 | }, videoList); 109 | valueUser.name = valueUser.DisplayName !== '' ? valueUser.DisplayName : valueUser.Email; 110 | valueUser.numberComplete = myCounter; 111 | valueUser.totalVideos = videoCounter; 112 | valueUser.notStarted = valueUser.numberComplete === 0 ? 'not-started' : 'started'; 113 | valueUser.percentComplete = (myCounter / videoCounter) * 100 + '%'; 114 | valueUser.amountComplete = (myCounter / videoCounter) * 100; 115 | valueUser.courseComplete = valueUser.numberComplete === valueUser.totalVideos ? 'complete' : 'not-complete'; 116 | 117 | }); 118 | } 119 | }); 120 | } 121 | }); 122 | 123 | }); 124 | }); 125 | $('.collapse').collapse(function() {return false}); 126 | } 127 | 128 | // #endregion 129 | } else { 130 | $scope.editMode = false; 131 | $location.path('/videos/'); 132 | 133 | } 134 | 135 | // #endregion 136 | 137 | $scope.courseList = function () { 138 | $location.path('/videos/'); 139 | } 140 | 141 | }]); -------------------------------------------------------------------------------- /ng/Views/answerListView.html: -------------------------------------------------------------------------------- 1 | 
2 | 16 | 32 |
33 |
34 |

{{ resx.LoggedOutMessage }}

35 |
-------------------------------------------------------------------------------- /ng/Views/editCategories.html: -------------------------------------------------------------------------------- 1 | 
2 | 15 |
16 |
17 |
18 |

No Courses Exist

19 |

No courses have been set up for this module. Please begin by creating your first Category. Once a Category has been added, you may add more categories and courses.

20 |

21 | 22 | 23 | 24 | 25 |

26 |
27 |
28 |
29 |

Instructions

30 |
31 |

Create and edit categories and courses. Creating a category will create a new Security Role Group. Creating a new course will create a new Security Role.

32 |

Add users to courses by clicking the users icon for that course.

33 |

Disabling all courses within a category will hide the category from the user in the Video list view as well.

34 |

Note: Category and course names may not be used more than once.

35 |
36 |
37 |

38 | 39 | 40 | 41 | 42 |

43 |
44 |
45 |
46 |
47 |

Categories and Courses

48 |
49 |
50 |
51 |
52 |

53 | {{ category.RoleGroupName }} 54 |

55 |

56 | 57 | 58 | 59 |

60 | 61 | 64 | 65 |
66 |
    67 |
  • 68 | 69 | {{ course.RoleName }} 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 82 | 83 | 84 | 85 | 86 | 87 |   88 |
  • 89 |
  • 90 | 91 | 92 | 93 | 94 |
  • 95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
-------------------------------------------------------------------------------- /ng/Views/editCourseView.html: -------------------------------------------------------------------------------- 1 | 
2 | 15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 37 | 40 | 43 | 44 | 61 | 66 | 67 | 68 |
{{ resx.EditCourseTblHdr_Order }}{{ resx.EditCourseTblHdr_Id }}{{ resx.EditCourseTblHdr_Title }}{{ resx.EditCourseTblHdr_Description }}{{ resx.EditCourseTblHdr_VimeoId }}
32 | {{ video.OrderIndex + 1}} 33 | 35 | {{ video.title }} 36 | 38 | {{ video.VideoId }} 39 | 41 | {{ video.title }} 42 |
{{ video.description }}
45 | 46 | {{ video.VimeoId }}
47 | {{ resx.EditCourseWatchOnVimeo_Txt }} 48 |

49 | 50 | Manage Questions for Video 51 | 52 |
53 | 54 |
55 | 58 |
59 | 60 |
62 | 65 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

{{ resx.EditCourseAddVideo_Title }}

76 |
77 |
78 |
79 |
80 | 81 | 82 |
83 | 84 | 85 | 88 | 89 |
90 |
91 |
92 |
93 |
94 | {{ resx.VideoVimeoUrlExample_Text }} 95 |
96 |
97 |
98 |
99 |
100 |
101 |
-------------------------------------------------------------------------------- /ng/Views/editQuestionsView.html: -------------------------------------------------------------------------------- 1 | 
2 | 15 |
16 |
17 |

{{ thisVideo.name }}

18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 40 | 45 | 47 | 48 | 49 | 50 | 56 | 57 | 58 |
{{ resx.EditCourseTblHdr_Order }}{{ resx.EditCourseTblHdr_Title }}
{{ $index + 1 }} 30 | 31 | {{ question.QuestionText }} 32 | 33 | 34 | 35 | 36 | 39 | 41 | 44 | 46 |
51 | 52 | 53 | 54 | 55 |
59 |
60 |
61 |
-------------------------------------------------------------------------------- /ng/Views/statusView.html: -------------------------------------------------------------------------------- 1 | 
2 | 16 |
17 |
18 |
    19 |
  • 20 | 21 |
      22 |
    • 23 | 26 |
      27 | 30 |
        31 |
      • 32 |
        33 |
        34 |

        {{ user.name }}

        35 |
        36 |
        37 |

        38 |
        {{ resx.CourseProgressNotStarted_Txt }} 39 |

        40 | 41 |
        42 |
        43 | 40% Complete (success) 44 |
        45 |
        46 |

        {{ user.numberComplete + ' of ' + user.totalVideos }} {{ resx.CourseProgressCompleted_Txt }}

        47 |

        {{ resx.CourseProgressCourseComplete_Txt }}

        48 | View Q & A 49 |
        50 |
        51 |
      • 52 |
      53 |
      54 |
    • 55 |
    56 |
  • 57 |
58 |
59 |
60 |
-------------------------------------------------------------------------------- /ng/Views/templates/accordion-group.html: -------------------------------------------------------------------------------- 1 | 
2 | 24 |
25 | 39 |
40 |
41 |

No videos have been added to this course. Click here to add videos.

42 |
43 |
44 |
45 |
46 | -------------------------------------------------------------------------------- /ng/Views/templates/accordion.html: -------------------------------------------------------------------------------- 1 | 
  • 2 |

    {{ $parent.category.RoleGroupName }}

    3 |
      4 | 5 | 6 | 7 | 8 |
    9 |
  • 10 | -------------------------------------------------------------------------------- /ng/Views/videoListView.html: -------------------------------------------------------------------------------- 1 | 
    2 | 18 |
      19 |
    • 20 |

      {{ category.RoleGroupName }}

      21 |
        22 | 23 | 24 | 25 | 26 |
      27 |
    • 28 |
    29 |
    30 |
    31 |

    {{ resx.LoggedOutMessage }}

    32 |
    -------------------------------------------------------------------------------- /ng/Views/videoPlayerView.html: -------------------------------------------------------------------------------- 1 | 
    2 | 15 |
    16 |
    17 |
    18 |
    19 |
    20 | 21 |
    22 |
    23 |
    24 |
    25 |
    26 |
    27 |
    28 |

    {{selectedVimeo.title}}

    29 |

    {{ resx.VideoDetailsLength_Text }}: {{showDuration()}}
    {{ resx.VideoDetailsVideo_Text }} {{ orderIndex + 1 }} {{ resx.VideoDetailsOf_Text }} {{ courseLength }}

    30 |

    {{ selectedVimeo.description }}

    31 |
    32 |
    33 |
    34 |
    35 |
    36 |

    Questions

    37 |
      38 |
    1. 39 | {{question.QuestionText}} 40 |