Merge branch 'temp-packages' into dev-v7
# Conflicts: # src/Umbraco.Web.UI.Client/src/less/components/editor/subheader/umb-editor-sub-header.less
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.resources.ourPackageRepositoryResource
|
||||
* @description handles data for package installations
|
||||
**/
|
||||
function ourPackageRepositoryResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
|
||||
var baseurl = "https://our.umbraco.org/webapi/packages/v1";
|
||||
|
||||
return {
|
||||
|
||||
getDetails: function (packageId) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(baseurl + "/" + packageId),
|
||||
'Failed to get package details');
|
||||
},
|
||||
|
||||
getCategories: function () {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(baseurl),
|
||||
'Failed to query packages');
|
||||
},
|
||||
|
||||
getPopular: function (maxResults, category) {
|
||||
|
||||
if (maxResults === undefined) {
|
||||
maxResults = 10;
|
||||
}
|
||||
if (category === undefined) {
|
||||
category = "";
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(baseurl + "?pageIndex=0&pageSize=" + maxResults + "&category=" + category + "&order=Popular"),
|
||||
'Failed to query packages');
|
||||
},
|
||||
|
||||
search: function (pageIndex, pageSize, category, query, canceler) {
|
||||
|
||||
var httpConfig = {};
|
||||
if (canceler) {
|
||||
httpConfig["timeout"] = canceler;
|
||||
}
|
||||
|
||||
if (category === undefined) {
|
||||
category = "";
|
||||
}
|
||||
if (query === undefined) {
|
||||
query = "";
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(baseurl + "?pageIndex=" + pageIndex + "&pageSize=" + pageSize + "&category=" + category + "&query=" + query),
|
||||
httpConfig,
|
||||
'Failed to query packages');
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('umbraco.resources').factory('ourPackageRepositoryResource', ourPackageRepositoryResource);
|
||||
@@ -7,6 +7,31 @@ function packageResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.packageInstallResource#getInstalled
|
||||
* @methodOf umbraco.resources.packageInstallResource
|
||||
*
|
||||
* @description
|
||||
* Gets a list of installed packages
|
||||
*/
|
||||
getInstalled: function() {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"packageInstallApiBaseUrl",
|
||||
"GetInstalled")),
|
||||
'Failed to get installed packages');
|
||||
},
|
||||
|
||||
uninstall: function(packageId) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"packageInstallApiBaseUrl",
|
||||
"Uninstall", { packageId: packageId })),
|
||||
'Failed to uninstall package');
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
|
||||
@@ -1,4 +1,62 @@
|
||||
/*Contains multiple services for various helper tasks */
|
||||
function versionHelper() {
|
||||
|
||||
return {
|
||||
|
||||
//see: https://gist.github.com/TheDistantSea/8021359
|
||||
versionCompare: function(v1, v2, options) {
|
||||
var lexicographical = options && options.lexicographical,
|
||||
zeroExtend = options && options.zeroExtend,
|
||||
v1parts = v1.split('.'),
|
||||
v2parts = v2.split('.');
|
||||
|
||||
function isValidPart(x) {
|
||||
return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
|
||||
}
|
||||
|
||||
if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
|
||||
return NaN;
|
||||
}
|
||||
|
||||
if (zeroExtend) {
|
||||
while (v1parts.length < v2parts.length) {
|
||||
v1parts.push("0");
|
||||
}
|
||||
while (v2parts.length < v1parts.length) {
|
||||
v2parts.push("0");
|
||||
}
|
||||
}
|
||||
|
||||
if (!lexicographical) {
|
||||
v1parts = v1parts.map(Number);
|
||||
v2parts = v2parts.map(Number);
|
||||
}
|
||||
|
||||
for (var i = 0; i < v1parts.length; ++i) {
|
||||
if (v2parts.length === i) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (v1parts[i] === v2parts[i]) {
|
||||
continue;
|
||||
}
|
||||
else if (v1parts[i] > v2parts[i]) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (v1parts.length !== v2parts.length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.services').factory('versionHelper', versionHelper);
|
||||
|
||||
function packageHelper(assetsService, treeService, eventsService, $templateCache) {
|
||||
|
||||
|
||||
@@ -108,6 +108,8 @@
|
||||
@import "components/umb-empty-state.less";
|
||||
@import "components/umb-property-editor.less";
|
||||
@import "components/umb-iconpicker.less";
|
||||
@import "components/umb-packages.less";
|
||||
@import "components/umb-package-local-install.less";
|
||||
|
||||
@import "components/buttons/umb-button.less";
|
||||
@import "components/buttons/umb-button-group.less";
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
//
|
||||
// Install local package
|
||||
//
|
||||
|
||||
// Helpers
|
||||
.faded {
|
||||
color: @grayMed;
|
||||
}
|
||||
|
||||
.inline-flex {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.mt-3 {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
// Upload state
|
||||
|
||||
.umb-upload-local,
|
||||
.umb-info-local {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.umb-upload-local form,
|
||||
.umb-info-local-items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
margin: 0;
|
||||
|
||||
max-width: 640px;
|
||||
}
|
||||
|
||||
.umb-upload-local__dropzone {
|
||||
position: relative;
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
border: 2px dashed @grayLight;
|
||||
border-radius: 3px;
|
||||
background: @grayLighter;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
margin-bottom: 30px;
|
||||
|
||||
transition: 100ms box-shadow ease, 100ms border ease;
|
||||
|
||||
&:hover,
|
||||
&.drag-over {
|
||||
border-color: @blue;
|
||||
border-style: solid;
|
||||
box-shadow: 0 3px 8px rgba(0,0,0, .1);
|
||||
transition: 100ms box-shadow ease, 100ms border ease;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-upload-local__dropzone i {
|
||||
display: block;
|
||||
color: @grayLight;
|
||||
font-size: 110px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.umb-upload-local__select-file {
|
||||
font-weight: bold;
|
||||
color: @blue;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
// Accept terms
|
||||
.umb-accept-terms {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.umb-package-installer-label .label-text {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.umb-package-installer-label input[type="radio"],
|
||||
.umb-package-installer-label input[type="checkbox"] {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.umb-package-installer-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
font-size: 13px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
// Info state
|
||||
.umb-info-local-items {
|
||||
border: 2px solid @grayLight;
|
||||
border-radius: 3px;
|
||||
background: @grayLighter;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
margin: 0 20px;
|
||||
max-width: 540px;
|
||||
}
|
||||
|
||||
.umb-info-local-items a {
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-info-local-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.umb-info-local-items .umb-package-icon {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
min-height: 150px;
|
||||
font-size: 60px;
|
||||
}
|
||||
|
||||
.umb-info-local-items .umb-package-icon img {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.umb-info-local-items .umb-package-info {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20px 40px;
|
||||
}
|
||||
|
||||
.umb-info-local-items .umb-package-installer-label {
|
||||
margin-left: 10px;
|
||||
}
|
||||
520
src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less
Normal file
520
src/Umbraco.Web.UI.Client/src/less/components/umb-packages.less
Normal file
@@ -0,0 +1,520 @@
|
||||
.umb-packages-view-title {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: @black;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.umb-packages-view-wrapper {
|
||||
padding: 20px 60px;
|
||||
}
|
||||
|
||||
.umb-packages-section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.umb-packages-search {
|
||||
width: 100%;
|
||||
background: @grayLighter;
|
||||
border-radius: 3px;
|
||||
padding: 30px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.umb-packages-search input {
|
||||
border-width: 2px;
|
||||
border-radius: 3px;
|
||||
min-height: 44px;
|
||||
|
||||
padding: 4px 10px;
|
||||
font-size: 16px;
|
||||
border-color: #ececec;
|
||||
margin-bottom: 0;
|
||||
border-color: @grayLight;
|
||||
|
||||
&:hover, &:focus {
|
||||
border-color: @grayLight;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-packages__pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.umb-packages {
|
||||
margin: 0 -10px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
// Cards
|
||||
.umb-package {
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.umb-package-link {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
border: 1px solid #ececec;
|
||||
border-radius: 3px;
|
||||
|
||||
text-decoration: none !important;
|
||||
|
||||
transition: border-color 100ms ease;
|
||||
|
||||
&:hover {
|
||||
border-color: @blue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Icon
|
||||
.umb-package-icon {
|
||||
display: flex;
|
||||
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
padding-top: 10px;
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.umb-package-icon img {
|
||||
max-width: 70px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
|
||||
// Info
|
||||
.umb-package-info {
|
||||
padding-right: 15px;
|
||||
padding-bottom: 15px;
|
||||
padding-left: 15px;
|
||||
padding-top: 15px;
|
||||
text-align: center;
|
||||
background: @grayLighter;
|
||||
border-top: 1px solid #ececec;
|
||||
}
|
||||
|
||||
|
||||
// Name
|
||||
.umb-package-name {
|
||||
font-size: 14px;
|
||||
max-width: 250px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
font-weight: bold;
|
||||
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
line-height: normal;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.umb-package-description {
|
||||
font-size: 11px;
|
||||
color: @grayMed;
|
||||
word-wrap: break-word;
|
||||
line-height: 1.1rem;
|
||||
}
|
||||
|
||||
// Numbers
|
||||
.umb-package-numbers {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
|
||||
opacity: .6;
|
||||
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.umb-package-numbers small {
|
||||
padding: 0 5px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.umb-package-numbers i {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.umb-package-link:hover .umb-package-numbers {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.umb-package-link:hover .umb-package-numbers .icon-hearts {
|
||||
color: red !important;
|
||||
}
|
||||
|
||||
// Version
|
||||
.umb-package-version {
|
||||
display: inline-flex;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
padding: 1px 5px;
|
||||
background: #ececec;
|
||||
border-radius: 3px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* umb-buttons-era */
|
||||
.umb-era-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
|
||||
height: 38px;
|
||||
line-height: 1;
|
||||
|
||||
max-width: 100%;
|
||||
padding: 0 18px;
|
||||
|
||||
color: #484848;
|
||||
background-color: #e0e0e0;
|
||||
|
||||
text-decoration: none !important;
|
||||
user-select: none;
|
||||
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
border-radius: 3px;
|
||||
border: 0 none;
|
||||
box-sizing: border-box;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
transition: background-color 80ms ease, color 80ms ease;
|
||||
}
|
||||
|
||||
|
||||
.umb-era-button:hover,
|
||||
.umb-era-button:active {
|
||||
color: #484848;
|
||||
background-color: #d3d3d3;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
.umb-era-button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.umb-era-button.-blue {
|
||||
background: @blue;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.umb-era-button.-blue:hover {
|
||||
background-color: @blueDark;
|
||||
}
|
||||
|
||||
.umb-era-button.-link {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.umb-era-button.-link:hover {
|
||||
background-color: transparent;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.umb-era-button.-inactive {
|
||||
cursor: not-allowed;
|
||||
color: #BBB;
|
||||
background: #EAE7E7;
|
||||
}
|
||||
|
||||
.umb-era-button.-inactive:hover {
|
||||
color: #BBB;
|
||||
background: #EAE7E7;
|
||||
}
|
||||
|
||||
|
||||
.umb-era-button.-full-width {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
/* CATEGORIES */
|
||||
|
||||
.umb-packages-categories {
|
||||
display: flex;
|
||||
user-select: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.umb-packages-category {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1 0 auto;
|
||||
justify-content: center;
|
||||
max-width: 25%;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: @black;
|
||||
box-sizing: border-box;
|
||||
justify-content: center;
|
||||
border-top: 1px solid @grayLight;
|
||||
border-bottom: 1px solid @grayLight;
|
||||
border-right: 1px solid @grayLight;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.umb-packages-category:hover,
|
||||
.umb-packages-category.-active {
|
||||
text-decoration: none;
|
||||
color: @blue;
|
||||
}
|
||||
|
||||
.umb-packages-category.-first {
|
||||
border-left: 1px solid @grayLight;
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
|
||||
.umb-packages-category.-last {
|
||||
border-right: 1px solid @grayLight;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
|
||||
/* PACKAGE DETAILS */
|
||||
|
||||
.umb-package-details {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.umb-package-details__back-link {
|
||||
font-weight: bold;
|
||||
color: @grayMed;
|
||||
}
|
||||
|
||||
.umb-package-details__back-link:hover {
|
||||
color: @black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.umb-package-details__main-content {
|
||||
flex: 1 1 auto;
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
.umb-package-details__sidebar {
|
||||
flex: 0 0 350px;
|
||||
}
|
||||
|
||||
.umb-package-details__section {
|
||||
background: @grayLighter;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.umb-package-details__section-title {
|
||||
font-size: 17px;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
margin-top: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.umb-package-details__section-description {
|
||||
font-size: 12px;
|
||||
line-height: 1.6em;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.umb-package-details__information-item {
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.umb-package-details__information-item-label {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.umb-package-details__information-item-label-2 {
|
||||
font-size: 12px;
|
||||
color: @grayMed;
|
||||
}
|
||||
|
||||
.umb-package-details__compatability {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.umb-package-details__compatability-label {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.umb-package-details__description {
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
.umb-package-details__description p {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Links */
|
||||
|
||||
.umb-package-details__link {
|
||||
color: #DA3287;
|
||||
}
|
||||
|
||||
.umb-package-details__link:hover {
|
||||
color: #B32D71;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Owner profile */
|
||||
|
||||
.umb-package-details__owner-profile {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.umb-package-details__owner-profile-avatar {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.umb-package-details__owner-profile-name {
|
||||
font-size: 15px;
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.umb-package-details__owner-profile-karma {
|
||||
font-size: 12px;
|
||||
color: @grayMed;
|
||||
}
|
||||
|
||||
/* gallery */
|
||||
|
||||
.umb-gallery__thumbnails {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.umb-gallery__thumbnail {
|
||||
flex: 1 1 100px;
|
||||
border: 1px solid @grayLight;
|
||||
border-radius: 3px;
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.umb-gallery__thumbnail:hover {
|
||||
cursor: pointer;
|
||||
border-color: @blue;
|
||||
}
|
||||
|
||||
/* Avatar */
|
||||
|
||||
.umb-avatar {
|
||||
border-radius: 50%;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
/* Progress bar */
|
||||
|
||||
.umb-progress-bar {
|
||||
background: @grayLight;
|
||||
width: 100%;
|
||||
display: block;
|
||||
height: 10px;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.umb-progress-bar__progress {
|
||||
background: #50C878;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/* PACKAGE LIST */
|
||||
|
||||
.umb-package-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.umb-package-list__item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background: @grayLighter;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 3px;
|
||||
padding: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.umb-package-list__item-icon {
|
||||
flex: 0 0 50px;
|
||||
margin-right: 20px;
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.umb-package-list__item-content {
|
||||
flex: 1 1 auto;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.umb-package-list__item-name {
|
||||
font-size: 16px;
|
||||
margin-bottom: 5px;
|
||||
color: @black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.umb-package-list__item-description {
|
||||
font-size: 14px;
|
||||
color: @grayMed;
|
||||
}
|
||||
|
||||
.umb-package-list__item-actions {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
@@ -366,17 +366,17 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.umb-panel-header-content.-top-position {
|
||||
position: relative;
|
||||
top: -12px;
|
||||
}
|
||||
|
||||
.umb-panel-header-left-side {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.umb-panel-header-left-side.-top-position {
|
||||
position: relative;
|
||||
top: -12px;
|
||||
}
|
||||
|
||||
.umb-panel-header-icon {
|
||||
cursor: pointer;
|
||||
margin-right: 5px;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
<div class="umb-panel-header-content-wrapper">
|
||||
|
||||
<div class="umb-panel-header-content" ng-class="{'-top-position': tabs || !icon }">
|
||||
<div class="umb-panel-header-content">
|
||||
|
||||
<div class="umb-panel-header-left-side">
|
||||
<div class="umb-panel-header-left-side" ng-class="{'-top-position': tabs || !icon }">
|
||||
|
||||
<div class="umb-panel-header-icon" ng-if="!hideIcon" ng-click="openIconPicker()" ng-class="{'-placeholder': $parent.icon==='' || $parent.icon===null}">
|
||||
<i class="icon {{$parent.icon}}" ng-if="$parent.icon!=='' && $parent.icon!==null"></i>
|
||||
|
||||
@@ -31,7 +31,7 @@ function FormsController($scope, $route, $cookieStore, packageResource) {
|
||||
return packageResource.installFiles(pack);
|
||||
}, $scope.error)
|
||||
.then(function(pack){
|
||||
$scope.state = "Restarting, please hold...";
|
||||
$scope.state = "Restarting, please wait...";
|
||||
return packageResource.installData(pack);
|
||||
}, $scope.error)
|
||||
.then(function(pack){
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackagesCategoryController($scope, $routeParams) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.page = {};
|
||||
vm.page.name = "Category";
|
||||
|
||||
vm.selectCategory = selectCategory;
|
||||
|
||||
vm.categories = [
|
||||
{
|
||||
"icon": "icon-male-and-female",
|
||||
"name": "All",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"icon": "icon-male-and-female",
|
||||
"name": "Collaboration",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"icon": "icon-molecular-network",
|
||||
"name": "Backoffice extensions"
|
||||
},
|
||||
{
|
||||
"icon": "icon-brackets",
|
||||
"name": "Developer tools"
|
||||
},
|
||||
{
|
||||
"icon": "icon-wand",
|
||||
"name": "Starter kits"
|
||||
},
|
||||
{
|
||||
"icon": "icon-medal",
|
||||
"name": "Umbraco Pro"
|
||||
},
|
||||
{
|
||||
"icon": "icon-wrench",
|
||||
"name": "Website utilities"
|
||||
}
|
||||
];
|
||||
|
||||
vm.packages = [
|
||||
{
|
||||
"name": "uSightly",
|
||||
"description": "An HTML5 audio player based on jPlayer",
|
||||
"karma": "1",
|
||||
"downloads": "1672",
|
||||
"icon":"https://our.umbraco.org/media/wiki/150283/635768313097111400_usightlylogopng.png?bgcolor=fff&height=154&width=281&format=png"
|
||||
},
|
||||
{
|
||||
"name": "Kill IE6",
|
||||
"description": "A simple port of the IE6 warning script (http://code.google.com/p/ie6-upgrade-warning/) to use in your Umbraco websites.",
|
||||
"karma": "11",
|
||||
"downloads": "688",
|
||||
"icon":"https://our.umbraco.org/media/wiki/9138/634697622367666000_offroadcode-100x100.png?bgcolor=fff&height=154&width=281&format=png"
|
||||
},
|
||||
{
|
||||
"name": "Examine Media Indexer",
|
||||
"description": "CogUmbracoExamineMediaIndexer",
|
||||
"karma": "3",
|
||||
"downloads": "1329",
|
||||
"icon":"https://our.umbraco.org/media/wiki/50703/634782902373558000_cogworks.jpg?bgcolor=fff&height=154&width=281&format=png"
|
||||
},
|
||||
{
|
||||
"name": "SVG Icon Picker",
|
||||
"description": "A picker, for picking icons from an SVG spritesheet.",
|
||||
"karma": "5",
|
||||
"downloads": "8",
|
||||
"icon":"https://our.umbraco.org/media/wiki/154472/635997115126742822_logopng.png?bgcolor=fff&height=154&width=281&format=png"
|
||||
},
|
||||
{
|
||||
"name": "Pipeline CRM",
|
||||
"description": "Pipeline is a social CRM that lives in Umbraco back-office. It tracks opportunities and helps teams collaborate with timelines and tasks. It stores information about your customers and your interactions with them. It integrates with your website, capturing opportunities from forms and powering personal portals.",
|
||||
"karma": "3",
|
||||
"downloads": "105",
|
||||
"icon":"https://our.umbraco.org/media/wiki/152476/635917291068518788_pipeline-crm-logopng.png?bgcolor=fff&height=154&width=281&format=png"
|
||||
},
|
||||
{
|
||||
"name": "CodeMirror",
|
||||
"description": "CodeMirror Editor for Umbraco",
|
||||
"karma": "1",
|
||||
"downloads": "70",
|
||||
"icon":"https://our.umbraco.org/media/wiki/151028/635810233171153461_logopng.png?bgcolor=fff&height=154&width=281&format=png"
|
||||
}
|
||||
];
|
||||
|
||||
function selectCategory(category) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Packages.CategoryController", PackagesCategoryController);
|
||||
|
||||
})();
|
||||
109
src/Umbraco.Web.UI.Client/src/views/packager/category.html
Normal file
109
src/Umbraco.Web.UI.Client/src/views/packager/category.html
Normal file
@@ -0,0 +1,109 @@
|
||||
<div ng-controller="Umbraco.Editors.Packages.CategoryController as vm" class="clearfix">
|
||||
|
||||
<umb-load-indicator ng-if="page.loading"></umb-load-indicator>
|
||||
|
||||
<form name="packagesForm" ng-submit="save()" novalidate>
|
||||
|
||||
<umb-editor-view footer="false" ng-if="!page.loading">
|
||||
|
||||
<umb-editor-header
|
||||
name="vm.page.name"
|
||||
name-locked="true"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
hide-alias="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
|
||||
<umb-editor-sub-header>
|
||||
<umb-editor-sub-header-content-left>
|
||||
|
||||
<umb-editor-sub-header-section>
|
||||
<div class="umb-packages-categories -collapsed">
|
||||
<a href="" class="umb-packages-category" ng-class="{'-active': category.active === true}" ng-click="vm.selectCategory(category)" ng-repeat="category in vm.categories">
|
||||
<i class="umb-packages-category-icon" ng-class="category.icon"></i>
|
||||
<div>{{ category.name }}</div>
|
||||
</a>
|
||||
</div>
|
||||
</umb-editor-sub-header-section>
|
||||
|
||||
</umb-editor-sub-header-content-left>
|
||||
</umb-editor-sub-header>
|
||||
|
||||
|
||||
<h4><strong>Popular</strong></h4>
|
||||
<div class="umb-packages clearfix">
|
||||
|
||||
<div class="umb-package" ng-repeat="package in vm.packages">
|
||||
<a class="umb-package-link" href="#">
|
||||
|
||||
<div class="umb-package-icon">
|
||||
<img ng-src="{{package.icon}}" alt="" />
|
||||
</div>
|
||||
|
||||
<div class="umb-package-info">
|
||||
<div class="umb-package-name">{{ package.name }}</div>
|
||||
|
||||
<div class="umb-package-numbers">
|
||||
<small class="umb-package-downloads">
|
||||
<i class="icon-download-alt"></i> <strong>{{ package.downloads }}</strong>
|
||||
</small>
|
||||
<small class="umb-package-karma">
|
||||
<i class="icon-hearts"></i> <strong>{{ package.ownerInfo.karma }}</strong>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
</div> <!-- end package -->
|
||||
|
||||
</div> <!-- end packages -->
|
||||
|
||||
|
||||
<h4><strong>Latest</strong></h4>
|
||||
<div class="umb-packages clearfix">
|
||||
|
||||
<div class="umb-package" ng-repeat="package in vm.packages">
|
||||
<a class="umb-package-link" href="#">
|
||||
|
||||
<div class="umb-package-icon">
|
||||
<img src="{{ package.icon }}" alt="" />
|
||||
</div>
|
||||
|
||||
<div class="umb-package-info">
|
||||
<h4 class="umb-package-name">
|
||||
{{ package.name }}
|
||||
</h4>
|
||||
|
||||
<div class="umb-package-numbers">
|
||||
<small class="umb-package-downloads">
|
||||
<i class="icon-download-alt"></i> <strong>{{ package.downloads }}</strong>
|
||||
</small>
|
||||
<small class="umb-package-karma">
|
||||
<i class="icon-hearts"></i> <strong>{{ package.ownerInfo.karma }}</strong>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
</div> <!-- end package -->
|
||||
|
||||
</div> <!-- end packages -->
|
||||
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
|
||||
<umb-editor-footer-content-left>
|
||||
Breadcrumbs here
|
||||
</umb-editor-footer-content-left>
|
||||
|
||||
</umb-editor-footer>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,100 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackageDetailsController($scope, $routeParams) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.page = {};
|
||||
|
||||
vm.package = {
|
||||
"name": "Merchello",
|
||||
"description": "<p>Merchello is a high performance, designer friendly, open source Umbraco ecommerce package built for the store owner.</p> <p><strong>What Merchello does for you</strong></p> <p>In version 1, Merchello supports a large variety of products with options that can be attached to a single warehouse, processes orders, manages taxes and shipping, and sends out email notifications to your customers. The beauty of Merchello is that while it oversees all of your products, orders, and store settings, it allows Umbraco to maintain your content. This seamless integration gives you the flexibility to build your store in any way imagineable on a robust platform capable of handling a wide variety of store sizes.</p> <p><strong>Find out more on our website</strong></p> <p><strong><a href="https://merchello.com">https://merchello.com</a></strong></p> <p><strong>Contribute</strong></p> <p>We would love and need your help. If you want to contribute to Merchello's core, the easiest way to get started is to fork the project on https://github.com/merchello/Merchello and open src/Merchello.sln in Visual Studio. We're excited to see what you do!</p> <p><strong>Starter Kit</strong></p> <p>We have built a simple starter kit for Merchello called Bazaar, and you can download it below in the package files tab.</p>",
|
||||
"compatibility": [
|
||||
{
|
||||
"version": "7.4.x",
|
||||
"percentage": "100"
|
||||
},
|
||||
{
|
||||
"version": "7.3.x",
|
||||
"percentage": "86"
|
||||
},
|
||||
{
|
||||
"version": "7.2.x",
|
||||
"percentage": "93"
|
||||
},
|
||||
{
|
||||
"version": "7.1.x",
|
||||
"percentage": "100"
|
||||
}
|
||||
],
|
||||
"information": {
|
||||
"owner": "Rusty Swayne",
|
||||
"ownerAvatar": "https://our.umbraco.org/media/upload/d476d257-a494-46d9-9a00-56c2f94a55c8/our-profile.jpg?width=200&height=200&mode=crop",
|
||||
"ownerKarma": "2673",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Lee"
|
||||
},
|
||||
{
|
||||
"name": "Jason Prothero"
|
||||
}
|
||||
],
|
||||
"created": "18/12/2013",
|
||||
"currentVersion": "2.0.0",
|
||||
"netVersion": "4.5",
|
||||
"license": "MIT",
|
||||
"downloads": "4198",
|
||||
"karma": "53"
|
||||
},
|
||||
"externalSources": [
|
||||
{
|
||||
"name": "Source code",
|
||||
"url": "https://github.com/merchello/Merchello"
|
||||
},
|
||||
{
|
||||
"name": "Issue tracker",
|
||||
"url": "http://issues.merchello.com/youtrack/oauth?state=%2Fyoutrack%2FrootGo"
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"thumbnail": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"source": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png"
|
||||
},
|
||||
{
|
||||
"thumbnail": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"source": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png"
|
||||
},
|
||||
{
|
||||
"thumbnail": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"source": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png"
|
||||
},
|
||||
{
|
||||
"thumbnail": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"source": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png"
|
||||
},
|
||||
{
|
||||
"thumbnail": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"source": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png"
|
||||
},
|
||||
{
|
||||
"thumbnail": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"source": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png"
|
||||
},
|
||||
{
|
||||
"thumbnail": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"source": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png"
|
||||
},
|
||||
{
|
||||
"thumbnail": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"source": "https://our.umbraco.org/media/wiki/104946/635591947547374885_Product-Listpng.png"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Packages.DetailsController", PackageDetailsController);
|
||||
|
||||
})();
|
||||
141
src/Umbraco.Web.UI.Client/src/views/packager/details.html
Normal file
141
src/Umbraco.Web.UI.Client/src/views/packager/details.html
Normal file
@@ -0,0 +1,141 @@
|
||||
<div ng-controller="Umbraco.Editors.Packages.DetailsController as vm">
|
||||
|
||||
<umb-load-indicator ng-if="page.loading"></umb-load-indicator>
|
||||
|
||||
<form name="packagesForm" ng-submit="save()" novalidate>
|
||||
|
||||
<umb-editor-view ng-if="!page.loading">
|
||||
|
||||
<umb-editor-header
|
||||
name="vm.package.name"
|
||||
name-locked="true"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
hide-alias="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
<div class="umb-package-details">
|
||||
|
||||
<div class="umb-package-details__main-content">
|
||||
|
||||
<div class="umb-package-details__description" ng-bind-html-unsafe="vm.package.description"></div>
|
||||
|
||||
<div class="umb-gallery">
|
||||
<div class="umb-gallery__thumbnails">
|
||||
<a class="umb-gallery__thumbnail" target="_blank" href="{{ image.source }}" ng-repeat="image in vm.package.images">
|
||||
<img ng-src="{{ image.thumbnail }}" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__sidebar">
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<button class="umb-era-button -blue -full-width">Install package</button>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<div class="umb-package-details__owner-profile">
|
||||
<div class="umb-package-details__owner-profile-avatar">
|
||||
<img class="umb-avatar" ng-src="{{vm.package.information.ownerAvatar}}" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="umb-package-details__owner-profile-name">{{ vm.package.information.owner }}</div>
|
||||
<div class="umb-package-details__owner-profile-karma">
|
||||
{{ vm.package.information.owner }} has <strong>{{ vm.package.information.ownerKarma }}</strong> karma points
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<div class="umb-package-details__section-title">Information</div>
|
||||
<div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Owner:</div>
|
||||
<div>{{vm.package.information.owner}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Contributors:</div>
|
||||
<div ng-repeat="contributor in vm.package.information.contributors">
|
||||
<a class="umb-package-details__link" href="{{ contributor.profileUrl }}" target="_blank">{{ contributor.name }}<span ng-if="!$last">, </span></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Created:</div>
|
||||
<div>{{vm.package.information.created}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Current version:</div>
|
||||
<div>{{vm.package.information.created}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">.Net Version:</div>
|
||||
<div>{{vm.package.information.netVersion}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">License:</div>
|
||||
<div>{{vm.package.information.license}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Downloads:</div>
|
||||
<div>{{vm.package.information.downloads}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Karma:</div>
|
||||
<div>{{vm.package.information.karma}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<div class="umb-package-details__section-title">Compatibility</div>
|
||||
<div class="umb-package-details__section-description">This project is compatible with the following versions as reported by community members who have downloaded this package:</div>
|
||||
<div class="umb-package-details__compatability" ng-repeat="compatibility in vm.package.compatibility | filter:percentage > 0">
|
||||
<div class="umb-package-details__compatability-label">
|
||||
<span class="umb-package-details__information-item-label">{{compatibility.version}}</span>
|
||||
<span class="umb-package-details__information-item-label-2">({{compatibility.percentage}}%)</span>
|
||||
</div>
|
||||
<div class="umb-progress-bar">
|
||||
<span class="umb-progress-bar__progress" style="width: {{compatibility.percentage}}%"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<div class="umb-package-details__section-title">External sources</div>
|
||||
<div>
|
||||
<div class="umb-package-details__information-item" ng-repeat="externalSource in vm.package.externalSources">
|
||||
<a class="umb-package-details__link" target="_blank" href="{{ externalSource.url }}">
|
||||
<i class="icon-out"></i>
|
||||
{{ externalSource.name }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</umb-editor-container>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,50 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackagesOverviewController($scope, $route, $location, navigationService, $timeout, $cookieStore) {
|
||||
|
||||
//Hack!
|
||||
// if there is a cookie value for packageInstallUri then we need to redirect there,
|
||||
// the issue is that we still have webforms and we cannot go to a hash location and then window.reload
|
||||
// because it will double load it.
|
||||
// we will refresh and then navigate there.
|
||||
|
||||
var installPackageUri = window.localStorage.getItem("packageInstallUri");
|
||||
if (installPackageUri) {
|
||||
window.localStorage.removeItem("packageInstallUri");
|
||||
$location.path(installPackageUri).search("");
|
||||
}
|
||||
else {
|
||||
var vm = this;
|
||||
|
||||
vm.page = {};
|
||||
vm.page.name = "Packages";
|
||||
vm.page.navigation = [
|
||||
{
|
||||
"name": "Packages",
|
||||
"icon": "icon-cloud",
|
||||
"view": "views/packager/views/repo.html",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"name": "Installed",
|
||||
"icon": "icon-box",
|
||||
"view": "views/packager/views/installed.html"
|
||||
},
|
||||
{
|
||||
"name": "Install local",
|
||||
"icon": "icon-add",
|
||||
"view": "views/packager/views/install-local.html"
|
||||
}
|
||||
];
|
||||
|
||||
$timeout(function () {
|
||||
navigationService.syncTree({ tree: "packager", path: "-1" });
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Packages.OverviewController", PackagesOverviewController);
|
||||
|
||||
})();
|
||||
28
src/Umbraco.Web.UI.Client/src/views/packager/overview.html
Normal file
28
src/Umbraco.Web.UI.Client/src/views/packager/overview.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<div ng-controller="Umbraco.Editors.Packages.OverviewController as vm" class="clearfix">
|
||||
|
||||
<form name="packagesForm" ng-submit="save()" novalidate val-form-manager>
|
||||
|
||||
<umb-editor-view footer="false">
|
||||
|
||||
<umb-editor-header
|
||||
name="vm.page.name"
|
||||
name-locked="true"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
navigation="vm.page.navigation"
|
||||
hide-alias="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
<umb-editor-sub-views
|
||||
sub-views="vm.page.navigation">
|
||||
</umb-editor-sub-views>
|
||||
|
||||
</umb-editor-container>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,146 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackagesInstallLocalController($scope, $route, $location, Upload, umbRequestHelper, packageResource, $cookieStore, $timeout) {
|
||||
|
||||
var vm = this;
|
||||
vm.state = "upload";
|
||||
|
||||
vm.localPackage = {};
|
||||
vm.installPackage = installPackage;
|
||||
vm.installState = {
|
||||
status: ""
|
||||
};
|
||||
vm.zipFile = {
|
||||
uploadStatus: "idle",
|
||||
uploadProgress: 0,
|
||||
serverErrorMessage: null
|
||||
};
|
||||
|
||||
$scope.handleFiles = function (files, event) {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
upload(files[i]);
|
||||
}
|
||||
};
|
||||
|
||||
function upload(file) {
|
||||
|
||||
Upload.upload({
|
||||
url: umbRequestHelper.getApiUrl("packageInstallApiBaseUrl", "UploadLocalPackage"),
|
||||
fields: {},
|
||||
file: file
|
||||
}).progress(function (evt) {
|
||||
|
||||
// calculate progress in percentage
|
||||
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total, 10);
|
||||
|
||||
// set percentage property on file
|
||||
vm.zipFile.uploadProgress = progressPercentage;
|
||||
|
||||
// set uploading status on file
|
||||
vm.zipFile.uploadStatus = "uploading";
|
||||
|
||||
}).success(function (data, status, headers, config) {
|
||||
|
||||
if (data.notifications && data.notifications.length > 0) {
|
||||
|
||||
// set error status on file
|
||||
vm.zipFile.uploadStatus = "error";
|
||||
|
||||
// Throw message back to user with the cause of the error
|
||||
vm.zipFile.serverErrorMessage = data.notifications[0].message;
|
||||
|
||||
//TODO: Handle the error in UI
|
||||
|
||||
} else {
|
||||
|
||||
// set done status on file
|
||||
vm.zipFile.uploadStatus = "done";
|
||||
loadPackage();
|
||||
vm.localPackage = data;
|
||||
}
|
||||
|
||||
}).error(function (evt, status, headers, config) {
|
||||
|
||||
//TODO: Handle the error in UI
|
||||
|
||||
// set status done
|
||||
vm.zipFile.uploadStatus = "error";
|
||||
|
||||
//if the service returns a detailed error
|
||||
if (evt.InnerException) {
|
||||
vm.zipFile.serverErrorMessage = evt.InnerException.ExceptionMessage;
|
||||
|
||||
//Check if its the common "too large file" exception
|
||||
if (evt.InnerException.StackTrace && evt.InnerException.StackTrace.indexOf("ValidateRequestEntityLength") > 0) {
|
||||
vm.zipFile.serverErrorMessage = "File too large to upload";
|
||||
}
|
||||
|
||||
} else if (evt.Message) {
|
||||
file.serverErrorMessage = evt.Message;
|
||||
}
|
||||
|
||||
// If file not found, server will return a 404 and display this message
|
||||
if (status === 404) {
|
||||
vm.zipFile.serverErrorMessage = "File not found";
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function loadPackage() {
|
||||
if (vm.zipFile.uploadStatus === "done") {
|
||||
vm.state = "packageDetails";
|
||||
}
|
||||
}
|
||||
|
||||
function installPackage() {
|
||||
vm.installState.status = "Installing";
|
||||
|
||||
//TODO: If any of these fail, will they keep calling the next one?
|
||||
packageResource
|
||||
.installFiles(vm.localPackage)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "Importing...";
|
||||
return packageResource.import(pack);
|
||||
},
|
||||
installError)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "Installing...";
|
||||
return packageResource.installFiles(pack);
|
||||
},
|
||||
installError)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "Restarting, please wait...";
|
||||
return packageResource.installData(pack);
|
||||
},
|
||||
installError)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "All done, your browser will now refresh";
|
||||
return packageResource.cleanUp(pack);
|
||||
},
|
||||
installError)
|
||||
.then(function(result) {
|
||||
|
||||
if (result.postInstallationPath) {
|
||||
//Put the redirect Uri in a cookie so we can use after reloading
|
||||
window.localStorage.setItem("packageInstallUri", result.postInstallationPath);
|
||||
}
|
||||
//reload on next digest (after cookie)
|
||||
$timeout(function() {
|
||||
window.location.reload(true);
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
installError);
|
||||
}
|
||||
|
||||
function installError() {
|
||||
//TODO: Need to do something about this?
|
||||
}
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Packages.InstallLocalController", PackagesInstallLocalController);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,112 @@
|
||||
<div class="umb-packages-view-wrapper" ng-controller="Umbraco.Editors.Packages.InstallLocalController as vm">
|
||||
|
||||
<!-- Upload -->
|
||||
<div class="umb-upload-local" ng-if="vm.state === 'upload'">
|
||||
<form novalidate name="localPackageForm">
|
||||
|
||||
<!-- Drag and drop files area -->
|
||||
<div ngf-drop
|
||||
ng-hide="hideDropzone"
|
||||
ng-model="filesHolder"
|
||||
ngf-change="handleFiles($files, $event)"
|
||||
class="umb-upload-local__dropzone"
|
||||
ngf-drag-over-class="drag-over"
|
||||
ngf-multiple="false"
|
||||
ngf-allow-dir="false"
|
||||
ngf-pattern="*.zip"
|
||||
ngf-max-size="{{ maxFileSize }}"
|
||||
ng-class="{'is-small': compact!=='false' || (done.length+queue.length) > 0 }">
|
||||
|
||||
|
||||
<div class="content">
|
||||
|
||||
<!-- Drag and drop illustration -->
|
||||
<i class="icon-box" draggable="false"></i>
|
||||
<small class="faded" draggable="false"><strong>Drop to upload</strong></small>
|
||||
|
||||
<!-- Select files -->
|
||||
<div class="umb-upload-local__select-file"
|
||||
ngf-select
|
||||
ng-model="filesHolder"
|
||||
ngf-change="handleFiles($files, $event)"
|
||||
ngf-multiple="true"
|
||||
ngf-pattern="*.zip"
|
||||
ngf-max-size="{{ maxFileSize }}">
|
||||
- <localize key="media_orClickHereToUpload">or click here to choose files</localize>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h3><strong>Upload package</strong></h3>
|
||||
<p class="faded">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
|
||||
</p>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Package details -->
|
||||
<div class="umb-info-local" ng-if="vm.state === 'packageDetails'">
|
||||
<div class="umb-info-local-items">
|
||||
|
||||
<form novalidate name="localPackageForm">
|
||||
<div class="umb-package-icon">
|
||||
<i ng-if="!vm.localPackage.icon" class="icon-box"></i>
|
||||
<img ng-if="vm.localPackage.icon" ng-src="{{vm.localPackage.icon}}" alt="" />
|
||||
</div>
|
||||
|
||||
|
||||
<div class="umb-package-info">
|
||||
<h4 class="umb-info-local-item"><strong>{{ vm.localPackage.name }}</strong></h4>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Author</strong>
|
||||
<a href="{{ vm.localPackage.authorLink }}" target="_blank">{{ vm.localPackage.author }}</a>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Version</strong>
|
||||
{{ vm.localPackage.version }}
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>License</strong>
|
||||
<a href="{{ vm.localPackage.licenseUrl }}">{{ vm.localPackage.license }}</a>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Read me</strong>
|
||||
<br>
|
||||
<small ng-bind-html-unsafe="vm.localPackage.readMe"></small>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item mt-3" ng-if="vm.installState.status == '' && vm.localPackage.isCompatible">
|
||||
<button type="button"
|
||||
ng-class="{'-inactive' : localPackageForm.$invalid}"
|
||||
ng-disabled="localPackageForm.$invalid"
|
||||
class="umb-era-button -blue inline-flex"
|
||||
ng-click="vm.installPackage()">
|
||||
Install package
|
||||
</button>
|
||||
<label for="license-accept" class="umb-package-installer-label">
|
||||
<input type="checkbox" id="license-accept" ng-model="vm.localPackage.packageLicenseAccept" required no-dirty-check>
|
||||
<strong class="label-text">I accept <a href="{{ vm.localPackage.licenseUrl }}">terms of use</a></strong>
|
||||
</label>
|
||||
</div>
|
||||
<div class="umb-info-local-item text-error" ng-if="!vm.localPackage.isCompatible">
|
||||
This package cannot be installed, it requires a minimum Umbraco version of {{vm.localPackage.umbracoVersion}}
|
||||
</div>
|
||||
<div class="umb-info-local-item text-info">
|
||||
<p>{{vm.installState.status}}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,52 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackagesInstalledController($scope, $route, $location, packageResource) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.confirmUninstall = confirmUninstall;
|
||||
vm.uninstallPackage = uninstallPackage;
|
||||
vm.state = "list";
|
||||
vm.installState = {
|
||||
status: ""
|
||||
};
|
||||
vm.package = {};
|
||||
|
||||
function init() {
|
||||
packageResource.getInstalled()
|
||||
.then(function (packs) {
|
||||
vm.installedPackages = packs;
|
||||
});
|
||||
vm.installState.status = "";
|
||||
vm.state = "list";
|
||||
}
|
||||
|
||||
function confirmUninstall(pck) {
|
||||
vm.state = "packageDetails";
|
||||
vm.package = pck;
|
||||
}
|
||||
|
||||
function uninstallPackage(installedPackage) {
|
||||
vm.installState.status = "Uninstalling package...";
|
||||
packageResource.uninstall(installedPackage.id)
|
||||
.then(function () {
|
||||
if (installedPackage.files.length > 0) {
|
||||
vm.installState.status = "All done, your browser will now refresh";
|
||||
|
||||
var url = window.location.href + "?uninstalled=" + vm.package.packageGuid;
|
||||
window.location.reload(true);
|
||||
}
|
||||
else {
|
||||
init();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Packages.InstalledController", PackagesInstalledController);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,102 @@
|
||||
<div ng-controller="Umbraco.Editors.Packages.InstalledController as vm">
|
||||
|
||||
<!-- Package list-->
|
||||
<div class="umb-packages-view-wrapper" ng-if="vm.state == 'list'">
|
||||
|
||||
<div class="umb-packages-view-title">Installed packages</div>
|
||||
|
||||
<div class="umb-package-list">
|
||||
|
||||
<div class="umb-package-list__item" ng-repeat="installedPackage in vm.installedPackages">
|
||||
|
||||
<div class="umb-package-list__item-icon">
|
||||
<i ng-if="!installedPackage.icon" class="icon-box"></i>
|
||||
<img ng-if="installedPackage.icon" ng-src="{{installedPackage.icon}}" />
|
||||
</div>
|
||||
|
||||
<div class="umb-package-list__item-content">
|
||||
<div class="umb-package-list__item-name">{{ installedPackage.name }}</div>
|
||||
<div class="umb-package-list__item-description">
|
||||
{{ installedPackage.version }} | <a href="{{ installedPackage.url }}">{{ installedPackage.url }}</a>| {{ installedPackage.author }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-list__item-actions">
|
||||
<button type="button" class="umb-era-button" ng-click="vm.confirmUninstall(installedPackage)">Uninstall</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Package details -->
|
||||
<div ng-if="vm.state === 'packageDetails'">
|
||||
|
||||
<umb-editor-sub-header>
|
||||
<umb-editor-sub-header-content-left>
|
||||
<a class="umb-package-details__back-link" href="" ng-click="vm.state = 'list'">← Take me back</a>
|
||||
</umb-editor-sub-header-content-left>
|
||||
</umb-editor-sub-header>
|
||||
|
||||
<div class="umb-info-local">
|
||||
|
||||
<div class="umb-info-local-items">
|
||||
|
||||
<form novalidate name="uninstallForm">
|
||||
<div class="umb-package-icon">
|
||||
<i ng-if="!vm.package.icon" class="icon-box"></i>
|
||||
<img ng-if="vm.package.icon" ng-src="{{vm.package.icon}}" alt="" />
|
||||
</div>
|
||||
|
||||
|
||||
<div class="umb-package-info">
|
||||
<h4 class="umb-info-local-item"><strong>{{ vm.package.name }}</strong></h4>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Author</strong>
|
||||
<a href="{{ vm.package.authorLink }}" target="_blank">{{ vm.package.author }}</a>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Version</strong>
|
||||
{{ vm.package.version }}
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>License</strong>
|
||||
<a href="{{ vm.package.licenseUrl }}">{{ vm.package.license }}</a>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Read me</strong>
|
||||
<br>
|
||||
<small> {{ vm.package.readme }} </small>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item mt-3" ng-if="vm.installState.status == ''">
|
||||
<button type="button"
|
||||
ng-class="{'-inactive' : uninstallForm.$invalid}"
|
||||
ng-disabled="uninstallForm.$invalid"
|
||||
class="umb-era-button -blue inline-flex"
|
||||
ng-click="vm.uninstallPackage(vm.package)">
|
||||
Uninstall package
|
||||
</button>
|
||||
<label for="confirm-uninstall" class="umb-package-installer-label">
|
||||
<input type="checkbox" id="confirm-uninstall" ng-model="vm.package.confirmUninstall" required no-dirty-check>
|
||||
<strong class="label-text">Confirm package uninstall</strong>
|
||||
</label>
|
||||
</div>
|
||||
<div class="umb-info-local-item text-info">
|
||||
<p>{{vm.installState.status}}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,240 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackagesRepoController($scope, $route, $location, $timeout, ourPackageRepositoryResource, $q, packageResource, $cookieStore) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.packageViewState = "packageList";
|
||||
vm.categories = [];
|
||||
vm.loading = true;
|
||||
vm.pagination = {
|
||||
pageNumber: 1,
|
||||
totalPages: 10,
|
||||
pageSize: 8
|
||||
};
|
||||
vm.searchQuery = "";
|
||||
vm.installState = {
|
||||
status: ""
|
||||
};
|
||||
vm.selectCategory = selectCategory;
|
||||
vm.showPackageDetails = showPackageDetails;
|
||||
vm.setPackageViewState = setPackageViewState;
|
||||
vm.nextPage = nextPage;
|
||||
vm.prevPage = prevPage;
|
||||
vm.goToPage = goToPage;
|
||||
vm.installPackage = installPackage;
|
||||
vm.downloadPackage = downloadPackage;
|
||||
|
||||
//used to cancel any request in progress if another one needs to take it's place
|
||||
var canceler = null;
|
||||
|
||||
function getActiveCategory() {
|
||||
if (vm.searchQuery !== "") {
|
||||
return "";
|
||||
}
|
||||
for (var i = 0; i < vm.categories.length; i++) {
|
||||
if (vm.categories[i].active === true) {
|
||||
return vm.categories[i].name;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
vm.loading = true;
|
||||
|
||||
$q.all([
|
||||
ourPackageRepositoryResource.getCategories()
|
||||
.then(function(cats) {
|
||||
vm.categories = cats;
|
||||
}),
|
||||
ourPackageRepositoryResource.getPopular(8)
|
||||
.then(function(pack) {
|
||||
vm.popular = pack.packages;
|
||||
}),
|
||||
ourPackageRepositoryResource.search(vm.pagination.pageNumber - 1, vm.pagination.pageSize)
|
||||
.then(function(pack) {
|
||||
vm.packages = pack.packages;
|
||||
vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize);
|
||||
})
|
||||
])
|
||||
.then(function() {
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
$scope.$watch(function() {
|
||||
return vm.searchQuery;
|
||||
}, _.debounce(function (newVal, oldVal) {
|
||||
$scope.$apply(function () {
|
||||
if (vm.searchQuery) {
|
||||
if (newVal !== null && newVal !== undefined && newVal !== oldVal) {
|
||||
vm.loading = true;
|
||||
|
||||
//a canceler exists, so perform the cancelation operation and reset
|
||||
if (canceler) {
|
||||
canceler.resolve();
|
||||
canceler = $q.defer();
|
||||
}
|
||||
else {
|
||||
canceler = $q.defer();
|
||||
}
|
||||
|
||||
ourPackageRepositoryResource.search(vm.pagination.pageNumber - 1,
|
||||
vm.pagination.pageSize,
|
||||
"",
|
||||
vm.searchQuery,
|
||||
canceler)
|
||||
.then(function(pack) {
|
||||
vm.packages = pack.packages;
|
||||
vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize);
|
||||
vm.pagination.pageNumber = 1;
|
||||
vm.loading = false;
|
||||
//set back to null so it can be re-created
|
||||
canceler = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 200));
|
||||
|
||||
}
|
||||
|
||||
function selectCategory(selectedCategory, categories) {
|
||||
var reset = false;
|
||||
for (var i = 0; i < categories.length; i++) {
|
||||
var category = categories[i];
|
||||
if (category.name === selectedCategory.name && category.active === true) {
|
||||
//it's already selected, let's unselect to show all again
|
||||
reset = true;
|
||||
}
|
||||
category.active = false;
|
||||
}
|
||||
|
||||
vm.loading = true;
|
||||
vm.searchQuery = "";
|
||||
var searchCategory = selectedCategory.name;
|
||||
if (reset === true) {
|
||||
searchCategory = "";
|
||||
}
|
||||
|
||||
$q.all([
|
||||
ourPackageRepositoryResource.getPopular(8, searchCategory)
|
||||
.then(function(pack) {
|
||||
vm.popular = pack.packages;
|
||||
}),
|
||||
ourPackageRepositoryResource.search(vm.pagination.pageNumber - 1, vm.pagination.pageSize, searchCategory, vm.searchQuery)
|
||||
.then(function(pack) {
|
||||
vm.packages = pack.packages;
|
||||
vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize);
|
||||
vm.pagination.pageNumber = 1;
|
||||
})
|
||||
])
|
||||
.then(function() {
|
||||
vm.loading = false;
|
||||
selectedCategory.active = reset === false;
|
||||
});
|
||||
}
|
||||
|
||||
function showPackageDetails(selectedPackage) {
|
||||
ourPackageRepositoryResource.getDetails(selectedPackage.id)
|
||||
.then(function(pack) {
|
||||
vm.package = pack;
|
||||
vm.packageViewState = "packageDetails";
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function setPackageViewState(state) {
|
||||
if(state) {
|
||||
vm.packageViewState = state;
|
||||
}
|
||||
}
|
||||
|
||||
function nextPage(pageNumber) {
|
||||
ourPackageRepositoryResource.search(pageNumber - 1, vm.pagination.pageSize, getActiveCategory(), vm.searchQuery)
|
||||
.then(function (pack) {
|
||||
vm.packages = pack.packages;
|
||||
vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize);
|
||||
});
|
||||
}
|
||||
|
||||
function prevPage(pageNumber) {
|
||||
ourPackageRepositoryResource.search(pageNumber - 1, vm.pagination.pageSize, getActiveCategory(), vm.searchQuery)
|
||||
.then(function (pack) {
|
||||
vm.packages = pack.packages;
|
||||
vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize);
|
||||
});
|
||||
}
|
||||
|
||||
function goToPage(pageNumber) {
|
||||
ourPackageRepositoryResource.search(pageNumber - 1, vm.pagination.pageSize, getActiveCategory(), vm.searchQuery)
|
||||
.then(function (pack) {
|
||||
vm.packages = pack.packages;
|
||||
vm.pagination.totalPages = Math.ceil(pack.total / vm.pagination.pageSize);
|
||||
});
|
||||
}
|
||||
|
||||
function downloadPackage(selectedPackage) {
|
||||
vm.loading = true;
|
||||
|
||||
packageResource
|
||||
.fetch(selectedPackage.id)
|
||||
.then(function(pack) {
|
||||
vm.packageViewState = "packageInstall";
|
||||
vm.loading = false;
|
||||
vm.localPackage = pack;
|
||||
vm.localPackage.allowed = true;
|
||||
},
|
||||
error);
|
||||
}
|
||||
|
||||
function error(e, args) {
|
||||
|
||||
}
|
||||
|
||||
function installPackage(selectedPackage) {
|
||||
|
||||
vm.installState.status = "importing...";
|
||||
|
||||
packageResource
|
||||
.import(selectedPackage)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "Installing...";
|
||||
return packageResource.installFiles(pack);
|
||||
},
|
||||
error)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "Restarting, please wait...";
|
||||
return packageResource.installData(pack);
|
||||
},
|
||||
error)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "All done, your browser will now refresh";
|
||||
return packageResource.cleanUp(pack);
|
||||
},
|
||||
error)
|
||||
.then(function(result) {
|
||||
|
||||
if (result.postInstallationPath) {
|
||||
//Put the redirect Uri in a cookie so we can use after reloading
|
||||
window.localStorage.setItem("packageInstallUri", result.postInstallationPath);
|
||||
}
|
||||
|
||||
//reload on next digest (after cookie)
|
||||
$timeout(function () {
|
||||
window.location.reload(true);
|
||||
});
|
||||
|
||||
},
|
||||
error);
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Packages.RepoController", PackagesRepoController);
|
||||
|
||||
})();
|
||||
293
src/Umbraco.Web.UI.Client/src/views/packager/views/repo.html
Normal file
293
src/Umbraco.Web.UI.Client/src/views/packager/views/repo.html
Normal file
@@ -0,0 +1,293 @@
|
||||
<div ng-controller="Umbraco.Editors.Packages.RepoController as vm" class="clearfix">
|
||||
|
||||
<umb-load-indicator ng-show="vm.loading"></umb-load-indicator>
|
||||
|
||||
<!-- LIST -->
|
||||
<div class="umb-packages-view-wrapper" ng-if="vm.packageViewState === 'packageList'">
|
||||
|
||||
<div class="umb-packages-section">
|
||||
<div class="umb-packages-search">
|
||||
<input class="-full-width-input" type="text" name="query" placeholder="Search for packages" umb-auto-focus ng-model="vm.searchQuery" no-dirty-check>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-show="vm.loading === false">
|
||||
<div class="umb-packages-section" ng-if="vm.searchQuery == ''">
|
||||
<div class="umb-packages-categories">
|
||||
<a href=""
|
||||
class="umb-packages-category"
|
||||
ng-click="vm.selectCategory(category, vm.categories)"
|
||||
ng-repeat="category in vm.categories"
|
||||
ng-class="{'-active': category.active, '-first': $first, '-last': $last}">
|
||||
<div>{{ category.name }}</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-packages-section" ng-if="vm.searchQuery == ''">
|
||||
<h4><strong>Popular</strong></h4>
|
||||
<div class="umb-packages clearfix">
|
||||
|
||||
<div class="umb-package" ng-repeat="package in vm.popular">
|
||||
<a class="umb-package-link" href="" ng-click="vm.showPackageDetails(package)">
|
||||
|
||||
<div class="umb-package-icon">
|
||||
<img ng-src="{{package.icon}}" alt="" />
|
||||
</div>
|
||||
|
||||
<div class="umb-package-info">
|
||||
<div class="umb-package-name">{{ package.name }}</div>
|
||||
<div class="umb-package-description">{{ package.excerpt | limitTo: 40 }}<span ng-if="package.excerpt > (package.excerpt | limitTo: 40)">...</span></div>
|
||||
|
||||
<div class="umb-package-numbers">
|
||||
<small class="umb-package-downloads">
|
||||
<i class="icon-download-alt"></i> <strong>{{ package.downloads }}</strong>
|
||||
</small>
|
||||
<small class="umb-package-karma">
|
||||
<i class="icon-hearts"></i> <strong>{{ package.ownerInfo.karma }}</strong>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
</div> <!-- end package -->
|
||||
|
||||
</div> <!-- end packages -->
|
||||
</div>
|
||||
|
||||
<div class="umb-packages-section">
|
||||
<h4><strong>Latest</strong></h4>
|
||||
<div class="umb-packages clearfix">
|
||||
|
||||
<div class="umb-package" ng-repeat="package in vm.packages">
|
||||
<a class="umb-package-link" href="" ng-click="vm.showPackageDetails(package)">
|
||||
|
||||
<div class="umb-package-icon">
|
||||
<img src="{{ package.icon }}" alt="" />
|
||||
</div>
|
||||
|
||||
<div class="umb-package-info">
|
||||
<div class="umb-package-name">{{ package.name }}</div>
|
||||
<div class="umb-package-description">{{ package.excerpt | limitTo: 40 }}<span ng-if="package.excerpt > (package.excerpt | limitTo: 40)">...</span></div>
|
||||
|
||||
<div class="umb-package-numbers">
|
||||
<small class="umb-package-downloads">
|
||||
<i class="icon-download-alt"></i> <strong>{{ package.downloads }}</strong>
|
||||
</small>
|
||||
<small class="umb-package-karma">
|
||||
<i class="icon-hearts"></i> <strong>{{ package.ownerInfo.karma }}</strong>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
</div> <!-- end package -->
|
||||
|
||||
</div> <!-- end packages -->
|
||||
</div>
|
||||
|
||||
<div class="umb-packages__pagination" ng-if="vm.pagination.totalPages > 1 && vm.loading === false">
|
||||
|
||||
<umb-pagination page-number="vm.pagination.pageNumber"
|
||||
total-pages="vm.pagination.totalPages"
|
||||
on-next="vm.nextPage"
|
||||
on-prev="vm.prevPage"
|
||||
on-go-to-page="vm.goToPage">
|
||||
</umb-pagination>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- DETAILS --->
|
||||
<div class="umb-packages-view-wrapper" ng-if="vm.packageViewState === 'packageDetails' && vm.loading === false">
|
||||
|
||||
<umb-editor-sub-header>
|
||||
<umb-editor-sub-header-content-left>
|
||||
<a class="umb-package-details__back-link" href="" ng-click="vm.setPackageViewState('packageList');">← Take me back</a>
|
||||
</umb-editor-sub-header-content-left>
|
||||
</umb-editor-sub-header>
|
||||
|
||||
<div class="umb-package-details">
|
||||
|
||||
<div class="umb-package-details__main-content">
|
||||
|
||||
<div class="umb-packages-view-title">{{ vm.package.name }}</div>
|
||||
|
||||
<div class="umb-package-details__description" ng-bind-html-unsafe="vm.package.description"></div>
|
||||
|
||||
<div class="umb-gallery">
|
||||
<div class="umb-gallery__thumbnails">
|
||||
<a class="umb-gallery__thumbnail" target="_blank" href="{{ image.source }}" ng-repeat="image in vm.package.images">
|
||||
<img ng-src="{{ image.thumbnail }}" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__sidebar">
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<button class="umb-era-button -blue -full-width" ng-click="vm.downloadPackage(vm.package)">Install package</button>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<div class="umb-package-details__owner-profile">
|
||||
<div class="umb-package-details__owner-profile-avatar">
|
||||
<img class="umb-avatar" ng-src="{{ 'https://our.umbraco.org' + vm.package.ownerInfo.ownerAvatar }}" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="umb-package-details__owner-profile-name">{{ vm.package.ownerInfo.owner }}</div>
|
||||
<div class="umb-package-details__owner-profile-karma">
|
||||
{{ vm.package.ownerInfo.owner }} has <strong>{{ vm.package.ownerInfo.karma }}</strong> karma points
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<div class="umb-package-details__section-title">Information</div>
|
||||
<div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Owner:</div>
|
||||
<div>{{vm.package.ownerInfo.owner}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Contributors:</div>
|
||||
<div ng-repeat="contributor in vm.package.ownerInfo.contributors">
|
||||
<a class="umb-package-details__link" href="{{ contributor.profileUrl }}" target="_blank">{{ contributor.name }}<span ng-if="!$last">, </span></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Created:</div>
|
||||
<div>{{vm.package.created}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Current version:</div>
|
||||
<div>{{vm.package.latestVersion}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">.Net Version:</div>
|
||||
<div>{{vm.package.information.netVersion}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">License:</div>
|
||||
<div>{{vm.package.licenseName}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Downloads:</div>
|
||||
<div>{{vm.package.downloads}}</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">Karma:</div>
|
||||
<div>{{vm.package.ownerInfo.karma}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<div class="umb-package-details__section-title">Compatibility</div>
|
||||
<div class="umb-package-details__section-description">This project is compatible with the following versions as reported by community members who have downloaded this package:</div>
|
||||
<div class="umb-package-details__compatability" ng-repeat="compatibility in vm.package.compatibility | filter:percentage > 0">
|
||||
<div class="umb-package-details__compatability-label">
|
||||
<span class="umb-package-details__information-item-label">{{compatibility.version}}</span>
|
||||
<span class="umb-package-details__information-item-label-2">({{compatibility.percentage}}%)</span>
|
||||
</div>
|
||||
<div class="umb-progress-bar">
|
||||
<span class="umb-progress-bar__progress" style="width: {{compatibility.percentage}}%"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__section">
|
||||
<div class="umb-package-details__section-title">External sources</div>
|
||||
<div>
|
||||
<div class="umb-package-details__information-item" ng-repeat="externalSource in vm.package.externalSources">
|
||||
<a class="umb-package-details__link" target="_blank" href="{{ externalSource.url }}">
|
||||
<i class="icon-out"></i>
|
||||
{{ externalSource.name }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Package details -->
|
||||
<div class="umb-info-local" ng-if="vm.packageViewState === 'packageInstall' && vm.loading === false">
|
||||
<div class="umb-info-local-items">
|
||||
|
||||
<form novalidate name="localPackageForm">
|
||||
<div class="umb-package-icon">
|
||||
<i ng-if="!vm.localPackage.icon" class="icon-box"></i>
|
||||
<img ng-if="vm.localPackage.icon" ng-src="{{vm.localPackage.icon}}" alt="" />
|
||||
</div>
|
||||
|
||||
|
||||
<div class="umb-package-info">
|
||||
<h4 class="umb-info-local-item"><strong>{{ vm.localPackage.name }}</strong></h4>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Author</strong>
|
||||
<a href="{{ vm.localPackage.authorLink }}" target="_blank">{{ vm.localPackage.author }}</a>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Version</strong>
|
||||
{{ vm.localPackage.version }}
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>License</strong>
|
||||
<a href="{{ vm.localPackage.licenseUrl }}">{{ vm.localPackage.license }}</a>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>Read me</strong>
|
||||
<br>
|
||||
<small ng-bind-html-unsafe="vm.localPackage.readMe"></small>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item mt-3" ng-if="vm.installState.status == '' && vm.localPackage.isCompatible">
|
||||
<button type="button"
|
||||
ng-class="{'-inactive' : localPackageForm.$invalid}"
|
||||
ng-disabled="localPackageForm.$invalid"
|
||||
class="umb-era-button -blue inline-flex"
|
||||
ng-click="vm.installPackage(vm.localPackage)">
|
||||
Install package
|
||||
</button>
|
||||
<label for="license-accept" class="umb-package-installer-label">
|
||||
<input type="checkbox" id="license-accept" ng-model="vm.localPackage.packageLicenseAccept" required no-dirty-check>
|
||||
<strong class="label-text">I accept <a href="{{ vm.localPackage.licenseUrl }}">terms of use</a></strong>
|
||||
</label>
|
||||
</div>
|
||||
<div class="umb-info-local-item text-error" ng-if="!vm.localPackage.isCompatible">
|
||||
This package cannot be installed, it requires a minimum Umbraco version of {{vm.localPackage.umbracoVersion}}
|
||||
</div>
|
||||
<div class="umb-info-local-item text-info">
|
||||
<p>{{vm.installState.status}}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
Reference in New Issue
Block a user