diff --git a/angularjs-portal-home/pom.xml b/angularjs-portal-home/pom.xml
index 0efcfee81..405d11ad5 100644
--- a/angularjs-portal-home/pom.xml
+++ b/angularjs-portal-home/pom.xml
@@ -22,7 +22,7 @@
edu.wisc.my.apps
uw-frame
war
- 3.1.5-SNAPSHOT
+ 4.0.1-SNAPSHOT
diff --git a/angularjs-portal-home/src/main/webapp/css/widget.less b/angularjs-portal-home/src/main/webapp/css/widget.less
index 7d0175b73..40569968a 100644
--- a/angularjs-portal-home/src/main/webapp/css/widget.less
+++ b/angularjs-portal-home/src/main/webapp/css/widget.less
@@ -1,265 +1,3 @@
-// LIST OF LINKS
-lol {
- .list-of-links {
- height: 194px;
- padding: 0;
-
- div[class^="list-of-links__"] {
- height: 194px;
- overflow: hidden;
- display: flex;
- flex-flow: row wrap;
-
- &.list-of-links__1 {
- justify-content: center;
- align-items: center;
- align-content: center;
- }
-
- &.list-of-links__2 {
- justify-content: space-around;
- align-items: baseline;
- align-content: center;
- padding: 40px 0;
- }
-
- &.list-of-links__3 {
- justify-content: space-around;
- align-items: baseline;
- align-content: space-around;
- }
-
- &.list-of-links__4 {
- justify-content: space-around;
- align-items: baseline;
- align-content: flex-start;
- }
-
- &.list-of-links__long {
- justify-content: space-around;
-
- .widget-list a:hover {
- cursor: pointer;
- }
- }
-
- circle-button {
- width: 120px;
- height: 88px;
- text-align: center;
- }
- }
- }
-}
-
-// OPTION LINK
-option-link {
- .widget-option-link {
- height: 196px;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-content: center;
- align-items: center;
-
- .option-link-icon {
- margin-bottom: 16px;
-
- i {
- color: @grayscale10;
- font-size: 70px;
- }
- }
-
- md-input-container {
- margin: 0 0 18px;
- }
- }
-}
-
-// RSS
-rss {
- .rss {
- overflow-y: hidden;
- height: 194px;
-
- .widget-list {
- max-height: 194px;
-
- li a {
- div {
- display: inline-block;
- }
-
- div.headline {
- width: 80%;
- font-size: 12px;
- }
-
- div.headline.nodate {
- width: 100%;
- }
-
- div.date {
- width: 18%;
- font-size: 10px;
- vertical-align: top;
- }
- }
- }
- }
-}
-
-// SEARCH WITH LINKS
-swl {
- md-input-container {
- margin-top: 0;
- padding-right: 16px;
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
- align-content: flex-start;
-
- .md-button {
- margin: 0;
- padding: 0;
- }
- }
-
- div[class^="search-with-links__"] {
- display: flex;
- flex-direction: row;
- justify-content: center;
- align-items: baseline;
- align-content: center;
- width: 100%;
-
- circle-button {
- width: 120px;
- height: 88px;
- text-align: center;
- }
- }
-}
-
-// BASIC
-.basic-widget {
- height: 194px;
- display: flex;
- justify-content: center;
- align-items: flex-start;
- align-content: center;
-
- .widget-icon-container {
- padding-top: 40px;
- }
-
- &:hover {
- text-decoration: none !important;
- }
-}
-
-// CUSTOM
-.custom-widget {
- height: 194px;
-
- md-input-container {
- margin-top: 0;
- margin-bottom: 0;
- padding-right: 16px;
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
- align-content: flex-start;
- }
-}
-
-// WEATHER
-weather {
- .forecast .day {
- text-align: center;
- border-radius: 4px;
- padding: 0 8px;
-
- p {
- font-size: 11px;
- }
- }
-
- .fa-exclamation-triangle {
- font-size: -webkit-xxx-large;
- width: 100%;
- text-align: center;
- padding-bottom: 20px;
- padding-top: 12px;
- }
-
- .warning-message-weather-widget {
- text-align: -webkit-center;
- padding: 20px;
- }
-
- .fa-frown-o {
- font-size: 50px;
- width: 100%;
- text-align: center;
- }
-
- .error-message-weather-widget {
- font-size: smaller;
- text-align: center;
- }
-
- img {
- width: 42px;
- position: relative;
- right: 1px;
- }
-
- a {
- color: #666;
- }
-
- .credit {
- position: absolute;
- font-size: 9px;
- right: 0;
-
- a {
- color: @color1;
-
- &:hover {
- text-decoration: underline;
- }
- }
- }
-
- .weather-dropdown {
- position: absolute;
- bottom: 39px;
- left: 12px;
- font-size: 10px;
- }
-
- .weather-not-clicked {
- color: #b70101;
- }
-
- @media (max-width: 1246px) {
- .weather-dropdown {
- right: 20px;
- }
- }
-
- @media (max-width: 1200px) {
- .weather-dropdown {
- right: 30px;
- }
- }
-}
-
// WIDGET CREATOR
.widget-creator {
.portlet-body {
@@ -306,48 +44,6 @@ weather {
}
}
-.scroll-widget {
- max-height: 210px;
- overflow-y: scroll;
-}
-
-.fixed-width-widget {
- width: 315px;
-}
-
-.widget-middle {
- width: 315px;
- margin: auto;
-}
-
-// MAINTENANCE MODE
-.widget-frame {
- .overlay__maintenance-mode {
- position: absolute;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.5);
- z-index: 99;
- border-radius: 3px;
-
- .maintenance-content {
- text-align: center;
- font-weight: bold;
- padding: 10px;
- background: #fff;
- margin: 66px 10px 0;
- display: block;
- border-radius: 3px;
-
- p {
- margin-bottom: 0;
-
- .material-icons {
- height: 40px;
- width: 40px;
- font-size: 40px;
- }
- }
- }
- }
+&.widget-remove {
+ right: 0;
}
diff --git a/angularjs-portal-home/src/main/webapp/my-app/layout/directives.js b/angularjs-portal-home/src/main/webapp/my-app/layout/directives.js
index b2f2940d6..fc75a2059 100644
--- a/angularjs-portal-home/src/main/webapp/my-app/layout/directives.js
+++ b/angularjs-portal-home/src/main/webapp/my-app/layout/directives.js
@@ -10,13 +10,6 @@ define(['angular', 'require'], function(angular, require) {
};
});
- app.directive('defaultCard', function() {
- return {
- restrict: 'E',
- templateUrl: require.toUrl('./partials/default-card.html'),
- };
- });
-
app.directive('marketplaceLight', function() {
return{
restrict: 'E',
@@ -39,6 +32,14 @@ define(['angular', 'require'], function(angular, require) {
};
});
+ app.directive('removeButton', function() {
+ return {
+ restrict: 'E',
+ controller: 'LayoutController',
+ templateUrl: require.toUrl('./partials/remove-button.html'),
+ };
+ });
+
return app;
});
diff --git a/angularjs-portal-home/src/main/webapp/my-app/layout/partials/default-card.html b/angularjs-portal-home/src/main/webapp/my-app/layout/partials/default-card.html
deleted file mode 100644
index 465b9e4cb..000000000
--- a/angularjs-portal-home/src/main/webapp/my-app/layout/partials/default-card.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- {{portlet.description}}
-
- info
-
-
- close
-
-
-
-
-
-
{{ ::portlet.title }}
-
-
-
-
-
diff --git a/angularjs-portal-home/src/main/webapp/my-app/layout/partials/remove-button.html b/angularjs-portal-home/src/main/webapp/my-app/layout/partials/remove-button.html
new file mode 100644
index 000000000..ac07791e7
--- /dev/null
+++ b/angularjs-portal-home/src/main/webapp/my-app/layout/partials/remove-button.html
@@ -0,0 +1,6 @@
+
+ close
+
diff --git a/angularjs-portal-home/src/main/webapp/my-app/layout/static/partials/static-content-card.html b/angularjs-portal-home/src/main/webapp/my-app/layout/static/partials/static-content-card.html
deleted file mode 100644
index 46662a147..000000000
--- a/angularjs-portal-home/src/main/webapp/my-app/layout/static/partials/static-content-card.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
{{ ::portlet.title }}
-
-
-
-
-
-
- {{:: portlet.description | truncate:160}}
-
-
-
-
diff --git a/angularjs-portal-home/src/main/webapp/my-app/layout/widget/controllers.js b/angularjs-portal-home/src/main/webapp/my-app/layout/widget/controllers.js
deleted file mode 100644
index f3e5e6a85..000000000
--- a/angularjs-portal-home/src/main/webapp/my-app/layout/widget/controllers.js
+++ /dev/null
@@ -1,601 +0,0 @@
-'use strict';
-
-define(['angular'], function(angular) {
- var app = angular.module('my-app.layout.widget.controllers', []);
-
- /**
- * Controller for 'optionLink' directive (/widget/directives.js)
- */
- app.controller('OptionLinkController', ['$scope', '$log', 'layoutService',
- function($scope, $log, layoutService) {
- /**
- * Set up default configuration if no config exists
- */
- var configInit = function() {
- $scope.config = {
- singleElement: false,
- arrayName: 'array',
- value: 'value',
- display: 'display',
- };
- };
-
- /**
- * Set up the widget based on received configuration
- */
- var populateWidgetContent = function() {
- if ($scope.portlet.widgetURL && $scope.portlet.widgetType) {
- // Initialize portlet widget json
- $scope.portlet.widgetData = [];
- // Fetch widget JSON
- layoutService.getWidgetJson($scope.portlet).then(function(data) {
- if (data) {
- var arr = $scope.portlet.widgetData[$scope.config.arrayName];
- if ($scope.config.singleElement) {
- // Set the default selected url
- $scope.portlet.selectedUrl =
- $scope.portlet.widgetData[$scope.config.value];
- } else if (arr && arr.length > 0) {
- $scope.portlet.selectedUrl = arr[0][$scope.config.value];
- }
- } else {
- $log.warn('Got nothing back from widget fetch for ' +
- $scope.portlet.fname);
- }
- return data;
- }).catch(function() {
- $log.warn('Could not getWidgetJson ' + $scope.portlet);
- });
- }
- };
-
- // Set default values if no config was received
- if (!$scope.config) {
- configInit();
- }
- // Set up widget content
- populateWidgetContent();
- }]);
-
- /**
- * Controller for weather widget (/widget/directives.js)
- */
- app.controller('WeatherController',
- ['$scope', '$log', 'layoutService', 'keyValueService', '$q',
- function($scope, $log, layoutService, keyValueService, $q) {
- // Bindable members
- $scope.weatherData = [];
- $scope.loading = false;
- $scope.fetchKey = 'userWeatherPreference';
- $scope.currentUnits = 'F';
- $scope.nextUnits = 'C';
-
- /**
- * Configure widget content
- */
- var populateWidgetContent = function() {
- if ($scope.portlet.widgetURL && $scope.portlet.widgetType) {
- $scope.loading = true;
- // fetch portlet widget json
- $scope.portlet.widgetData = [];
- var widgetPromise = layoutService.getWidgetJson($scope.portlet);
- var preferencePromise = keyValueService.getValue($scope.fetchKey);
-
- $q.all([widgetPromise, preferencePromise]).then(function(data) {
- $scope.loading = false;
-
- if (data) {
- $log.debug(data);
- var allTheWeathers = data[0];
- var myPref = data[1];
- $scope.portlet.widgetData = allTheWeathers.weathers;
- $scope.weatherData = $scope.portlet.widgetData;
- $scope.currentUnits = 'F';
- $scope.nextUnits = 'C';
- var userPreference = myPref.userWeatherPreference;
- if (userPreference === null || userPreference === '' ||
- typeof userPreference === 'undefined') {
- userPreference = 'F';
- }
-
- while (userPreference != $scope.currentUnits) {
- $scope.cycleUnits();
- }
- } else {
- $scope.error = true;
- $log.warn('Got nothing back from widget fetch');
- }
- return data;
- }).catch(function() {
- $scope.loading = false;
- $scope.error = true;
- });
- }
- };
-
- /**
- * Respond to click events when changing temperature unit type
- */
- $scope.cycleUnits = function() {
- var userPreference = $scope.nextUnits;
- var value = {};
-
- if (userPreference === 'F') {
- $scope.changeKToF();
- $scope.currentUnits = 'F';
- $scope.nextUnits = 'C';
- }
- if (userPreference === 'C') {
- $scope.changeFToC();
- $scope.currentUnits = 'C';
- $scope.nextUnits = 'K';
- }
- if (userPreference === 'K') {
- $scope.changeCToK();
- $scope.currentUnits = 'K';
- $scope.nextUnits = 'F';
- }
-
- // Set user preference
- value.userWeatherPreference = $scope.currentUnits;
-
- // Remember the user's preferred unit of measurement
- keyValueService.setValue($scope.fetchKey, value);
- };
-
- /**
- * Change from farenheit to celsius
- */
- $scope.changeFToC = function() {
- var ratio = (5 / 9);
- var offset = 32;
- for (var i = 0; i < $scope.weatherData.length; i++) {
- $scope.weatherData[i].currentWeather.temperature =
- ($scope.weatherData[i].currentWeather.temperature -
- offset) * ratio;
- for (var j = 0; j < $scope.weatherData[i].forecast.length; j++) {
- $scope.weatherData[i].forecast[j].highTemperature =
- ($scope.weatherData[i].forecast[j].highTemperature -
- offset) * ratio;
- $scope.weatherData[i].forecast[j].lowTemperature =
- ($scope.weatherData[i].forecast[j].lowTemperature -
- offset) * ratio;
- }
- }
- };
-
- /**
- * Change from celsius to kelvin
- */
- $scope.changeCToK = function() {
- var offset = 273;
- for (var i = 0; i < $scope.weatherData.length; i++) {
- $scope.weatherData[i].currentWeather.temperature =
- ($scope.weatherData[i].currentWeather.temperature + offset);
-
- for (var j = 0; j < $scope.weatherData[i].forecast.length; j++) {
- $scope.weatherData[i].forecast[j].highTemperature =
- ($scope.weatherData[i].forecast[j].highTemperature + offset);
- $scope.weatherData[i].forecast[j].lowTemperature =
- ($scope.weatherData[i].forecast[j].lowTemperature + offset);
- }
- }
- };
-
- /**
- * Change kelvin to celsius
- */
- $scope.changeKToC = function() {
- var offset = 273;
- for (var i = 0; i < $scope.weatherData.length; i++) {
- $scope.weatherData[i].currentWeather.temperature =
- ($scope.weatherData[i].currentWeather.temperature - offset);
-
- for (var j = 0; j < $scope.weatherData[i].forecast.length; j++) {
- $scope.weatherData[i].forecast[j].highTemperature =
- ($scope.weatherData[i].forecast[j].highTemperature - offset);
- $scope.weatherData[i].forecast[j].lowTemperature =
- ($scope.weatherData[i].forecast[j].lowTemperature - offset);
- }
- }
- };
-
- /**
- * Change celsius to farenheit
- */
- $scope.changeCToF = function() {
- var ratio = (9 / 5);
- var offset = 32;
- for (var i = 0; i < $scope.weatherData.length; i++) {
- $scope.weatherData[i].currentWeather.temperature =
- ($scope.weatherData[i].currentWeather.temperature *
- ratio) + offset;
-
- for (var j = 0; j < $scope.weatherData[i].forecast.length; j++) {
- $scope.weatherData[i].forecast[j].highTemperature =
- ($scope.weatherData[i].forecast[j].highTemperature *
- ratio) + offset;
- $scope.weatherData[i].forecast[j].lowTemperature =
- ($scope.weatherData[i].forecast[j].lowTemperature *
- ratio) + offset;
- }
- }
- };
-
- /**
- * Change kelvin to farenheit (via celsius)
- */
- $scope.changeKToF = function() {
- $scope.changeKToC();
- $scope.changeCToF();
- };
-
- // Initialize weather widget
- populateWidgetContent();
- $scope.details = false;
- }]);
-
- /**
- * Controller for 'rss' widget type (/widget/directives.js)
- */
- app.controller('RSSWidgetController',
- ['$scope', 'layoutService',
- function($scope, layoutService) {
- /**
- *
- * @param dateString
- * @returns {*}
- */
- $scope.getPrettyDate = function(dateString) {
- // Create a new date if a date string was provided, otherwise return null
- return dateString ? new Date(dateString) : null;
- };
-
- /**
- * Initialize rss widget
- */
- var init = function() {
- $scope.loading = true;
- // Only initialize if everything is provided
- if ($scope.portlet &&
- $scope.portlet.widgetURL &&
- $scope.portlet.widgetType) {
- // Set defaults if any config attributes are missing
- if (!$scope.config) {
- $scope.config = {};
- }
- if (!$scope.config.lim) {
- $scope.config.lim = 5;
- }
- if (!$scope.config.titleLim) {
- $scope.config.titleLim = 40;
- }
- if (!$scope.config.showShowing) {
- $scope.config.showShowing = false;
- }
-
- // If we got JSON, display it in the widget
- var successFn = function(result) {
- $scope.loading = false;
- $scope.data = result.data;
-
- if ($scope.data.status !== 'ok') {
- $scope.error = true;
- $scope.loading = false;
- } else {
- if (!$scope.data.items || $scope.data.items.length == 0) {
- $scope.isEmpty = true;
- $scope.loading = false;
- $scope.error = true;
- } else {
- if (!$scope.config.showShowing &&
- $scope.data.items.length > $scope.config.lim) {
- $scope.config.showShowing = true;
- }
- }
- }
- };
-
- // If getting JSON failed, show empty widget
- var errorFn = function(data) {
- $scope.error = true;
- $scope.isEmpty = true;
- $scope.loading = false;
- };
-
- // Get rss as JSON feed
- layoutService.getRSSJsonified($scope.portlet.widgetURL)
- .then(successFn).catch(errorFn);
- }
- };
-
- init();
- }]);
-
- /**
- * Controller for 'swl' widget type (/widget/directives.js)
- */
- app.controller('SearchWithLinksController',
- ['$scope', '$sce', function($scope, $sce) {
- $scope.secureURL = $sce.trustAsResourceUrl($scope.config.actionURL);
- }]);
-
- /**
- * Controller for 'generic' and 'custom' widget types
- * (/widget/partials/widget-card.html)
- */
- app.controller('CustomWidgetController',
- ['$scope', 'layoutService', '$log',
- function($scope, layoutService, $log) {
- $scope.loading = false;
- /**
- * Configure widget content
- */
- var populateWidgetContent = function() {
- if ($scope.portlet.widgetURL && $scope.portlet.widgetType) {
- $scope.loading = true;
- // fetch portlet widget json
- $scope.portlet.widgetData = [];
- layoutService.getWidgetJson($scope.portlet).then(function(data) {
- $scope.loading = false;
- if (data) {
- $scope.portlet.widgetData = data;
- $scope.content = $scope.portlet.widgetData;
- if (Array.isArray($scope.content) && $scope.content.length == 0) {
- $scope.isEmpty = true;
- } else if ($scope.portlet.widgetConfig &&
- $scope.portlet.widgetConfig.evalString
- && eval($scope.portlet.widgetConfig.evalString)) {
- // ideally this would do a check on an embedded
- // object for emptiness
- // example : '$scope.content.report.length === 0'
- $scope.isEmpty = true;
- }
- } else {
- $log.warn('Got nothing back from widget fetch from ' +
- $scope.portlet.widgetURL);
- $scope.isEmpty = true;
- }
- return data;
- }).catch(function() {
- $scope.loading = false;
- });
- }
- };
-
- /**
- * Filter array for provided values of a given object -- used by some widgets (i.e. Leave Balances)
- *
- * @param {Array