diff --git a/Client/WebServer/css/governance.css b/Client/WebServer/css/governance.css new file mode 100644 index 000000000..ec2258bec --- /dev/null +++ b/Client/WebServer/css/governance.css @@ -0,0 +1,1117 @@ + +.governance-page { + border: 0px solid; + background-color: whitesmoke; + /*background-color: #fdfdfd;*/ + } + + .governance-search-page-container { + font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + color: #365558; + line-height: 150%; + margin: 20 25 20 30px; + } + + .governance-common-style-container{ + /*background-color: white;*/ + font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + color: #324d50; + line-height: 150%; + margin: 20 30px; + margin: 20 25 20 30px; + caret-color: transparent; + } + + .governance-node-html-footer-container { + font: 400 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + color: #e6eaea; + background-color: #365558; + line-height: 160%; + border-top: 5px solid #0295aa; + margin: 80px 0 0 0; + padding: 30 0 20 0px; + caret-color: transparent; + } + + /* DELETE candidate (delete class assignment on DocsSapace.js too) + + .governance-context-menu-clickeable-container { + font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + color: #111; + line-height: 150%; + margin: 20 20 20 30px; + } + + */ + + #governance-common-style-container-div ul { + padding: 0px; + margin-left: 35px; + list-style-position: outside; + } + + .governance-font-normal { + font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + color: #111; + line-height: 150%; + } + + .governance-title-table { + vertical-align: middle; + width: 100%; + min-width: 95px; + margin-bottom: 0px; + margin-top: 0px; + border: 0px solid #cdcdcd; + padding: 5px; + } + + .governance-table-cell{ + display: table-cell; + width: 100%; + } + + .governance-definition-table { + background-color: white; + vertical-align: middle; + margin-bottom: 20px; + margin-top: 0px; + border: 1px solid #cdcdcd; + border-radius: 5px; + padding: 10px; + display: table; + width: 100%; + box-sizing: border-box; + border-collapse: separate; + border-spacing: 10px; + /* DELETE candidate + margin-right: 20px; + */ + } + + .governance-definition-text { + display: table-cell; + vertical-align: middle; + padding: 0 20px; + } + + .governance-image-container { + padding: 5px 0px 5px 5px; + border: solid 0px; + display: table-cell; + vertical-align: middle; + } + + .governance-hierarchy-image-container { + padding: 0px 0px 0px 0px; + border: solid 0px; + margin-left: auto; + margin-right: auto; + width: 100%; + } + + /* Link without tooltip */ + .governance-link { + position: relative; + display: inline-block; + color: #0295aa !important; + text-decoration: underline !important; + cursor: pointer; + } + + /* Tooltip container */ + .governance-tooltip { + position: relative; + display: inline-block; + border-bottom: 1px dashed #999; + cursor: pointer; + line-height: inherit; + } + + /* Tooltip text */ + .governance-tooltip .governance-tooltiptext { + visibility: hidden; + width: 240px; + background-color: #0295aa; + color: #fff; + font-weight: normal; + font-style: normal; + font-size: 15px; + line-height: 130%; + text-align: center; + padding: 15px; + border-radius: 6px; + + /* Position the governance-tooltip text */ + position: absolute; + z-index: 0; + bottom: 125%; + left: 50%; + margin-left: -120px; + + + /* Fade in governance-tooltip */ + opacity: 0; + transition: opacity 0.3s; + } + + /* Tooltip arrow */ + .governance-tooltip .governance-tooltiptext::after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: #0295aa transparent transparent transparent; + } + + /* Show the tooltip text when you mouse over the tooltip container */ + .governance-tooltip:hover .governance-tooltiptext { + visibility: visible; + opacity: 1; + } + + /* Headings */ + + .governance-h1 { + font-size:210%; + margin-top: 40px; + padding-bottom: 5px; + } + + .governance-h2 { + font-weight:700; + font-size:170%; + line-height: 170%; + margin-top: 30px; + padding-bottom: 5px; + overflow:hidden; + } + + .governance-h2::after{ + content:''; + display:inline-block; + width:90%; + margin-right:-100%; + border-bottom: 1px solid #cdd4d5; + margin-left: 20px; + } + + .governance-h3 { + font-weight:500; + font-size:150%; + margin-top: 40px; + margin-bottom: 20px; + } + + .governance-h4 { + font-weight:400; + font-style: italic; + font-size:135%; + margin-top: 30px; + margin-bottom: 20px; + } + + /* DELETE candidate + + .governance-h5 {font-weight:400; font-size:140%; margin-top: 35px; font-style:italic;} + + .governance-h6 {font-weight:400; font-size:130%; margin-top: 35px; font-style:italic;} + margin-right: 20px; + + */ + .governance-text-area { + font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + resize: none; + outline: none; + box-shadow: none; + overflow:hidden; + background-color: #eff; + border: 1px solid #0295aa; + border-radius: 5px; + color: #111; + width: 100%; + height: 25%; + z-index:100; + padding: 0px 10px; + font-size: 95%; + line-height: 140%; + caret-color: #111; + } + + /* Alerts */ + .governance-alert-note { + color: #31708f; + background-color: #d9edf7; + padding: 15px; + border: 1px solid rgba(49, 112, 143, .3); + border-radius: 4px; + margin: 20px 0; + width: 100%; + box-sizing: border-box; + } + + .governance-alert-success { + color: #3c763d; + background-color: #dff0d8; + padding: 15px; + border: 1px solid rgba(60, 118, 61, .3); + border-radius: 4px; + margin: 20px 0; + width: 100%; + box-sizing: border-box; + } + + .governance-alert-important { + color: #5e3e07; + background-color: #fcf8e3; + padding: 15px; + border: 1px solid rgba(138, 109, 59, .3); + border-radius: 4px; + margin: 20px 0; + width: 100%; + box-sizing: border-box; + } + + .governance-alert-warning { + color: #a94442; + background-color: #f2dede; + padding: 15px; + border: 1px solid rgba(169, 68, 66, .3); + border-radius: 4px; + margin: 20px 0; + width: 100%; + box-sizing: border-box; + } + + .governance-alert-error { + color: #fff16c; + background-color: #ff3131; + padding: 30px; + border: 1px solid rgba(0, 0, 0, .5); + border-radius: 4px; + margin: 20px 0; + width: 100%; + box-sizing: border-box; + } + + .governance-callout { + background-color:white; + padding: 20px; + margin: 20px 0; + border: 1px solid rgba(54, 85, 88, .3); + border-left-width: 5px; + border-radius: 3px; + border-left-color: #bcd643; + font-weight: 550 !important; + width: 100%; + box-sizing: border-box; + } + + .governance-topic-index { + background-color:white; + padding: 25 20px; + margin: 40px 0 0 0; + border: 1px solid rgba(49, 112, 143, .2); + border-left-width: 5px; + border-radius: 5px; + border-left-color: #365558; + width: 100%; + box-sizing: border-box; + } + + .governance-topic-index h2 { + font-size: 130%; + font-weight: 300; + margin: 10px 0 35 -5; + padding: 0px; + } + + .governance-topic-index h3 { + font-size: 150%; + font-weight: 300; + margin: 25px 0; + padding: 0px; + } + + .governance-topic-index p { + font-size: 100%; + padding: 0px; + margin: 2px 0; + } + + .governance-topic-index a { + color: #365558; + } + + .governance-topic-index a:hover { + text-decoration: underline; + cursor: pointer; + color: #0295aa; + } + + .governance-summary { + background-color:white; + font-weight: 600; + color: #365558; + padding: 20px; + margin-bottom: 20px; + border-radius: 5px; + border: 1px solid rgba(54, 85, 88, .3); + border-left: 5px solid #fd6a33; + width: 100%; + box-sizing: border-box; + } + + .governance-section { + font-size:120%; + padding: 200px; + } + + .governance-note-circle:before { + content:"\f05a" + } + + .governance-check-square-o:before { + content:"\f046" + } + + .governance-exclamation-circle:before { + content:"\f06a" + } + + .governance-warning-sign:before,.fa-exclamation-triangle:before { + content:"\f06a" + } + + .governance-fa { + font:normal normal normal 14px/1 FontAwesome; + font-size:inherit; + text-rendering:auto; + -webkit-font-smoothing:antialiased; + -moz-osx-font-smoothing:grayscale + } + + .governance-font-small { + font:normal normal normal 14px/1 "segoeui"; + font-size:inherit; + text-rendering:auto; + -webkit-font-smoothing:antialiased; + -moz-osx-font-smoothing:grayscale; + line-height: 150% + } + + li > .governance-font-small { + margin-bottom:7px; + } + + div.governance-font-small { + margin-bottom:7px; + } + + hr.governance-shaded { + box-shadow: inset 0 6px 6px -6px rgba(0,0,0,0.5); + margin: 90 0 70 0; + height: 12px; + border: 0; + background: white; + width: 100%; + } + + /* Topic Navigation */ + + .governance-topic-navigation { + display: table; + width: 100%; + vertical-align: middle; + margin: 80px 0 0 0; + /* + border-top: 1px solid rgba(54, 85, 88, .3); + margin: 60px 0 0 0; + padding-top: 20px; + */ + } + + .governance-topic-navigation div { + display: table-cell; + width: 50%; + max-width: 50%; + text-align: center; + vertical-align: top; + padding: 10px; + /* + height: 40px; + */ + } + + .governance-topic-navigation div button{ + border-radius: 50px; + border: 0px; + color: #e6eaea; + background-color: #365558; + padding: 10px; + margin: 0 0 10 10px; + font-size: 100%; + line-height: 150%; + width: 150px; + height:100%; + } + + .governance-topic-navigation div button:hover { + background-color: #0295aa; + cursor: pointer; + } + + /* Footer */ + + .governance-node-html-footer-table { + display: table; + width: 100%; + border-collapse: separate; + border-spacing: 6px; + } + + .governance-footer-row { + display: table-row; + } + + .governance-footer-cell { + padding: 5px 15px 0px 30px; + display: table-cell; + width: 33%; + } + + #governance-footer h3 { + font-size: 180%; + font-weight: 300; + padding: 10px 0 0 0; + } + + #governance-footer h4 { + font-size: 120%; + font-weight: 300; + } + + #governance-footer button{ + border: 1px outset #e6eaea; + border-radius: 20px; + background-color: transparent; + color: e6eaea; + padding: 10px; + margin: 0 0 0 10px; + } + + #governance-footer button:hover { + border: 1px inset #e6eaea; + cursor: pointer; + } + + #governance-footer a:hover { + text-decoration: none; + color: #ff8c29 !important; + cursor: pointer; + } + + #governance-footer a:link, + #governance-footer a:visited, + #governance-footer a:active { + text-decoration: none; + color: #ffd1a9; + } + + .governance-footer-language { + width: 30px; + margin-top: 7px; + padding: 7 7px; + } + + .governance-footer-language-selected { + width: 30px; + margin-top: 7px; + padding: 7 7px; + background-color: rgba(230, 234, 234, 0.2); + /* border: 1px solid rgba(205, 212, 213, 0.5); DELETE Candidate*/ + border: 1px solid rgba(200, 200, 200, .5); + border-radius: 3px; + } + + + /* DELETE candidate + .governance-footer-body { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; + } + */ + + /* Links */ + a:link.governance-plain-link { + text-decoration: none; + } + + a:visited.governance-plain-link { + text-decoration: none; + } + + a:hover.governance-plain-link { + text-decoration: none; + } + + a:active.governance-plain-link { + text-decoration: none; + } + + /* Icon after external links, using FontAwesome*/ + a[href^="http://"]:after, a[href^="https://"]:after { + content: "\f08e"; + font-family: FontAwesome; + font-weight: normal; + font-style: normal; + display: inline-block; + text-decoration: none; + padding-left: 3px; + } + + /* Tags */ + + kbd.governance-kbd { + margin: 0 0 0 15px; + } + + code.governance-code { + color: #d9534f; + background-color: rgba(230, 234, 234, .5); + /* border: 1px solid rgba(205, 212, 213, 0.5); DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .1); + border-radius: 3px; + padding: 0 5; + } + + code.governance-footer-code { + color: #eee; + background-color: rgba(230, 234, 234, 0.2); + /* border: 1px solid rgba(205, 212, 213, 0.5); DELETE Candidate*/ + border: 1px solid rgba(200, 200, 200, .5); + border-radius: 3px; + padding: 0 5; + } + + a:hover.code.governance-footer-code { + color: #eee; + background-color: rgba(253, 106, 51, 1); + /* border: 1px solid rgba(205, 212, 213, 0.5); DELETE Candidate*/ + border: 1px solid rgba(200, 200, 200, .5); + border-radius: 3px; + padding: 0 5; + } + + /* Style the button that is used to open and close the governance-collapsible-element content */ + .governance-collapsible-element { + background-color: #eee; + color: #31708f; + cursor: pointer; + width: 97.5%; + text-align: left; + outline: none; + font-size: 100%; + padding: 10px; + margin: 4px 0 4 20; + transition: 0.1s; + /* border: 1px solid #ddd; DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .3); + border-radius: 5px; + background-color: white; + vertical-align: middle; + box-sizing: border-box; + } + + .governance-collapsible-element img { + vertical-align: middle; + display: inline-block; + margin: 0 20px 0 0; + width: 40px; + height: 40px; + } + + /* This definition is redundant with .governance-collapsible-element img but affects some images. Investigation required to delete it.*/ + + .governance-collapsible-image { + vertical-align: middle; + display: inline-block; + margin: 0 20px 0 0; + width: 40px; + height: 40px; + } + + /* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */ + .active, .governance-collapsible-element:hover { + border: 1px solid #0295aa; + background-color: #eff; + } + + /* Style the governance-collapsible-element content. Note: hidden by default */ + .governance-collapsible-content { + padding: 0 18px; + display: none; + margin-left: 75px; + z-index: 1; + font-size: 90%; + line-height: 90%; + } + + .governance-collapsible-code-content { + padding: 0; + display: none; + margin-left: 0px; + z-index: 1; + } + + .governance-collapsible-element:after { + content: '\02795'; /* Unicode character for "plus" sign (+) */ + font-size: 60%; + color: #31708f; + margin-left: 5px; + float: right; + vertical-align: middle; + line-height: 40px; + } + + .governance-collapsible-active:after { + content: "\2796"; /* Unicode character for "minus" sign (-) */ + } + + /* This is the same Style as the collapsible counter part but will not hold any collapsed content inside. */ + .governance-non-collapsible-element { + /* + background-color: #fdfdfd; + color: #444; + padding: 15px; + width: 100%; + border: none; + text-align: left; + outline: none; + font-size: 125%; + vertical-align: middle; + min-height: 80px; + */ + background-color: #eee; + color: #31708f; + width: 97.5%; + text-align: left; + outline: none; + font-size: 100%; + vertical-align: middle; + padding: 10px; + margin: 4px 0 4 20; + transition: 0.1s; + /* border: 1px solid #ddd;DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .3); + border-radius: 5px; + background-color: white; + + box-sizing: border-box; + } + + /* Info Tables */ + .governance-info-table { + background-color: transparent; + max-width: 100%; + margin-bottom: 20px; + margin-top: 20px; + /* border: 1px solid #cdcdcd; DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .3); + border-spacing: 0px; + } + + .governance-info-table > thead > tr > th, + .governance-info-table > tbody > tr > th, + .governance-info-table > tfoot > tr > th, + .governance-info-table > thead > tr > td, + .governance-info-table > tbody > tr > td, + .governance-info-table > tfoot > tr > td { + padding: 8px; + line-height: 150%; + vertical-align: top; + } + + .governance-info-table > thead > tr > th > a { + vertical-align: middle; + text-transform: none; + background-color: #333; + color: white; + text-align: left; + } + + .governance-info-table > tbody > tr > td { + /* border-top: 1px solid #cdcdcd; DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .3); + } + + .governance-info-table-alt-bg td { + background-color: #f9f9f9; + } + + /* Gif Image */ + .governance-gif { + max-width: 100%; + width: 100%; + /* border: 1px solid #cdcdcd; DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .3); + border-spacing: 1px; + } + + /* PNG Image */ + .governance-png { + max-width: 100%; + width: 100%; + /* border: 1px solid #cdcdcd; DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .3); + border-spacing: 1px; + } + + /* Search Page */ + .governance-image-logo-search { + margin: auto; + margin-top: 225px; + margin-bottom: 25px; + } + + .governance-search-box { + width: 700px; + height: 45px; + margin-top: 50px; + margin-bottom: 600px; + border-radius: 30px; + border: 1px solid #0295aa; + background-color: white; + vertical-align: middle; + } + + .governance-search-input { + width: 95%; + height: 45px; + margin: 0 20px; + font-size: 100%; + color: #6b6b6b; + border: none; + outline: none; + background-color: transparent; + } + + /* Search Results Page */ + + /* Search Results Page Header*/ + + .governance-report-page-header { + display: table; + } + + .governance-image-logo-report-page { + vertical-align: middle; + display: table-cell; + padding-right: 25px; + caret-color: transparent; + } + + .governance-report-page-box { + height: 45px; + border-radius: 30px; + border: 1px solid #0295aa; + background-color: white; + vertical-align: middle; + display: table-cell; + width: 100%; + } + + .governance-report-page-header-tabs-container { + display: table; + padding-left: 180px; + margin-top: 20px; + caret-color: transparent; + } + + .governance-report-page-header-tabs-container > input { + display: none; + } + + .governance-report-page-header-tabs-container > label { + display: inline-block; + vertical-align: bottom; + padding: 0 15px 3px 15px; + color: #365558; + font-size: 90%; + } + + .governance-report-page-header-tabs-container > label:hover { + color: #0295aa; + padding-bottom: 3px; + cursor: pointer; + } + + .governance-report-page-header-tabs-container > input:checked + label { + color: #0295aa; + padding-bottom: 2px; + border-bottom: 3px solid #0295aa; + } + + /* Search Results Page Content */ + .governance-search-result-content { + border-top: 1px solid #0295aa; + margin-left: -180px; + caret-color: transparent; + } + + .governance-search-result-content > div { + display: none; + } + + #tab1:checked ~ .governance-search-result-content #content1, + #tab2:checked ~ .governance-search-result-content #content2, + #tab3:checked ~ .governance-search-result-content #content3, + #tab4:checked ~ .governance-search-result-content #content4, + #tab5:checked ~ .governance-search-result-content #content5, + #tab6:checked ~ .governance-search-result-content #content6, + #tab7:checked ~ .governance-search-result-content #content7, + #tab8:checked ~ .governance-search-result-content #content8 { + display: block; + } + + /* Search Results Page Record */ + + .governance-search-result-content-record-container { + margin: 20px 0; + } + + .governance-search-result-content-record-container > p { + margin: 1px; + } + + .governance-search-result-content-record-project-category { + font-size: 90%; + color: #31708f; + } + + .governance-search-result-content-record-project-category-link { + font-size: 90%; + color: #31708f; + } + + a:hover.governance-search-result-content-record-project-category-link { + text-decoration: underline; + cursor: pointer; + } + + .governance-search-result-content-record-topic { + font-size: 90%; + color: #31708f; + } + + .governance-search-result-content-record-tutorial { + font-size: 90%; + color: #31708f; + } + + .governance-search-result-content-record-review { + font-size: 90%; + color: #31708f; + } + + .governance-search-result-content-record-topic { + font-size: 90%; + color: #31708f; + } + + .governance-search-result-content-record-tutorial { + font-size: 90%; + color: #31708f; + } + + .governance-search-result-content-record-review { + font-size: 90%; + color: #31708f; + } + + .governance-search-result-content-record-title { + font-size: 120%; + font-weight: 500; + text-decoration: none; + color: #e44d40; + } + + a:link.governance-search-result-content-record-title { + text-decoration: none; + color: #e44d40; + } + + a:visited.governance-search-result-content-record-title { + text-decoration: none; + color: #fd6a33; + } + + a:hover.governance-search-result-content-record-title { + text-decoration: underline; + cursor: pointer; + } + + a:active.governance-search-result-content-record-title { + text-decoration: none; + color: #fd6a33; + } + + .governance-search-result-content-record-extract { + font-size: 100%; + color: #333; + margin-top: 5px!important; + } + + /* Command Results Page Content */ + .governance-command-result-content { + /* border-top: 1px solid #cdcdcd; DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .3); + margin-left: -240px; + } + + .governance-command-result-message { + font-size: 90%; + color: #31708f; + } + + .governance-hidden-anchor { + border-top: 1px solid #eee; + padding: 0px; + margin: -20px 0px -40px 0; + width: 100%; + text-align: right; + color: transparent; + font-size: 75%; + } + + .governance-hidden-anchor::after{ + content:' \2693'; + color: transparent; + font-size: 130%; + } + + .governance-hidden-anchor:hover::after{ + content:' \2693'; + color: #365558; + font-size: 130%; + } + + .governance-hidden-block { + border-top: 1px solid #eee; + padding: 0px; + margin: -5px 0px -30px 0; + width: 100%; + text-align: right; + color: transparent; + font-size: 75%; + } + + .governance-hidden-block::after{ + content:' \25BD'; + color: #e0e0e0; + font-size: 150%; + } + + .governance-hidden-block:hover::after{ + content:' \25BC'; + color: #365558; + font-size: 150%; + } + + .governance-hidden-include { + border-top: 1px solid #eee; + padding: 0px; + margin: -5px 0px -30px 0; + width: 100%; + text-align: right; + color: transparent; + font-size: 75%; + } + + .governance-hidden-include::after{ + content:' \275E'; + color: #e6e6e6; + font-size: 200%; + } + + .governance-hidden-include:hover::after{ + content:' \275E'; + color: #365558; + font-size: 200%; + } + + .governance-hidden-placeholder { + border-top: 1px solid #eee; + padding: 0px; + margin: -5px 0px -30px 0; + width: 100%; + text-align: right; + color: transparent; + font-size: 75%; + } + + .governance-hidden-placeholder::after{ + content:' \275E'; + color: #e6e6e6; + font-size: 200%; + } + + .governance-hidden-placeholder:hover::after{ + content:' \275E'; + color: #365558; + font-size: 200%; + } + + /* Hierarchy Table */ + .governance-hierarchy-table { + min-width: 100%; + max-width: 100%; + margin-bottom: 20px; + margin-top: 20px; + /* border: 1px solid #cdcdcd; DELETE Candidate*/ + border: 1px solid rgba(54, 85, 88, .3); + border-spacing: 0; + border-collapse: collapse; + font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + color: #111; + } + + .governance-hierarchy-table-row{ + background-color: #f5f5f5; + } + + .governance-hierarchy-table-cell{ + text-align: center; + vertical-align: middle; + } + + .governance-external-link { + text-decoration: underline; + color: #31708f; + } + + .governance-chapter { + border-top: 1px solid #eee; + padding: 0px; + margin: -5px 0px -30px 0; + width: 100%; + height: 40px; + text-align: right; + color: transparent; + font-size: 75%; + } + + .governance-youtube-video-container{ + background-color: white; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + margin-bottom: 35px; + max-width: 830px; + max-height: 476px; + } + + \ No newline at end of file diff --git a/Client/WebServer/index.html b/Client/WebServer/index.html index a693d0d9d..73898b909 100644 --- a/Client/WebServer/index.html +++ b/Client/WebServer/index.html @@ -8,6 +8,7 @@ + @@ -115,6 +116,9 @@
+
+
+
diff --git a/Client/httpInterface.js b/Client/httpInterface.js index 44900a6e5..283405b10 100644 --- a/Client/httpInterface.js +++ b/Client/httpInterface.js @@ -1547,6 +1547,12 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE } break + case 'governance.css': + { + sendStyleSheet('governance.css') + } + break + case 'context-menu.css': { sendStyleSheet('context-menu.css') diff --git a/Projects/Education/UI/Spaces/Docs-Space/DocsSpace.js b/Projects/Education/UI/Spaces/Docs-Space/DocsSpace.js index b4053b0e3..bc35e0c59 100644 --- a/Projects/Education/UI/Spaces/Docs-Space/DocsSpace.js +++ b/Projects/Education/UI/Spaces/Docs-Space/DocsSpace.js @@ -171,11 +171,8 @@ function newEducationDocSpace() { } function setupSidePanelTab() { - thisObject.sidePanelTab = newSidePanelTab() - thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) - thisObject.sidePanelTab.tabIcon = UI.projects.foundations.spaces.designSpace.getIconByProjectAndName('Education', 'docs-tab') - thisObject.sidePanelTab.tabLabel = 'Docs' - thisObject.sidePanelTab.initialize('right') + thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Education', 'docs-tab', 'Docs', 'right') + openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', onOpening) closingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closing', onClosing) @@ -437,7 +434,6 @@ function newEducationDocSpace() { } function physics() { - thisObject.sidePanelTab.physics() docsAppDivPhysics() function docsAppDivPhysics() { @@ -461,7 +457,6 @@ function newEducationDocSpace() { if (CAN_SPACES_DRAW === false) { return } if (isInitialized === false) { return } borders() - thisObject.sidePanelTab.draw() } function borders() { diff --git a/Projects/Education/UI/Spaces/Tutorial-Space/TutorialSpace.js b/Projects/Education/UI/Spaces/Tutorial-Space/TutorialSpace.js index dc7b974c9..c6d05730c 100644 --- a/Projects/Education/UI/Spaces/Tutorial-Space/TutorialSpace.js +++ b/Projects/Education/UI/Spaces/Tutorial-Space/TutorialSpace.js @@ -363,7 +363,7 @@ function newEducationTutorialSpace() { This forces the tutorial to close the workspaces panel and to keep it closed. */ if (workspacesCounter === 5) { - UI.projects.foundations.spaces.sideSpace.sidePanelTab.close() + UI.projects.foundations.spaces.workspaceSpace.sidePanelTab.close() } return } @@ -372,7 +372,7 @@ function newEducationTutorialSpace() { This forces the tutorial to open the workspaces panel and to keep it closed. */ if (workspacesCounter === 5) { - UI.projects.foundations.spaces.sideSpace.sidePanelTab.open() + UI.projects.foundations.spaces.workspaceSpace.sidePanelTab.open() } return } diff --git a/Projects/Foundations/UI/Spaces/Chat-Space/ChatSpace.js b/Projects/Foundations/UI/Spaces/Chat-Space/ChatSpace.js index d4450a10d..5df19ec8f 100644 --- a/Projects/Foundations/UI/Spaces/Chat-Space/ChatSpace.js +++ b/Projects/Foundations/UI/Spaces/Chat-Space/ChatSpace.js @@ -31,10 +31,9 @@ function newFoundationsChatSpace() { return thisObject function initialize() { - - thisObject.sidePanelTab = newSidePanelTab() - thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) - thisObject.sidePanelTab.initialize('right', 1) + return + thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Education', 'docs-tab', 'Docs', 'right') + openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', onOpening) closingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closing', onClosing) @@ -89,15 +88,14 @@ function newFoundationsChatSpace() { return thisObject.container } else { UI.projects.foundations.spaces.chartingSpace.viewport.onMouseWheel(event) - return + return } } else { - return + return } } function physics() { - thisObject.sidePanelTab.physics() chatAppDivPhysics() iFramePhysics() @@ -108,18 +106,18 @@ function newFoundationsChatSpace() { y: 0 } chatAppDivPosition = thisObject.container.frame.frameThisPoint(chatAppDivPosition) - chatAppDiv.style = ' ' + - 'position:fixed; top:' + chatAppDivPosition.y + 'px; ' + - 'left:' + chatAppDivPosition.x + 'px; z-index:1; ' + - 'width: ' + thisObject.container.frame.width + 'px;' + - 'height: ' + thisObject.container.frame.height + 'px' + chatAppDiv.style = ' ' + + 'position:fixed; top:' + chatAppDivPosition.y + 'px; ' + + 'left:' + chatAppDivPosition.x + 'px; z-index:1; ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' } function iFramePhysics() { let docIFrame = document.getElementById('chatIFrame') - docIFrame.style = ' ' + - 'width: ' + thisObject.container.frame.width + 'px;' + - 'height: ' + thisObject.container.frame.height + 'px' + docIFrame.style = ' ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' } } @@ -127,7 +125,6 @@ function newFoundationsChatSpace() { if (CAN_SPACES_DRAW === false) { return } if (isInitialized === false) { return } borders() - thisObject.sidePanelTab.draw() } function borders() { diff --git a/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js b/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js index 16a8f958d..ccde486e1 100644 --- a/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js +++ b/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js @@ -311,7 +311,7 @@ function newWorkspace() { workingAtTask = 0 UI.projects.education.spaces.docsSpace.sidePanelTab.close() - UI.projects.foundations.spaces.sideSpace.sidePanelTab.close() + UI.projects.foundations.spaces.workspaceSpace.sidePanelTab.close() UI.projects.foundations.spaces.floatingSpace.inMapMode = true workingAtTask = 2 break @@ -413,6 +413,8 @@ function newWorkspace() { UI.projects.foundations.spaces.floatingSpace.inMapMode = false thisObject.isInitialized = true + UI.projects.governance.spaces.reportsSpace.reset() + await UI.projects.education.spaces.docsSpace.reset() await UI.projects.education.spaces.tutorialSpace.reset() diff --git a/Projects/Foundations/UI/Spaces/Side-Space/SidePanelTab.js b/Projects/Foundations/UI/Spaces/Side-Space/SidePanelTab.js index cb6fb44ae..0fe13a547 100644 --- a/Projects/Foundations/UI/Spaces/Side-Space/SidePanelTab.js +++ b/Projects/Foundations/UI/Spaces/Side-Space/SidePanelTab.js @@ -15,7 +15,8 @@ function newSidePanelTab() { physics: physics, draw: draw, getContainer: getContainer, - initialize: initialize + initialize: initialize, + finalize: finalize } const TAB_WIDTH = 60 @@ -26,6 +27,7 @@ function newSidePanelTab() { let animation = 'none' let ORIGINAL_PARENT_POSITON let xOffset = 0 + let onMouseClickEventSubscriptionId thisObject.container = newContainer() thisObject.container.name = MODULE_NAME @@ -35,6 +37,11 @@ function newSidePanelTab() { return thisObject + function finalize() { + thisObject.pointerDirection = undefined + thisObject.container.eventHandler.stopListening(onMouseClickEventSubscriptionId) + } + function initialize(screenside, index) { thisObject.screenside = screenside if (index !== undefined) { @@ -54,7 +61,7 @@ function newSidePanelTab() { thisObject.container.frame.width = TAB_WIDTH thisObject.container.frame.height = TAB_HEIGHT - thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + onMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) resize() isInitialized = true } @@ -126,9 +133,7 @@ function newSidePanelTab() { } function positionPhysics() { - if (UI.projects.foundations.spaces.chartingSpace.viewport !== undefined) { - thisObject.container.frame.position.y = browserCanvas.height / 2 - TAB_HEIGHT / 2 // TOP_SPACE_HEIGHT + UI.projects.foundations.spaces.chartingSpace.viewport.marginAmount + TAB_HEIGHT * thisObject.index - } + thisObject.container.frame.position.y = browserCanvas.height / 2 - TAB_HEIGHT / 2 + (thisObject.index - 1) * TAB_HEIGHT } function draw() { @@ -382,7 +387,7 @@ function newSidePanelTab() { labelPosition = thisObject.container.frame.frameThisPoint(labelPosition) - browserCanvasContext.font = 12 + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.font = 12 + 'px ' + UI_FONT.PRIMARY browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREY + ', 1)' browserCanvasContext.fillText( thisObject.tabLabel, diff --git a/Projects/Foundations/UI/Spaces/Side-Space/SideSpace.js b/Projects/Foundations/UI/Spaces/Side-Space/SideSpace.js index 3ea331d34..54c027dab 100644 --- a/Projects/Foundations/UI/Spaces/Side-Space/SideSpace.js +++ b/Projects/Foundations/UI/Spaces/Side-Space/SideSpace.js @@ -1,173 +1,129 @@ function newFoundationsSideSpace() { - const MODULE_NAME = 'Side Space' let thisObject = { sidePanelTab: undefined, container: undefined, + leftTabs: undefined, + rightTabs: undefined, physics: physics, draw: draw, + createSidePanelTab: createSidePanelTab, + deleteSidePanelTab: deleteSidePanelTab, getContainer: getContainer, initialize: initialize, finalize: finalize } - let isInitialized = false + let existingTabs = new Map() - thisObject.container = newContainer() - thisObject.container.name = MODULE_NAME - thisObject.container.initialize() - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - thisObject.container.detectMouseOver = true - thisObject.container.status = 'hidden' - - let listView - - resize() - - let openingEventSubscriptionId - let closedEventSubscriptionId - let browserResizedEventSubscriptionId return thisObject function initialize() { - thisObject.sidePanelTab = newSidePanelTab() - thisObject.sidePanelTab.tabIcon = UI.projects.foundations.spaces.designSpace.getIconByProjectAndName('Foundations', 'workspace') - thisObject.sidePanelTab.tabLabel = 'Workspaces' - thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) - thisObject.sidePanelTab.initialize('left') - - browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) - - initializeListView() - isInitialized = true + thisObject.leftTabs = [] + thisObject.rightTabs = [] } function finalize() { - canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) - thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) - thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId) + thisObject.leftTabs = undefined + thisObject.rightTabs = undefined + existingTabs = undefined } - function initializeListView() { - listView = newListView() - listView.initialize() - listView.container.connectToParent(thisObject.container, false, false) - openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', listView.turnOn) - closedEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closed', listView.turnOff) - } + function createSidePanelTab(container, porject, iconName, label, side) { - function resize() { - thisObject.container.frame.width = SIDE_PANEL_WIDTH - thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT - thisObject.container.frame.position.x = -SIDE_PANEL_WIDTH - thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT + let sidePanel - if (listView !== undefined) { - listView.resize() + sidePanel = newSidePanelTab() + sidePanel.container.connectToParent(container, false, false) + sidePanel.tabIcon = UI.projects.foundations.spaces.designSpace.getIconByProjectAndName(porject, iconName) + sidePanel.tabLabel = label + sidePanel.initialize(side) + + let key = porject + '-' + iconName + '-' + label + '-' + side + if (existingTabs.get(key) !== undefined) { return existingTabs.get(key) } + + switch (side) { + case 'left': { + thisObject.leftTabs.push(sidePanel) + sidePanel.index = thisObject.leftTabs.length + + existingTabs.set(key, sidePanel) + break + } + case 'right': { + thisObject.rightTabs.push(sidePanel) + sidePanel.index = thisObject.rightTabs.length + + existingTabs.set(key, sidePanel) + break + } } - if (thisObject.sidePanelTab !== undefined) { - thisObject.sidePanelTab.resize() + return sidePanel + } + + function deleteSidePanelTab(porject, iconName, label, side) { + + let key = porject + '-' + iconName + '-' + label + '-' + side + if (existingTabs.get(key) !== undefined) { + let sidePanelTab = existingTabs.get(key) + + switch (side) { + case 'left': { + thisObject.leftTabs.splice(sidePanelTab.index - 1, 1) + break + } + case 'right': { + thisObject.rightTabs.splice(sidePanelTab.index - 1, 1) + break + } + } + + sidePanelTab.finalize() + existingTabs.delete(key) + + /* + Reindex Remaining SidTabs + */ + let indexLeft = 1 + let indexRight = 1 + + existingTabs.forEach(reindex) + + function reindex(sideTab, key, map) { + switch (sideTab.screenside) { + case 'left': { + sideTab.index = indexLeft + indexLeft++ + break + } + case 'right': { + sideTab.index = indexRight + indexRight++ + break + } + } + + } } } function getContainer(point, purpose) { - if (thisObject.sidePanelTab === undefined) { return } - let container - container = thisObject.sidePanelTab.getContainer(point, purpose) - if (container !== undefined) { return container } - - container = listView.getContainer(point, purpose) - if (container !== undefined) { return container } - - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } } function physics() { - thisObject.sidePanelTab.physics() - listView.physics() + existingTabs.forEach(sideTabPhysics) + + function sideTabPhysics(sideTab, key, map) { + sideTab.physics() + } } function draw() { - if (CAN_SPACES_DRAW === false) { return } - if (isInitialized === false) { return } - borders() - thisObject.sidePanelTab.draw() - listView.draw() - } + existingTabs.forEach(sideTabDraw) - function borders() { - let point1 - let point2 - let point3 - let point4 - - point1 = { - x: 0, - y: 0 - } - - point2 = { - x: thisObject.container.frame.width, - y: 0 - } - - point3 = { - x: thisObject.container.frame.width, - y: thisObject.container.frame.height - } - - point4 = { - x: 0, - y: thisObject.container.frame.height - } - - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - point3 = thisObject.container.frame.frameThisPoint(point3) - point4 = thisObject.container.frame.frameThisPoint(point4) - - browserCanvasContext.setLineDash([]) // Resets Line Dash - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.lineTo(point4.x, point4.y) - browserCanvasContext.lineTo(point1.x, point1.y) - browserCanvasContext.closePath() - - let opacity = 1 - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + '' - browserCanvasContext.fill() - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' - browserCanvasContext.lineWidth = 0.3 - browserCanvasContext.setLineDash([]) // Resets Line Dash - browserCanvasContext.stroke() - - /* Shadow */ - - if (thisObject.container.status !== 'hidden') { - for (let i = 0; i <= 30; i++) { - opacity = 1 - (i / 300) - 0.95 - - browserCanvasContext.setLineDash([]) // Resets Line Dash - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point2.x + i, point2.y) - browserCanvasContext.lineTo(point3.x + i, point3.y) - browserCanvasContext.closePath() - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' - browserCanvasContext.lineWidth = 1 - browserCanvasContext.setLineDash([]) // Resets Line Dash - browserCanvasContext.stroke() - } + function sideTabDraw(sideTab, key, map) { + sideTab.draw() } } } diff --git a/Projects/Foundations/UI/Spaces/Workspace-Space/WorkspaceSpace.js b/Projects/Foundations/UI/Spaces/Workspace-Space/WorkspaceSpace.js new file mode 100644 index 000000000..e90711410 --- /dev/null +++ b/Projects/Foundations/UI/Spaces/Workspace-Space/WorkspaceSpace.js @@ -0,0 +1,168 @@ +function newFoundationsWorkspaceSpace() { + const MODULE_NAME = 'Workspace Space' + let thisObject = { + sidePanelTab: undefined, + container: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize + } + + let isInitialized = false + + thisObject.container = newContainer() + thisObject.container.name = MODULE_NAME + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = true + thisObject.container.status = 'hidden' + + let listView + + resize() + + let openingEventSubscriptionId + let closedEventSubscriptionId + let browserResizedEventSubscriptionId + return thisObject + + function initialize() { + + thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Foundations', 'workspace', 'Workspaces', 'left') + + browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) + + initializeListView() + isInitialized = true + } + + function finalize() { + canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId) + } + + function initializeListView() { + listView = newListView() + listView.initialize() + listView.container.connectToParent(thisObject.container, false, false) + openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', listView.turnOn) + closedEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closed', listView.turnOff) + } + + function resize() { + thisObject.container.frame.width = SIDE_PANEL_WIDTH + thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT + thisObject.container.frame.position.x = -SIDE_PANEL_WIDTH + thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT + + if (listView !== undefined) { + listView.resize() + } + + if (thisObject.sidePanelTab !== undefined) { + thisObject.sidePanelTab.resize() + } + } + + function getContainer(point, purpose) { + if (thisObject.sidePanelTab === undefined) { return } + let container + + container = thisObject.sidePanelTab.getContainer(point, purpose) + if (container !== undefined) { return container } + + container = listView.getContainer(point, purpose) + if (container !== undefined) { return container } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } + + function physics() { + listView.physics() + } + + function draw() { + if (CAN_SPACES_DRAW === false) { return } + if (isInitialized === false) { return } + borders() + listView.draw() + } + + function borders() { + let point1 + let point2 + let point3 + let point4 + + point1 = { + x: 0, + y: 0 + } + + point2 = { + x: thisObject.container.frame.width, + y: 0 + } + + point3 = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + point4 = { + x: 0, + y: thisObject.container.frame.height + } + + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) + point4 = thisObject.container.frame.frameThisPoint(point4) + + browserCanvasContext.setLineDash([]) // Resets Line Dash + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() + + let opacity = 1 + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + '' + browserCanvasContext.fill() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' + browserCanvasContext.lineWidth = 0.3 + browserCanvasContext.setLineDash([]) // Resets Line Dash + browserCanvasContext.stroke() + + /* Shadow */ + + if (thisObject.container.status !== 'hidden') { + for (let i = 0; i <= 30; i++) { + opacity = 1 - (i / 300) - 0.95 + + browserCanvasContext.setLineDash([]) // Resets Line Dash + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point2.x + i, point2.y) + browserCanvasContext.lineTo(point3.x + i, point3.y) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.setLineDash([]) // Resets Line Dash + browserCanvasContext.stroke() + } + } + } +} diff --git a/Projects/Governance/Icons/governance-tab.png b/Projects/Governance/Icons/governance-tab.png new file mode 100644 index 000000000..281622484 Binary files /dev/null and b/Projects/Governance/Icons/governance-tab.png differ diff --git a/Projects/Governance/UI/Globals/Reports.js b/Projects/Governance/UI/Globals/Reports.js new file mode 100644 index 000000000..1315a1ec9 --- /dev/null +++ b/Projects/Governance/UI/Globals/Reports.js @@ -0,0 +1,6 @@ +function newGovernanceGlobalsReports() { + let thisObject = { + REPORTS_SPACE_WIDTH: 900 + } + return thisObject +} \ No newline at end of file diff --git a/Projects/Governance/UI/Spaces/Assets-Space/Assets.js b/Projects/Governance/UI/Spaces/Assets-Space/Assets.js deleted file mode 100644 index 3433850fc..000000000 --- a/Projects/Governance/UI/Spaces/Assets-Space/Assets.js +++ /dev/null @@ -1,47 +0,0 @@ -function newGobernanceAssetsSpace() { - const MODULE_NAME = 'Assets Space' - - let thisObject = { - container: undefined, - physics: physics, - draw: draw, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isDraggeable = false - - return thisObject - - function finalize() { - thisObject.container.finalize() - thisObject.container = undefined - } - - function initialize() { - - } - - function physics() { - if (UI.projects.foundations.spaces.designSpace.workspace === undefined) { return } - } - - function getContainer(point) { - - return undefined // since this space does not draw anything we return here - - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - thisObject.container.space = MODULE_NAME - return thisObject.container - } else { - return undefined - } - } - - function draw() { - - } -} diff --git a/Projects/Governance/UI/Spaces/Reports-Space/Footer.js b/Projects/Governance/UI/Spaces/Reports-Space/Footer.js new file mode 100644 index 000000000..f6ec9335b --- /dev/null +++ b/Projects/Governance/UI/Spaces/Reports-Space/Footer.js @@ -0,0 +1,158 @@ +function newGovernanceReportsFooter() { + let thisObject = { + addFooter: addFooter, + initialize: initialize, + finalize: finalize + } + + return thisObject + + function initialize() { + + } + + function finalize() { + + } + + function addFooter() { + + let HTML = '' + + HTML = HTML + '' // Container Ends + + return HTML + } +} \ No newline at end of file diff --git a/Projects/Governance/UI/Spaces/Reports-Space/ReportsPage.js b/Projects/Governance/UI/Spaces/Reports-Space/ReportsPage.js new file mode 100644 index 000000000..2b979d977 --- /dev/null +++ b/Projects/Governance/UI/Spaces/Reports-Space/ReportsPage.js @@ -0,0 +1,87 @@ +function newGovernanceReportsReportsPage() { + let thisObject = { + render: render, + initialize: initialize, + finalize: finalize + } + + return thisObject + + function initialize() { + + } + + function finalize() { + + } + + function render() { + + let resultsArary = [] + let initialTime = new Date() + buildHTML() + + function buildHTML() { + const tabs = ['Profiles', 'Referrals', 'Mentors', 'Supporters', 'Pools', 'Assets', 'Features', 'Positions'] + let HTML = '' + HTML = HTML + '
' + HTML = HTML + UI.projects.education.spaces.docsSpace.mainSearchPage.addSearchHeader() + + // Tabs + HTML = HTML + '
' + let checked = ' checked=""' + for (let i = 0; i < tabs.length; i++) { + let tab = tabs[i] + HTML = HTML + '' + checked = '' + } + + // Results + HTML = HTML + '
' + + let totalResults = new Map() + for (let i = 0; i < tabs.length; i++) { + let tab = tabs[i] + HTML = HTML + '
' + HTML = HTML + '

' + tab.toUpperCase() + '_TOTAL_RESULTS results (' + tab.toUpperCase() + '_TOTAL_SECONDS seconds)

' + + let resultCounter = 0 + + switch (tab) { + case 'Profiles': { + HTML = HTML + UI.projects.governance.spaces.reportsSpace.userProfiles.addHTML() + resultCounter = UI.projects.governance.spaces.reportsSpace.userProfiles.resultCounter + + break + } + } + + HTML = HTML + '
' + totalResults.set(tab, resultCounter) + } + + // End Content + HTML = HTML + '
' + HTML = HTML + '
' + + // End Section + HTML = HTML + '
' + + // Total Seconds Calculation + let finalTime = new Date() + let totalSeconds = ((finalTime.valueOf() - initialTime.valueOf()) / 1000).toFixed(3) + for (let i = 0; i < tabs.length; i++) { + let tab = tabs[i] + HTML = HTML.replace(tab.toUpperCase() + '_TOTAL_SECONDS', totalSeconds) + let resultCounter = totalResults.get(tab) + HTML = HTML.replace(tab.toUpperCase() + '_TOTAL_RESULTS', resultCounter) + } + + let docsContentDiv = document.getElementById('governance-content-div') + docsContentDiv.innerHTML = HTML + UI.projects.governance.spaces.reportsSpace.footer.addFooter() + + UI.projects.education.spaces.docsSpace.mainSearchPage.detectEnterOnSearchBox() + UI.projects.education.spaces.docsSpace.mainSearchPage.setFocusOnSearchBox() + } + } +} \ No newline at end of file diff --git a/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js b/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js new file mode 100644 index 000000000..6f3e4abac --- /dev/null +++ b/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js @@ -0,0 +1,233 @@ +function newGobernanceReportsSpace() { + const MODULE_NAME = 'Reports Space' + + let thisObject = { + container: undefined, + sidePanelTab: undefined, + reportsPage: undefined, + footer: undefined, + userProfiles: undefined, + tablesSortingOrders: undefined, + changeTableSortingOrder, + physics: physics, + draw: draw, + getContainer: getContainer, + finalize: finalize, + initialize: initialize, + reset: reset + } + + let browserResizedEventSubscriptionId + let openingEventSubscriptionId + let closingEventSubscriptionId + + let isInitialized = false + + return thisObject + + function finalize() { + + if (isInitialized === false) { return } + + thisObject.container.finalize() + thisObject.container = undefined + + canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(closingEventSubscriptionId) + thisObject.sidePanelTab = undefined + + UI.projects.foundations.spaces.sideSpace.deleteSidePanelTab('Governance', 'governance-tab', 'Gov', 'right') + + thisObject.reportsPage.finalize() + thisObject.reportsPage = undefined + + thisObject.footer.finalize() + thisObject.footer = undefined + + thisObject.userProfiles.finalize() + thisObject.userProfiles = undefined + + isInitialized = false + } + + function initialize() { + let resultsArary = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile') + if (resultsArary.length === 0) { return } + + thisObject.container = newContainer() + thisObject.container.name = MODULE_NAME + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = true + thisObject.container.status = 'hidden' + + resize() + + thisObject.reportsPage = newGovernanceReportsReportsPage() + thisObject.footer = newGovernanceReportsFooter() + thisObject.userProfiles = newGovernanceReportsUserProfiles() + + thisObject.reportsPage.initialize() + thisObject.footer.initialize() + thisObject.userProfiles.initialize() + + setupSidePanelTab() + + thisObject.tablesSortingOrders = {} + + isInitialized = true + + function setupSidePanelTab() { + + thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Governance', 'governance-tab', 'Gov', 'right') + + openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', onOpening) + closingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closing', onClosing) + + browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) + } + } + + function reset() { + finalize() + initialize() + } + + function resize() { + thisObject.container.frame.width = UI.projects.governance.globals.reports.REPORTS_SPACE_WIDTH + thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT + thisObject.container.frame.position.x = browserCanvas.width + thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT + + if (thisObject.sidePanelTab !== undefined) { + thisObject.sidePanelTab.resize() + } + } + + function physics() { + if (isInitialized === false) { return } + + docsAppDivPhysics() + + function docsAppDivPhysics() { + let docsSpaceDiv = document.getElementById('governance-reports-space-div') + docsAppDivPosition = { + x: 0, + y: 0 + } + docsAppDivPosition = thisObject.container.frame.frameThisPoint(docsAppDivPosition) + docsSpaceDiv.style = ' ' + + 'overflow-y: scroll;' + + 'overflow-x: hidden;' + + 'position:fixed; top:' + docsAppDivPosition.y + 'px; ' + + 'left:' + docsAppDivPosition.x + 'px; z-index:1; ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + } + } + + function getContainer(point, purpose) { + if (isInitialized === false) { return } + if (thisObject.sidePanelTab === undefined) { return } + let container + + container = thisObject.sidePanelTab.getContainer(point, purpose) + if (container !== undefined) { return container } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } + + function changeTableSortingOrder(table, property, order) { + thisObject.tablesSortingOrders[table].property = property + thisObject.tablesSortingOrders[table].order = order + thisObject.reportsPage.render() + } + + function onOpening() { + thisObject.reportsPage.render() + } + + function onClosing() { + + } + + function draw() { + if (CAN_SPACES_DRAW === false) { return } + if (isInitialized === false) { return } + borders() + } + + function borders() { + let point1 + let point2 + let point3 + let point4 + + point1 = { + x: 0, + y: 0 + } + + point2 = { + x: thisObject.container.frame.width, + y: 0 + } + + point3 = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + point4 = { + x: 0, + y: thisObject.container.frame.height + } + + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) + point4 = thisObject.container.frame.frameThisPoint(point4) + + browserCanvasContext.setLineDash([]) // Resets Line Dash + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() + + let opacity = 1 + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + '' + browserCanvasContext.fill() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' + browserCanvasContext.lineWidth = 0.3 + browserCanvasContext.stroke() + + /* Shadow */ + + if (thisObject.container.status !== 'hidden') { + for (let i = 0; i <= 30; i++) { + opacity = 1 - (i / 300) - 0.95 + + browserCanvasContext.setLineDash([]) // Resets Line Dash + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point2.x + i, point2.y) + browserCanvasContext.lineTo(point3.x + i, point3.y) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() + } + } + } +} diff --git a/Projects/Governance/UI/Spaces/Reports-Space/UserProfiles.js b/Projects/Governance/UI/Spaces/Reports-Space/UserProfiles.js new file mode 100644 index 000000000..03fc5dbcf --- /dev/null +++ b/Projects/Governance/UI/Spaces/Reports-Space/UserProfiles.js @@ -0,0 +1,205 @@ +function newGovernanceReportsUserProfiles() { + let thisObject = { + resultCounter: undefined, + addHTML: addHTML, + initialize: initialize, + finalize: finalize + } + + return thisObject + + function initialize() { + + } + + function finalize() { + + } + + function addHTML() { + + thisObject.resultCounter = 0 + let HTML = '' + let tableRecords = [] + let table = 'userProfiles' + let tableRecordDefinition = { + "properties": [ + { + "name": "name", + "label": "Name", + "type": "string", + "order": "ascending" + }, + { + "name": "blockchainPower", + "label": "Blockchain Power", + "type": "number", + "order": "descending" + }, + { + "name": "delegatedPower", + "label": "Delegated Power", + "type": "number", + "order": "descending" + }, + { + "name": "tokenPower", + "label": "Token Power", + "type": "number", + "order": "descending" + } + ] + } + /* + Here we get from the workspace all the nodes representing User Profiles. + */ + let resultsArary = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile') + /* + Transform the result array into table records. + */ + for (let j = 0; j < resultsArary.length; j++) { + let node = resultsArary[j] + + let tableRecord = { + "name": node.name, + "blockchainPower": node.payload.blockchainTokens | 0, + "delegatedPower": node.payload.tokenPower - node.payload.blockchainTokens | 0, + "tokenPower": node.payload.tokenPower | 0 + } + + tableRecords.push(tableRecord) + } + /* + Get the sorting order for this table. + */ + let sortingOrder = UI.projects.governance.spaces.reportsSpace.tablesSortingOrders[table] + /* + Set the default sorting order for this table. + */ + if (sortingOrder === undefined) { + UI.projects.governance.spaces.reportsSpace.tablesSortingOrders[table] = { + property: 'name', + order: 'ascending' + } + sortingOrder = UI.projects.governance.spaces.reportsSpace.tablesSortingOrders[table] + } + /* + Get the property type for the current sorting order. + */ + let propertyType + for (let i = 0; i < tableRecordDefinition.properties.length; i++) { + let property = tableRecordDefinition.properties[i] + if (property.name === sortingOrder.property) { + propertyType = property.type + break + } + } + /* + Apply the sorting order for this table. + */ + switch (propertyType) { + case 'string': { + switch (sortingOrder.order) { + case 'ascending': { + tableRecords.sort((a, b) => (a[sortingOrder.property].toLowerCase() > b[sortingOrder.property].toLowerCase()) ? 1 : -1) + break + } + case 'descending': { + tableRecords.sort((a, b) => (a[sortingOrder.property].toLowerCase() > b[sortingOrder.property].toLowerCase()) ? -1 : 1) + break + } + } + break + } + case 'number': { + switch (sortingOrder.order) { + case 'ascending': { + tableRecords.sort((a, b) => (a[sortingOrder.property] > b[sortingOrder.property]) ? 1 : -1) + break + } + case 'descending': { + tableRecords.sort((a, b) => (a[sortingOrder.property] > b[sortingOrder.property]) ? -1 : 1) + break + } + } + break + } + } + + /* + Build the HTML + */ + let odd = false + const upArrow = '↑' + const downArrow = '↓' + + HTML = HTML + '' + HTML = HTML + '' + HTML = HTML + '' + for (let i = 0; i < tableRecordDefinition.properties.length; i++) { + let property = tableRecordDefinition.properties[i] + let newOrder + let orderArrow + /* + If the property is the one defining the order, then the new order will be + the opossite order. + */ + if (property.name === sortingOrder.property) { + if (sortingOrder.order === 'ascending') { + newOrder = 'descending' + orderArrow = upArrow + } else { + newOrder = 'ascending' + orderArrow = downArrow + } + } else { + orderArrow = "" + /* + If the property is not the current defininf the order, then the new order will + be the default order for that property. + */ + for (let i = 0; i < tableRecordDefinition.properties.length; i++) { + let propertyDefinition = tableRecordDefinition.properties[i] + if (property.name === propertyDefinition.name) { + newOrder = propertyDefinition.order + break + } + } + } + HTML = HTML + '' + } + HTML = HTML + '' + HTML = HTML + '' + HTML = HTML + '' + + for (let j = 0; j < tableRecords.length; j++) { + let tableRecord = tableRecords[j] + + if (odd === true) { + HTML = HTML + '' + odd = false + } else { + HTML = HTML + '' + odd = true + } + + /* + Iterate through tableRecord properties. + */ + for (var property in tableRecord) { + if (Object.prototype.hasOwnProperty.call(tableRecord, property)) { + HTML = HTML + '' + } + } + + thisObject.resultCounter++ + + HTML = HTML + '' + } + + HTML = HTML + '' + HTML = HTML + '
' + '' + property.label + ' ' + orderArrow +'' + '
' + tableRecord[property] + '
' + + return HTML + } +} \ No newline at end of file diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index 45d7cf427..38bf41a33 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -228,8 +228,8 @@ "initializationIndex": 0, "animationPhysicsIndex": 1, "animationDrawIndex": 0, - "onMouseWheelIndex": 5, - "onMouseOverIndex": 6, + "onMouseWheelIndex": 6, + "onMouseOverIndex": 7, "onMouseClickIndex": 4, "onMouseDownIndex": 6 }, @@ -253,8 +253,8 @@ "initializationIndex": 2, "animationPhysicsIndex": 0, "animationDrawIndex": 5, - "onMouseWheelIndex": 3, - "onMouseOverIndex": 2, + "onMouseWheelIndex": 4, + "onMouseOverIndex": 3, "onMouseClickIndex": 2, "onMouseDownIndex": 3 }, @@ -267,7 +267,7 @@ "animationPhysicsIndex": 3, "animationDrawIndex": 2, "onMouseWheelIndex": 0, - "onMouseOverIndex": 5, + "onMouseOverIndex": 6, "onMouseClickIndex": 0, "onMouseDownIndex": 1 }, @@ -279,8 +279,8 @@ "initializationIndex": 4, "animationPhysicsIndex": 4, "animationDrawIndex": 3, - "onMouseWheelIndex": 2, - "onMouseOverIndex": 3, + "onMouseWheelIndex": 3, + "onMouseOverIndex": 4, "onMouseClickIndex": 3, "onMouseDownIndex": 4 }, @@ -292,8 +292,8 @@ "initializationIndex": 5, "animationPhysicsIndex": 2, "animationDrawIndex": 1, - "onMouseWheelIndex": 4, - "onMouseOverIndex": 4, + "onMouseWheelIndex": 5, + "onMouseOverIndex": 5, "onMouseClickIndex": 5, "onMouseDownIndex": 5 }, @@ -305,11 +305,24 @@ "initializationIndex": 6, "animationPhysicsIndex": 6, "animationDrawIndex": 6, - "onMouseWheelIndex": 1, - "onMouseOverIndex": 2, + "onMouseWheelIndex": 2, + "onMouseOverIndex": 3, "onMouseClickIndex": 6, "onMouseDownIndex": 0 }, + { + "name": "Workspace Space", + "folderName": "Workspace-Space", + "propertyName": "workspaceSpace", + "functionName": "newFoundationsWorkspaceSpace", + "initializationIndex": 7, + "animationPhysicsIndex": 7, + "animationDrawIndex": 7, + "onMouseWheelIndex": 1, + "onMouseOverIndex": 2, + "onMouseClickIndex": 7, + "onMouseDownIndex": 0 + }, { "name": "Chat Space", "folderName": "Chat-Space", @@ -956,7 +969,13 @@ "name": "Governance", "propertyName": "governance", "UI": { - "globals": [], + "globals": [ + { + "name": "Reports", + "propertyName": "reports", + "functionName": "newGovernanceGlobalsReports" + } + ], "functionLibraries": [ { "name": "Assets", @@ -1066,10 +1085,10 @@ "onMouseDownIndex": 0 }, { - "name": "Assets Space", - "folderName": "Assets-Space", - "propertyName": "assetsSpace", - "functionName": "newGobernanceAssetsSpace", + "name": "Reports Space", + "folderName": "Reports-Space", + "propertyName": "reportsSpace", + "functionName": "newGobernanceReportsSpace", "initializationIndex": 1, "animationPhysicsIndex": 1, "animationDrawIndex": 1,