Compare commits

...

127 Commits

Author SHA1 Message Date
AJ ONeal
9d57c66492 update urls 2018-05-17 03:02:49 -06:00
AJ ONeal
1503056c65 remove oauth3.js submodule 2017-11-10 13:04:16 -07:00
AJ ONeal
df5819ee32 Merge branch 'master' into v1.2 2017-11-10 13:01:58 -07:00
AJ ONeal
76d9d51e5a add oauth3.js submodule 2017-11-10 13:01:44 -07:00
AJ ONeal
e06188d9c2 remove oauth3.js submodule 2017-11-10 13:00:01 -07:00
Jon Lambson
39b9dae216 fixed verifying site with subdomains 2017-11-08 11:25:49 -07:00
Jon Lambson
655b3117b7 cleaning up some weird loading 2017-11-07 16:35:13 -07:00
Jon Lambson
67c4e8663f better path passing 2017-11-07 15:12:22 -07:00
Jon Lambson
057de03068 fixing breadcrumbsPath for fileContents 2017-11-07 15:04:02 -07:00
Jon Lambson
3bcc504ab2 almost got it. 2017-11-07 14:45:11 -07:00
Jon Lambson
d0ea91c0bb added button and api call 2017-11-06 16:33:49 -07:00
Jon Lambson
ab43fefc49 added upload helper for referrer token 2017-11-06 16:05:04 -07:00
Jon Lambson
8d4337d091 works without subdomain 2017-11-06 13:30:25 -07:00
Jon Lambson
a47b7ac969 added ability to not select a subdomain 2017-11-06 12:59:29 -07:00
Jon Lambson
574857233d added directive for referral 2017-11-03 16:44:09 -06:00
Jon Lambson
4e0545036d updating 2017-11-03 13:14:06 -06:00
Jon Lambson
efa628b099 Merge branch 'v1.2' of git.daplie.com:Daplie/walnut_launchpad into jon/upload-directives 2017-11-03 10:12:50 -06:00
Jon Lambson
132c4e9f35 added a download btn which doesnt work 2017-11-02 17:00:39 -06:00
aj
4e5028dc0f add contentRange api 2017-11-02 22:56:53 +00:00
Jon Lambson
d97c6ab369 Added notification when a new share has completed 2017-11-02 10:14:58 -06:00
Jon Lambson
b897d8275a fixing url params when already accepted invite 2017-11-01 12:10:39 -06:00
Jon Lambson
e9d0ce0846 added timeout to alerts 2017-10-31 17:03:40 -06:00
Jon Lambson
8f987882d2 fixing logging in and redirects with token 2017-10-31 15:55:05 -06:00
Jon Lambson
9368a25fd2 Merge branch 'oauth3' of git.daplie.com:Daplie/walnut_launchpad into jon/rebuild-dropbox-features 2017-10-31 12:53:12 -06:00
Drew Warren
c7444e2c84 Add return to failure case 2017-10-31 18:51:42 +00:00
Jon Lambson
f02300ed2b uncomment code 2017-10-31 12:26:56 -06:00
Jon Lambson
4e16edf4ba fixing ng-src 2017-10-31 12:25:37 -06:00
Jon Lambson
b97bf25788 fixing tokens and logins 2017-10-31 12:24:52 -06:00
Jon Lambson
b1e29b8d8d fixing trailing slashes ui.router 2017-10-30 15:45:58 -06:00
Jon Lambson
9344675546 fixed typo 2017-10-27 17:13:42 -06:00
Jon Lambson
369cca98b5 better restrecited searches 2017-10-27 17:11:28 -06:00
Jon Lambson
cd578bd85f fixed paths 2017-10-27 15:01:13 -06:00
Jon Lambson
1fda0db360 fixing a bunch of ifs 2017-10-27 13:56:43 -06:00
Jon Lambson
e2517c3c1e almost there 2017-10-27 11:00:55 -06:00
Jon Lambson
ae50d3dd14 wtf 2017-10-26 17:24:24 -06:00
Jon Lambson
1b65c78093 fixed crumbs 2017-10-26 16:50:36 -06:00
Jon Lambson
2579370bae thats paths 2017-10-26 16:27:26 -06:00
Jon Lambson
7bc9397564 folders deleted search query 2017-10-26 11:26:43 -06:00
Jon Lambson
894ccf09df fixing upload refresh 2017-10-26 11:08:34 -06:00
Jon Lambson
092714087e fixing more restrictions 2017-10-25 16:25:29 -06:00
Jon Lambson
fabac7b5f2 fixed some weird hiding and showing 2017-10-25 14:39:49 -06:00
Jon Lambson
dfc0bd65a2 fixing deleting folders 2017-10-25 13:46:05 -06:00
Jon Lambson
763c14e77d removing all debuggers 2017-10-25 11:26:42 -06:00
Jon Lambson
f68e126a3b fixing breadcrumbs for restricted sharing 2017-10-25 11:16:55 -06:00
Jon Lambson
a000c8e6ae fixing mulitple loading controllers 2017-10-24 14:58:46 -06:00
Jon Lambson
43fa9e69f8 deleting 2017-10-24 14:32:36 -06:00
Jon Lambson
6a2843d95f removing everything not working 2017-10-24 12:58:35 -06:00
Jon Lambson
dd5b5c666c asdf 2017-10-23 17:41:36 -06:00
Jon Lambson
ef91990767 rename 2017-10-23 17:26:06 -06:00
Jon Lambson
df43dbe68f rename 2017-10-23 17:17:49 -06:00
Jon Lambson
c263ef710b nested view added 2017-10-23 15:56:51 -06:00
Jon Lambson
ff1bd2d597 asdf 2017-10-23 14:20:54 -06:00
Jon Lambson
2ad1d1b96b fixed shares, fixed breadcrumbs search 2017-10-21 01:24:24 -06:00
Jon Lambson
65d1c582af debuggers 2017-10-20 15:02:03 -06:00
Jon Lambson
232bc70764 remove site functionality done 2017-10-18 14:58:03 -06:00
Jon Lambson
3409ddccec fixing shared folder/file upload 2017-10-18 12:10:29 -06:00
Jon Lambson
0b52305043 fixing restricted paths 2017-10-17 17:59:18 -06:00
Jon Lambson
f26468d3dc new file upload and folders 2017-10-17 16:52:57 -06:00
Jon Lambson
5cf80bb80b sharing should be dynamic 2017-10-17 15:19:41 -06:00
Jon Lambson
e91d913547 added delete functionality 2017-10-17 14:29:24 -06:00
Jon Lambson
57eb74d1c9 file tree navigation 2017-10-17 13:51:08 -06:00
Jon Lambson
5314114b4b remove all stupid javascript 2017-10-17 10:22:21 -06:00
Jon Lambson
1e934927a4 blah 2017-10-16 17:11:59 -06:00
Jon Lambson
107b6549c9 some validations 2017-10-16 14:56:35 -06:00
Jon Lambson
2c696b642b fixing upload path from inside a folder 2017-10-13 11:28:14 -06:00
Jon Lambson
ddf5cc5ad3 fixing share accepted message 2017-10-12 16:56:46 -06:00
Jon Lambson
238d828a6f fixing incorrect paths with sharing 2017-10-12 15:33:40 -06:00
Jon Lambson
281ed9d1b2 pulling 2017-10-12 10:41:11 -06:00
Jon Lambson
0ea815a91d fixed no shares 2017-10-10 14:18:37 -06:00
Jon Lambson
b8554c741f validation 2017-10-06 17:20:25 -06:00
Jon Lambson
e40340362e fixing some weird click throughs 2017-10-06 17:08:42 -06:00
Jon Lambson
94d4bb7b8c fixing upload 2017-10-06 12:31:26 -06:00
Jon Lambson
aa82fbb01f Merge branch 'jon/design2' into oauth3 2017-10-06 12:02:25 -06:00
Jon Lambson
aa72c44bdb fixing some upload weirdness 2017-10-06 12:02:03 -06:00
Jon Lambson
fb64b8bedc typo 2017-10-05 17:39:18 -06:00
Jon Lambson
1f424cc291 Merge branch 'jon/design2' into oauth3 2017-10-05 17:34:43 -06:00
Jon Lambson
60d1cd0716 added some css 2017-10-05 17:34:27 -06:00
Jon Lambson
199881244d Merge branch 'jon/design2' into oauth3 2017-10-05 13:01:39 -06:00
Jon Lambson
d7ca0346ec some alerts added 2017-10-05 13:01:05 -06:00
Jon Lambson
5978ac30ff added working on dynamic sharing 2017-10-04 16:27:36 -06:00
Jon Lambson
f1d1bc3686 Merge branch 'jon/design2' into oauth3 2017-10-04 13:35:50 -06:00
Jon Lambson
5cc01ded59 doesnt work 2017-10-04 13:35:28 -06:00
Jon Lambson
7ce1d1b850 stuff 2017-10-03 21:17:36 -06:00
Jon Lambson
af355a3021 Merge branch 'jon/design2' into oauth3 2017-10-03 16:28:52 -06:00
Jon Lambson
b5a8337e60 files done 2017-10-03 16:28:20 -06:00
Jon Lambson
208c9db28f hopefully done with files uploads 2017-10-03 15:48:18 -06:00
Jon Lambson
24907ece8d something asdf 2017-10-03 15:14:52 -06:00
Drew Warren
46476e1bd4 Update README.md 2017-10-03 15:13:34 -06:00
Drew Warren
3369ba52d1 Update README.md 2017-10-03 15:11:25 -06:00
Jon Lambson
6b81dbd564 asdf 2017-10-03 14:49:45 -06:00
Jon Lambson
67c70876a9 fixing 2017-10-03 10:32:02 -06:00
Jon Lambson
0df9771147 asdf 2017-10-02 21:32:36 -06:00
Jon Lambson
d530a898d6 ability to delete file/folder 2017-10-02 16:57:46 -06:00
Jon Lambson
fdc993f7b3 fixing way to delete site files 2017-10-02 16:49:56 -06:00
Jon Lambson
192a8b7933 oops broke everything 2017-10-02 15:25:23 -06:00
Jon Lambson
5196f55629 Merge branch 'oauth3' of git.daplie.com:Daplie/walnut_launchpad into jon/design2 2017-10-02 13:13:41 -06:00
aj
6328c40dc2 pass confirm param 2017-10-02 19:09:06 +00:00
Jon Lambson
5627e4983d functionality to delete file by pathname 2017-10-02 12:29:53 -06:00
Jon Lambson
f60017b725 asdf
;
2017-10-02 11:10:20 -06:00
Jon Lambson
d9056b2cb7 blah 2017-10-02 09:42:30 -06:00
Jon Lambson
58537e1d16 Merge branch 'oauth3' of git.daplie.com:Daplie/walnut_launchpad into jon/design2 2017-09-29 11:26:18 -06:00
aj
7c8e9fb526 merge 2017-09-29 00:17:33 +00:00
Jon Lambson
f75a42ee67 placeholder 2017-09-28 18:03:20 -06:00
Jon Lambson
7c5cd4e152 added more helpers 2017-09-28 17:27:10 -06:00
Jon Lambson
699e510a61 new design 2017-09-28 15:10:50 -06:00
Jon Lambson
bccd62f679 cool 2017-09-28 09:58:02 -06:00
Jon Lambson
3cad78d26b css stuff 2017-09-27 15:29:35 -06:00
Jon Lambson
2acc8cb2b4 werking 2017-09-26 17:25:59 -06:00
Jon Lambson
9b53de6cd6 got it 2017-09-26 13:06:05 -06:00
Jon Lambson
a737338278 almost??? 2017-09-25 17:15:52 -06:00
Jon Lambson
27ee78b409 new design, but not sure 2017-09-22 16:17:42 -06:00
Jon Lambson
b425be39d4 asdf 2017-09-22 14:34:57 -06:00
Jon Lambson
37a40a49ff asdf 2017-09-22 14:21:44 -06:00
Jon Lambson
db2f851daf oops 2017-09-20 16:43:16 -06:00
Jon Lambson
bafe0159ce removing commented out code 2017-09-20 16:42:00 -06:00
Jon Lambson
a292e7027a fixing modal 2017-09-20 16:41:00 -06:00
Jon Lambson
b07b484f9f added some stuff 2017-09-20 15:53:42 -06:00
Jon Lambson
451d6e578a building file tree 2017-09-20 12:43:13 -06:00
Jon Lambson
0611d314b2 fixing account setting login thing 2017-09-13 16:56:38 -06:00
Jon Lambson
ffef89e778 adding css 2017-09-11 13:41:58 -06:00
Jon Lambson
e3a4858e38 two file trees, just in case one doesnt work 2017-09-11 12:40:30 -06:00
Jon Lambson
2fdb097a0a added file tree. needs logic tho. 2017-09-11 11:18:52 -06:00
Jon Lambson
e49337e936 added delete 2017-09-07 15:47:48 -06:00
Jon Lambson
418bd74f8b fixxxx 2017-09-07 15:30:14 -06:00
Jon Lambson
4696eabeb1 added more 2017-09-07 15:26:22 -06:00
Jon Lambson
21985ad5c5 Merge branch 'oauth3' of git.daplie.com:Daplie/walnut_launchpad into jon/website 2017-09-06 14:18:04 -06:00
Jon Lambson
10084b7eb9 added stuff 2017-09-06 14:17:42 -06:00
23 changed files with 2138 additions and 348 deletions

0
.gitmodules vendored Normal file
View File

View File

@ -1,7 +1,7 @@
Daplie Web App
OAuth3 Web App
--------------
Prototype Daplie Web App.
Prototype OAuth3 Web App.
No build tools or fancy web server required.
@ -9,10 +9,13 @@ Clone and load the HTML. That's all.
```bash
npm install -g serve-https
git clone git@git.daplie.com:Daplie/walnut_launchpad.git
git clone git@git.coolaj86.com:coolaj86/walnut_launchpad.html.git
# install oauth3 to /assets/oauth3.org
pushd walnut_launchpad
bash ./install.sh
pushd landing-page
serve-https
```
<https://localhost.daplie.me:8443>
<https://localhost.example.com:8443>

@ -1 +0,0 @@
Subproject commit db284fbf911dc4f9d0cb99bb512d9663dcfd0ece

View File

@ -16,6 +16,9 @@
top: 25vh;
}
/* Common CSS */
.avoid-clicks {
pointer-events: none;
}
.cp {
cursor: pointer;
}
@ -34,7 +37,15 @@
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
}
.ls-none {
list-style: none;
}
.ls-pd0 {
-webkit-padding-start: 0;
}
.padding-side-15 {
padding: 0px 15px;
}
/* Side Menu */
.side-menu {
padding-top: 10px;
@ -58,11 +69,12 @@
align-items: center;
}
.button-container.active .side-menu-button {
background: steelblue;
color: white;
color: #fff;
background-color: #286090;
border-color: #122b40;
}
.button-container.active .button-title {
color: steelblue;
color: #286090;
}
.button-container a:hover {
text-decoration: none;
@ -148,3 +160,636 @@
overflow: hidden;
background-color: #e5e5e5;
}
.demo-title {
text-align: center;
font-size: 3rem;
margin-bottom: 50px;
}
.invite-option {
border: 1px solid #e5e5e5;
}
.invite-card-container {
flex-wrap: wrap;
width: 100%;
display: flex;
}
.invite-card-container .invite-option {
width: 25%;
background: white;
float: left;
padding: 2%;
text-align: center;
-webkit-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
margin: 5px;
}
.invite-card-container .invite-option:hover {
/*cursor: pointer;*/
box-shadow: 0px 2px 30px rgba(0, 0, 0, 0.3);
-webkit-transform: scale(1.04);
transform: scale(1.04);
}
.invite-card-container .invite-option:hover i, .invite-card-container .invite-option:hover h1, .invite-card-container .invite-option:hover span, .invite-card-container .invite-option:hover b {
color: #286090;
}
.invite-card-container .invite-option:hover .front {
opacity: 0;
visibility: hidden;
}
.invite-card-container .invite-option:hover .back {
opacity: 1 !important;
visibility: visible !important;
}
.invite-card-container .invite-option:hover .back a.button {
cursor: pointer;
-webkit-transform: translateY(0px) !important;
transform: translateY(0px) !important;
}
.invite-card-container .invite-option hr {
border: none;
border-bottom: 1px solid #F0F0F0;
}
.invite-card-container .invite-option i {
color: #D8D8D8;
-webkit-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
.invite-card-container .invite-option h1 {
margin: 10px 0;
color: #212121;
-webkit-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
.invite-card-container .invite-option p {
color: #999;
padding: 0 10px;
line-height: 1.3;
}
.invite-card-container .invite-option .price {
position: relative;
}
.invite-card-container .invite-option .price .front span.price {
font-size: 2rem;
text-transform: uppercase;
margin-top: 20px;
display: block;
font-weight: 700;
position: relative;
}
.invite-card-container .invite-option .price .front span.price b {
position: absolute;
font-size: 1rem;
margin-left: 2px;
font-weight: 600;
}
.invite-card-container .invite-option .price .back {
opacity: 0;
visibility: hidden;
-webkit-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
.invite-card-container .invite-option .price .back a.button {
background: #286090;
padding: 15px 20px;
display: inline-block;
text-decoration: none;
color: white;
position: absolute;
font-size: 13px;
top: -5px;
left: 0;
right: 0;
width: 150px;
margin: auto;
text-transform: uppercase;
-webkit-transform: translateY(20px);
transform: translateY(20px);
-webkit-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
.invite-card-container .invite-option .price .back a.button:hover {
background: #286090;
}
.invite-card-container .invite-option:hover i {
color: white;
}
.website-card-button-group {
display: flex;
justify-content: space-around;
}
.media {
border: 1px solid #d5dbdd;
padding: 5px 20px;
border-radius: 5px;
box-shadow: 0px 2px 1px rgba(0,0,0,0.04);
background: #fff;
display: -ms-flexbox;
display: flex;
-ms-flex-align: start;
align-items: flex-start;
}
.align-self-center {
-ms-flex-item-align: center !important;
align-self: center !important;
}
.rounded-circle {
border-radius: 50%;
}
.media .media-left img {
width: 75px;
}
.shares-container {
list-style: none;
-webkit-padding-start: 0px;
}
/*
Tree core styles
*/
.tree { margin: 1em; }
.tree input {
position: absolute;
clip: rect(0, 0, 0, 0);
}
.tree input ~ ul { display: none; }
.tree input:checked ~ ul { display: block; }
/*
Tree rows
*/
.tree li {
line-height: 1.2;
position: relative;
padding: 0 0 1em 1em;
}
.tree ul li { padding: 1em 0 0 1em; }
.tree > li:last-child { padding-bottom: 0; }
/*
Tree labels
*/
.tree_label {
position: relative;
display: inline-block;
background: #fff;
}
label.tree_label { cursor: pointer; }
label.tree_label:hover { color: #666; }
/*
Tree expanded icon
*/
label.tree_label:before {
/*background: #000;*/
color: #000;
position: relative;
z-index: 1;
float: left;
margin: 0 1em 0 -2em;
width: 1em;
height: 1em;
border-radius: 1em;
font-family: FontAwesome;
content: '\f07b';
text-align: center;
line-height: .9em;
}
/*
Tree branches
*/
/*.tree li:before {
position: absolute;
top: 0;
bottom: 0;
left: -.5em;
display: block;
width: 0;
border-left: 1px solid #777;
content: "";
}*/
.tree_label:after {
position: absolute;
top: 0;
left: -1.5em;
display: block;
height: 0.5em;
width: 1em;
border-bottom: 1px solid #777;
border-left: 1px solid #777;
border-radius: 0 0 0 .3em;
content: '';
}
.tree_label.filez:after {
position: absolute;
font-family: FontAwesome;
top: 0;
left: -1.5em;
display: block;
height: 0.5em;
width: 1em;
border-bottom: 1px solid #777;
border-left: 1px solid #777;
border-radius: 0 0 0 .3em;
content: '\f15c';
}
label.tree_label:active:before, label.tree_label:hover:before {
position: absolute;
font-family: FontAwesome;
top: 0;
display: block;
height: 0.5em;
width: 1em;
border-bottom: 1px solid #777;
border-left: 1px solid #777;
border-radius: 0 0 0 .3em;
content: '\f07c';
}
.breadcrumbs-list:last-child {
color: #777;
}
li.move-back {
margin-left: -20px;
}
label.tree_label:after { border-bottom: 0; }
ul.tree.files-only.ls-none {
margin-left: 30px;
}
.tree li:last-child:before {
height: 1em;
bottom: auto;
}
.tree > li:last-child:before { display: none; }
.tree_custom {
display: block;
background: #eee;
padding: 1em;
border-radius: 0.3em;
}
.tree ul {
-webkit-padding-start: 0;
}
.websites-tile img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
.websites-tile iframe {
border-width: 2px;
border-style: none;
border-color: none;
border-image: inone;
}
.websites-tile .btn {
background-color: white;
border: 1px solid #cccccc;
color: #696969;
padding: 0.5rem;
text-transform: uppercase;
}
.websites-tile .btn--block {
display: block;
width: 100%;
}
.websites-tile .cards {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
}
.websites-tile .cards__item {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
padding: 1rem;
}
@media (min-width: 40rem) {
.websites-tile .cards__item {
width: 50%;
}
}
@media (min-width: 56rem) {
.websites-tile .cards__item {
width: 33.3333%;
}
}
.websites-tile .card {
background-color: white;
border-radius: 0.25rem;
box-shadow: 0 20px 40px -14px rgba(0, 0, 0, 0.25);
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
overflow: hidden;
max-width: 350px;
min-width: 350px;
}
.websites-tile .card:hover .card__image {
-webkit-filter: contrast(100%);
filter: contrast(100%);
}
.websites-tile .card__content {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
padding: 1rem;
}
.websites-tile .card__image {
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
background: rgba(0, 0, 0, 0.5);
border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem;
-webkit-filter: contrast(70%);
filter: contrast(70%);
overflow: hidden;
position: relative;
-webkit-transition: -webkit-filter 0.5s cubic-bezier(0.43, 0.41, 0.22, 0.91);
transition: -webkit-filter 0.5s cubic-bezier(0.43, 0.41, 0.22, 0.91);
transition: filter 0.5s cubic-bezier(0.43, 0.41, 0.22, 0.91);
transition: filter 0.5s cubic-bezier(0.43, 0.41, 0.22, 0.91), -webkit-filter 0.5s cubic-bezier(0.43, 0.41, 0.22, 0.91);
}
.websites-tile .card__title {
color: #696969;
font-size: 1.25rem;
font-weight: 300;
letter-spacing: 2px;
text-transform: uppercase;
}
.websites-tile .card__text {
-webkit-box-flex: 1;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
font-size: 0.875rem;
line-height: 1.5;
margin-bottom: 1.25rem;
}
.card__title.text-center {
margin-bottom: 10px;
}
a:hover, a:focus {
color: #2a6496;
text-decoration: none;
}
.square-service-block{
position:relative;
overflow:hidden;
margin:15px auto;
}
.square-service-block a {
background-color: #e74c3c;
border-radius: 5px;
display: block;
padding: 60px 20px;
text-align: center;
width: 100%;
}
.square-service-block a:hover{
background-color: rgba(231, 76, 60, 0.8);
border-radius: 5px;
}
.ssb-icon {
color: #fff;
display: inline-block;
font-size: 28px;
margin: 0 0 20px;
}
h2.ssb-title {
color: #fff;
font-size: 20px;
font-weight: 200;
margin:0;
padding:0;
text-transform: uppercase;
}
.folder-actions-list .root {
display: none;
}
.folder-actions-list {
margin: 20px 0px;
-webkit-padding-start: 0px;
}
.folder-actions-list i {
color: #337ab7;
}
.folder-actions-list li {
padding: 5px 0px;
}
multiselect {
display:block;
}
multiselect .btn {
width: 100%;
display: inline-block;
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
text-align: center;
vertical-align: middle;
cursor: pointer;
color: #333333;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
background-color: #f5f5f5;
background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
border: 1px solid #cccccc;
border-bottom-color: #b3b3b3;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
}
.btn .caret {
margin-top: 9px;
}
multiselect .btn.error{
border: 1px solid #da4f49 !important;
}
multiselect .dropdown-menu {
max-height: 300px;
overflow-y: auto;
}
multiselect .dropdown-menu {
width: 100%;
margin-top: -2px;
box-sizing: border-box;
padding: 2px;
}
multiselect .dropdown-menu > li > a {
padding: 3px 10px;
cursor:pointer;
}
.icon-ok:before {
content: "\f00c";
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
text-decoration: inherit;
color: #000;
font-size: 14px;
}
.icon-remove:before {
content: "\f00d";
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
text-decoration: inherit;
color: #000;
font-size: 14px;
}
.error-notice {
margin-bottom: 15px;
}
.error-notice .oaerror {
width: 95%; /* Configure it fit in your design */
margin: 0 auto; /* Centering Stuff */
background-color: #FFFFFF; /* Default background */
padding: 20px;
border: 1px solid #eee;
border-left-width: 5px;
border-radius: 3px;
margin: 0 auto;
font-family: 'Open Sans', sans-serif;
font-size: 16px;
}
.error-notice .danger {
border-left-color: #d9534f; /* Left side border color */
background-color: rgba(217, 83, 79, 0.1); /* Same color as the left border with reduced alpha to 0.1 */
}
.error-notice .danger strong {
color: #d9534f;
}
.error-notice .warning {
border-left-color: #f0ad4e;
background-color: rgba(240, 173, 78, 0.1);
}
.error-notice .warning strong {
color: #f0ad4e;
}
.error-notice .info {
border-left-color: #5bc0de;
background-color: rgba(91, 192, 222, 0.1);
}
.error-notice .info strong {
color: #5bc0de;
}
.error-notice .success {
border-left-color: #3c763d;
background-color: rgba(43, 84, 44, 0.1);
}
.error-notice .success strong {
color: #3c763d;
}
.websites-tile .card__image--fence {
min-width: 350px;
min-height: 350px;
max-width: 350px;
max-height: 350px;
width: 350px;
height: 350px;
}
.referrer-modal div {
position: relative;
background-color: #3D3D3D;
max-width: 600px;
min-width: 150px;
padding: 15px;
text-align: center;
margin: 50px auto 0 auto;
border-radius: 5px;
z-index: 9999;
cursor: pointer;
box-shadow: 0 0 5px 1px grey;
}
.referrer-modal div::before {
content: '';
background-color: rgba(0,0,0,0.5);
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
}
.referrer-modal h4 {
font-family: 'Montserrat', Verdana, Sans-Serif;
color: coral;
}
.referrer-modal p {
font-family: 'Source Sans Pro', Verdana, Sans-Serif;
color: white;
}

View File

@ -34,6 +34,10 @@
<script src="/js/lib/angular/angular-local-storage.js" charset="utf-8"></script>
<script src="/js/lib/angular/angular-ui-router.min.js" charset="utf-8"></script>
<script src="/js/lib/angular/angucomplete-alt.min.js" charset="utf-8"></script>
<script src="/js/lib/angular/multiselect-dropdown.js" charset="utf-8"></script>
<script src="/js/lib/ez-file-tree/ez-file-tree.min.js" charset="utf-8"></script>
<script src="/js/lib/ez-file-tree/ez-object2array.min.js" charset="utf-8"></script>
<!-- Core Files -->
<script src="/js/app.js" charset="utf-8"></script>
<!-- Services -->

View File

@ -4,7 +4,7 @@
var angular = window.angular;
var OAUTH3 = window.OAUTH3;
var app = window.app = angular.module('launchpad', ['oauth3.org', 'ui.router', 'LocalStorageModule', 'angucomplete-alt']);
var app = window.app = angular.module('launchpad', ['oauth3.org', 'ui.router', 'LocalStorageModule', 'angucomplete-alt', 'ez.fileTree', 'ui.multiselect']);
app.directive('daplieFileChange', function () {
return {
@ -20,15 +20,19 @@ app.directive('daplieFileChange', function () {
};
});
app.config(['$stateProvider', '$urlRouterProvider', 'localStorageServiceProvider',
function ($stateProvider, $urlRouterProvider, localStorageServiceProvider) {
app.config([
'$stateProvider', '$urlRouterProvider', 'localStorageServiceProvider', '$urlMatcherFactoryProvider',
function ($stateProvider, $urlRouterProvider, localStorageServiceProvider, $urlMatcherFactoryProvider) {
$urlMatcherFactoryProvider.strictMode(false);
localStorageServiceProvider.setPrefix('launchpad').setStorageType('sessionStorage');
$urlRouterProvider.otherwise('/splash-page');
$stateProvider
.state('splash-page', {
data: { requiresLogin: false, session: null },
data: { requiresLogin: false, session: null },
url: '/splash-page',
templateUrl: '/templates/splash-page.html',
controller: 'loginCtrl as vm'
@ -121,6 +125,24 @@ app.config(['$stateProvider', '$urlRouterProvider', 'localStorageServiceProvider
}
}
})
.state('app.applications', {
url: 'apps',
views: {
'content@': {
templateUrl: 'templates/applications.html',
controller: '',
}
}
})
.state('app.devices', {
url: 'devices',
views: {
'content@': {
templateUrl: 'templates/devices.html',
controller: '',
}
}
})
.state('app.account-settings', {
url: 'account-settings',
views: {
@ -133,23 +155,22 @@ app.config(['$stateProvider', '$urlRouterProvider', 'localStorageServiceProvider
}]);
app.run(['$rootScope', '$state', 'Auth', '$location', function($rootScope, $state, Auth, $location) {
$rootScope.urlArray = [];
$rootScope.urlCrumbs = [];
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
var requiresLogin = toState.data.requiresLogin;
toState.data.session = $location.search();
$rootScope.redirectedURL = toState.url;
var query = $location.search();
$rootScope.urlArray.push($rootScope.redirectedURL);
var Crumbs = new Object();
Crumbs = {
absUrl: $location.$$absUrl,
url: $location.$$url,
path: $location.$$path,
params: $location.$$search,
toPath: toState.url,
fromPath: fromState.url
};
$rootScope.urlCrumbs.push(Crumbs);
if (requiresLogin && !Auth.isLoggedIn()) {
event.preventDefault();
if (!angular.equals(toState.data.session, {})) {
toState.data.session.token = OAUTH3.jwt.decode(query.access_token);
toState.data.session.refresh = OAUTH3.jwt.decode(query.refresh_token);
Auth.add(query);
$state.go('app.' + $rootScope.redirectedURL);
} else {
$state.go('splash-page', { 'toState': toState.name });
}
$state.go('splash-page', { 'toState': toState.name });
}
});
}]);

View File

@ -1,3 +1,10 @@
app.directive('referrerNotification', [function () {
return {
restrict: 'EA',
templateUrl: '/templates/widgets/referrer.html',
};
}]);
app.controller('loginCtrl', [
'$scope', '$timeout', 'Auth', '$location', 'localStorageService', '$rootScope', 'azp@oauth3.org', '$stateParams'
, function ($scope, $timeout, Auth, $location, localStorageService, $rootScope, Oauth3, $stateParams) {
@ -16,6 +23,29 @@ app.controller('loginCtrl', [
vm.showAdvanced = true;
vm.hideReferrerNotification = 'hidden';
vm.referrerInit = function () {
vm.referrerAlert = {};
if ($location.hash() !== '') {
var str = $location.hash();
var domain = str.split('=')[1];
vm.referrerAlert.title = domain + " has been created. What's next?";
vm.referrerAlert.msg = "Do this next... Or do this... Or this...";
if (str.indexOf('referrer') === 0) {
vm.hideReferrerNotification = '';
vm.closeReferrerModal = function () {
var popup = document.querySelector('.referrer-pop-up');
popup.style.display = 'none';
$location.url($location.path());
};
vm.sendToShares = function (){
$location.path('/website');
vm.hideReferrerNotification = 'hidden';
};
}
}
};
vm.toggleAdvanced = function () {
vm.showAdvanced = !vm.showAdvanced;
vm.independentIssuer = !vm.independentIssuer;
@ -105,10 +135,15 @@ app.controller('loginCtrl', [
session.subject = subject;
session.issuer = issuer;
Auth.add(session);
if ($rootScope.redirectedURL === '/splash-page') {
$location.path('/home');
if (Auth.sessions.length === 1) {
if ($rootScope.urlCrumbs[0].path === '/splash-page') {
$location.path('/home');
} else {
window.location.replace($rootScope.urlCrumbs[0].absUrl);
}
} else {
$location.path('/' + $rootScope.redirectedURL);
location.reload();
// window.location.replace($rootScope.urlCrumbs[$rootScope.urlCrumbs.length -1].absUrl);
}
}, function (err) {
console.error('auth error');

View File

@ -7,6 +7,7 @@ var app = window.app;
//
// TODO modularize for reuse
function analyzeFile(file, vm) {
vm.triggerFileRefresh = 'changed';
vm.isZip = /\.zip$/.test(file.name);
vm.unzip = vm.isZip;
vm.stripZip = vm.isZip;
@ -36,13 +37,48 @@ function handleFiles(ev) {
window.document.body.addEventListener('change', handleFiles);
*/
app.directive('daplieFileChange', [function () {
return {
restrict: 'A',
require:"ngModel",
link: function (scope, element, attrs, ngModel) {
element.bind('change', function (event) {
var files = event.target.files;
ngModel.$setViewValue(files[0]);
scope.$eval(attrs.daplieFileChange);
});
}
};
}]);
app.directive('fileTree', [function () {
return {
restrict: 'EA',
templateUrl: '/templates/widgets/filetree.html',
};
}]);
app.directive('notificationBar', [function () {
return {
restrict: 'EA',
templateUrl: '/templates/widgets/website-notification-bar.html',
};
}]);
app.controller('websiteCtrl', [
'$scope', '$q', 'Auth', 'azp@oauth3.org', '$timeout'
, function ($scope, $q, Auth, Oauth3, $timeout) {
'$scope', '$q', 'Auth', 'azp@oauth3.org', '$timeout', '$sce', '$rootScope', '$location',
function ($scope, $q, Auth, Oauth3, $timeout, $sce, $rootScope, $location) {
var vm = this;
var angular = window.angular;
vm.domains = [];
vm.copyUploadPath = '';
vm.displaySpinner = '';
vm.deleteAll = '';
vm.referrerSelectedDomain = false;
vm.alertNotification = {
hidden: 'hidden'
};
//vm.unzipPath = '/';
vm.uploadPath = '/';
@ -76,11 +112,14 @@ app.controller('websiteCtrl', [
el.session = session.token.sub + '@' + session.token.iss;
});
});
}, function(err) {
console.error("There was an error 1A", err);
return els;
});
});
})).then(function (results) {
return els;
});
}, function(err) {console.error("There was an error 1B", err)});
};
vm.getDomains = function () {
@ -137,20 +176,47 @@ app.controller('websiteCtrl', [
});
};
vm.setRecordDomain = function(domain) {
vm.domain.sub = vm.newRecord || '';
if (vm.record !== undefined) {
domain.title = vm.record.host;
domain.description.domain = vm.record.host;
domain.originalObject.domain = vm.record.host;
}
};
vm.setRecord = function () {
// TODO set record based on (record.host === sub + domain.domain)
var sub = vm.newRecord;
if ('@' === sub) {
if ('@' === sub || sub === undefined) {
sub = '';
}
vm.record = { sub: sub, host: (sub ? sub + '.' : '') + vm.domain.domain };
vm.currentHost = vm.record.host;
console.log('[setRecord] vm.record:');
console.log(vm.record);
};
vm.paramInit = function () {
// Share example -> ?token=fe8386d7ad6273bd9ca29864148c0d2d©
if ($rootScope.urlCrumbs[$rootScope.urlCrumbs.length -1].params.token !== undefined) {
vm.Shares.inviteToken = $rootScope.urlCrumbs[$rootScope.urlCrumbs.length -1].params.token;
var result = { data: { info: true } };
var msg = "You have a new share.";
vm.buildNotification(result, msg);
}
// Referrer example -> #referrer=daplieeleven.daplie.me
vm.referrerSelectedDomainName = $location.url().split('=')[1];
if ($location.url().includes('referrer')) {
$timeout(function() {
var el = document.querySelector('.create-share-btn');
el.click();
vm.referrerSelectedDomain = true;
}, 0);
}
};
vm.selectRecord = function (record) {
vm.record = record;
vm.newRecord = record.sub;
@ -169,13 +235,14 @@ app.controller('websiteCtrl', [
});
};
vm._uploadFile = function (pkg, opts) {
vm.newFileUploaded = opts.newFile.name;
opts.progress = opts.progress || opts;
return pkg.add({
hostname: opts.domain
, domain: opts.domain
, tld: opts.tld
, sld: opts.sld
//, sub: opts.record.sub
, sub: opts.sub
, multipart: { site: opts.newFile }
, progress: function (ev) {
// TODO must digest
@ -188,8 +255,23 @@ app.controller('websiteCtrl', [
, strip: opts.stripZip
, path: opts.uploadPath
}).then(function (result) {
opts.progress.uploadTotal = 0;
window.alert(JSON.stringify(result));
if (result.data.error) {
var msg = vm.newFileUploaded + " has encountered an error. " + result.data.error.message + '.';
} else {
var msg = "'" + vm.newFileUploaded + "'" + " has been uploaded.";
vm.uploadFolderContainer = false;
vm.uploadFileContainer = false;
}
vm.buildNotification(result, msg);
if (vm.copyR !== undefined) {
vm.cleanArrays();
var path = vm.breadcrumbsPath.join('/');
cleanPathQuery(path);
vm.Sites.contents(vm.copyR, vm.cleanedPath);
} else {
$location.url($location.path());
vm.listSites();
}
});
};
@ -204,7 +286,6 @@ app.controller('websiteCtrl', [
var sub;
var sld;
var tld;
/*
//vm.unlock('webpreneur');
if (!vm.currentFiles || !vm.currentFiles.length) {
@ -221,8 +302,7 @@ app.controller('websiteCtrl', [
return;
}
if (!vm.currentHost) {
window.alert('No hostname chosen.');
return;
vm.setRecord();
}
if (vm.domain) {
@ -233,6 +313,7 @@ app.controller('websiteCtrl', [
} else {
sld = vm.domain.sld;
tld = vm.domain.tld;
sub = vm.domain.sub;
}
} else {
parts = vm.currentHost.split('.');
@ -253,11 +334,12 @@ app.controller('websiteCtrl', [
// (because two users could both claim a single domain)
// We're claiming it at the top level (i.e. example.com)
// but we could also claim it at the subdomain level (needs UI update)
var domainReq = { sld: sld, tld: tld, sub: undefined };
var domainReq = { sld: sld, tld: tld, sub: sub };
return pkg.request(domainReq).then(function (result) {
var sess;
var prom;
var def;
var sub;
// can validate automatically
if (vm.domain.session && vm._isSubDomain(vm.currentHost, vm.domain.domain)) {
@ -271,7 +353,11 @@ app.controller('websiteCtrl', [
if (sess) {
prom = Auth.get(sess).then(function (oauth3) {
return oauth3.api('dns.set', { sld: sld, tld: tld, sub: ('' + result.data.prefix), type: 'TXT', ttl: 300, value: result.data.challenge });
sub = result.data.prefix;
if (result.data.sub) {
sub += '.' + result.data.sub;
}
return oauth3.api('dns.set', { sld: sld, tld: tld, sub: sub, type: 'TXT', ttl: 5, value: result.data.challenge });
});
}
}
@ -296,66 +382,280 @@ app.controller('websiteCtrl', [
});
};
vm.Sites.setUpload = function (r) {
console.log("Hey! At least it can tell if there's a change!");
if (r.newFile === undefined) {
r.newFile = vm.newFile;
}
analyzeFile(r.newFile, r);
console.log(r);
};
vm.Sites.upload = function (r) {
var pkg = Auth.oauth3.pkg('www@daplie.com');
//analyzeFile(r.newFile, r);
vm._uploadFile(pkg, r);
};
vm.Sites.archive = function (r) {
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.archive({
hostname: r.domain
, domain: r.domain
, tld: r.tld
, sld: r.sld
//, sub: vm.record.sub
//, path: vm.uploadPath
}).then(function (result) {
window.alert(JSON.stringify(result));
// TODO use iframe to initiate download?
window.open(result.data.url);
});
vm.cleanUploads = function (r) {
vm.folderName = '';
};
vm.Sites.remove = function (r, opts) {
if (!window.confirm("Delete files for this site?")) {
return;
}
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.remove({
hostname: r.domain
, domain: r.domain
, tld: r.tld
, sld: r.sld
//, sub: vm.record.sub
, path: opts.path || r.path
, confirm: opts.confirm || r.confirm
}).then(function (result) {
window.alert(JSON.stringify(result));
});
};
vm.Sites.contents = function (r) {
vm.Sites.allContents = function (r) {
vm.copyR = r;
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.contents({
hostname: r.domain
, domain: r.domain
, tld: r.tld
, sld: r.sld
//, sub: r.sub
, path: r.newPath
, sub: r.sub
, path: r.shareAccess.path
}).then(function (result) {
window.alert(JSON.stringify(result));
if (result.data.error) {
vm.folderStructure = result;
} else {
vm.cleanArrays();
vm.folderStructure = result;
result.data.forEach(function(data){
if (data.file) {
vm.siteFiles.push(data.name);
}
if (data.directory) {
vm.siteDirectories.push(data.name);
}
});
}
vm.displaySpinner = 'hidden';
vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1];
});
};
var cleanPathQuery = function (path) {
vm.cleanedPath = path.replace(/\/+/g, '/');
return vm.cleanedPath;
};
vm.closeFileUploadsContainers = function () {
vm.uploadFolderContainer = false;
vm.uploadFileContainer = false;
};
vm.Sites.fileContents = function (file, r) {
var path = vm.breadcrumbsPath;
path.push(file);
path = path.join('/');
cleanPathQuery(path);
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.contentRange({
hostname: r.domain,
domain: r.domain,
tld: r.tld,
sld: r.sld,
sub: r.sub,
path: vm.cleanedPath
}).then(function (result) {
vm.folderStructure = result;
});
};
vm.Sites.contents = function (r, dir) {
vm.siteFiles = [];
vm.siteDirectories = [];
dir = dir + '/';
cleanPathQuery(dir);
dir = vm.cleanedPath;
vm.previousSearchQuery = dir;
vm.displaySpinner = '';
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.contents({
hostname: r.domain,
domain: r.domain,
tld: r.tld,
sld: r.sld,
sub: r.sub,
path: dir
}).then(function (result) {
vm.cleanArrays();
vm.displaySpinner = 'hidden';
vm.folderStructure = result;
result.data.forEach(function(data){
if (data.file) {
vm.siteFiles.push(data.name);
}
if (data.directory) {
vm.siteDirectories.push(data.name);
}
});
vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1];
});
};
var crumbsCleanUp = function (crumb) {
var str2arryQuery = cleanPathQuery(vm.breadcrumbsPath.join('/'));
var str2arry = vm.breadcrumbs;
str2arryQuery = str2arryQuery.split('/');
if (vm.copyR.shareAccess.path !== '/') {
var removeFromBreadcrumbsQuery = str2arryQuery.indexOf(crumb) + 1;
var removeFromBreadcrumbs = str2arry.indexOf(crumb) + 1;
vm.breadcrumbsPath = str2arryQuery.splice(0,removeFromBreadcrumbsQuery);
vm.breadcrumbs = str2arry.splice(0,removeFromBreadcrumbs);
var strictPath = vm.strictPath.slice(0, -1);
if (vm.breadcrumbsPath.join('/').indexOf(strictPath) !== 0) {
vm.breadcrumbsPath = strictPath.split('/');
vm.breadcrumbs = strictPath.split('/');
vm.breadcrumbs.shift();
var result = { data: { warning: true } };
vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 2];
var msg = "You can only view inside the " + "'" + vm.currentFolder + "'" + ' folder.';
vm.buildNotification(result, msg);
}
} else {
var removeFromBreadcrumbsQuery = str2arryQuery.indexOf(crumb) + 1;
var removeFromBreadcrumbs = str2arry.indexOf(crumb) + 1;
vm.breadcrumbsPath = str2arryQuery.splice(0,removeFromBreadcrumbsQuery);
vm.breadcrumbs = str2arry.splice(0,removeFromBreadcrumbs);
}
};
var removeFolderCrumbsCleanUp = function (crumb) {
var str2arryQuery = cleanPathQuery(vm.breadcrumbsPath.join('/'));
var str2arry = vm.breadcrumbs;
str2arryQuery = str2arryQuery.split('/');
var removeFromBreadcrumbsQuery = str2arryQuery.indexOf(crumb);
var removeFromBreadcrumbs = str2arry.indexOf(crumb);
vm.breadcrumbsPath = str2arryQuery.splice(0,removeFromBreadcrumbsQuery);
vm.breadcrumbs = str2arry.splice(0,removeFromBreadcrumbs);
vm.copyR.fromFolder = vm.breadcrumbsPath.join('/');
vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1];
};
vm.getDirectoriesFromBreadcrumbs = function (dir) {
crumbsCleanUp(dir);
cleanPathQuery(vm.breadcrumbsPath.join('/'));
vm.Sites.contents(vm.copyR, vm.cleanedPath);
vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1];
};
vm.getDirectories = function (dir) {
vm.breadcrumbs.push(dir);
vm.breadcrumbsPath.push(dir);
cleanPathQuery(vm.breadcrumbsPath.join('/'));
vm.Sites.contents(vm.copyR, vm.cleanedPath);
vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1];
};
vm.removeAllFiles = function (r, opts) {
opts = {
path: '/',
confirm: true
};
vm.Sites.remove(r, opts);
};
vm.deleteFilesFrom = function (r, file) {
vm.pathRemoved = file;
var path = vm.breadcrumbsPath.join('/');
path = path + '/' + file;
path = cleanPathQuery(path);
var opts = {
path: path
};
vm.Sites.remove(r, opts);
};
vm.deleteFromInsideOfFolder = false;
vm.triggerDeleteFolder = function (path, r) {
removeFolderCrumbsCleanUp(path);
vm.deleteFromInsideOfFolder = true;
path = vm.previousSearchQuery;
var opts = {
path: path
};
vm.cleanArrays();
vm.Sites.remove(r, opts);
};
vm.Sites.remove = function (r, opts) {
if (!window.confirm("Delete files for this site?")) {
return;
}
var pkg = Auth.oauth3.pkg('www@daplie.com');
var removedPath = opts.path;
return pkg.remove({
hostname: r.domain
, domain: r.domain
, tld: r.tld
, sld: r.sld
, sub: r.sub
, path: opts.path || r.path
, confirm: opts.confirm || r.confirm
}).then(function (result) {
vm.cleanArrays();
if (vm.deleteFromInsideOfFolder) {
cleanPathQuery(vm.copyR.fromFolder);
vm.Sites.contents(vm.copyR, vm.cleanedPath);
} else {
cleanPathQuery(vm.breadcrumbsPath.join('/'));
vm.Sites.contents(vm.copyR, vm.cleanedPath);
}
var msg = 'Successfully deleted ' + "'" + removedPath + "'.";
vm.buildNotification(result, msg);
});
};
vm.Sites.archive = function (r) {
var pkg = Auth.oauth3.pkg('www@daplie.com');
var path;
if (vm.breadcrumbsPath === undefined && vm.breadcrumbs === undefined) {
path = r.shareAccess.path;
} else {
cleanPathQuery(vm.breadcrumbsPath.join('/'));
path = vm.cleanedPath;
}
debugger;
// FIXME: Figure out how to download specific folders
return pkg.archive({
hostname: r.domain
, domain: r.domain
, tld: r.tld
, sld: r.sld
, sub: r.sub
, path: path
}).then(function (result) {
window.alert(JSON.stringify(result));
// TODO use iframe to initiate download?
window.open(result.data.url);
});
};
vm.shareFolderFrom = function (r, opts) {
var sharePath;
if (vm.breadcrumbsPath === undefined && vm.breadcrumbs === undefined) {
sharePath = '/';
} else if (vm.breadcrumbsPath.join('/') === '' && vm.breadcrumbs.join('/') === '') {
sharePath = '/';
} else {
sharePath = cleanPathQuery(vm.breadcrumbsPath.join('/'));
sharePath = sharePath + '/';
}
cleanPathQuery(sharePath);
opts = {
sharePath: vm.cleanedPath,
shareMode: vm.copiedShareMode
};
vm.Shares.invite(r, opts);
};
vm.createNewFolder = function (r) {
r.folderName = vm.folderName;
vm.breadcrumbsPath.push(r.folderName);
};
vm.Sites.upload = function (r) {
var pkg = Auth.oauth3.pkg('www@daplie.com');
cleanPathQuery(vm.breadcrumbsPath.join('/'))
r.uploadPath = vm.cleanedPath;
vm._uploadFile(pkg, r);
};
vm.Shares = {};
vm.Shares.invite = function (r) {
vm.Shares.invite = function (r, opts) {
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.invite({
comment: r.shareEmail
@ -363,25 +663,45 @@ app.controller('websiteCtrl', [
, domain: r.domain
, tld: r.tld
, sld: r.sld
//, sub: r.sub
, path: r.sharePath
, mode: r.shareMode
, sub: r.sub
, path: opts.sharePath || r.sharePath
, mode: opts.shareMode || r.shareMode
}).then(function (result) {
var arr = r.sharedWith || [];
arr.push(result.data);
r.sharedWith = arr;
window.alert(JSON.stringify(result.data));
var path = result.data.path;
var person = result.data.comment;
var msg = "You have shared " + "'" + path + "'" + ' with ' + person + ".";
vm.buildNotification(result, msg);
});
};
vm.Shares.accept = function () {
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.acceptInvite({
token: vm.Shares.inviteToken
}).then(function (result) {
window.alert(JSON.stringify(result));
vm.listSites();
if (result.data.error) {
var msg = result.data.error.message + '.';
vm.buildNotification(result, msg);
} else {
var person = result.data.comment;
var path = result.data.path;
var shareMode = result.data.mode;
var domain = result.data.domain;
var msg = 'You accepted a share ' + "'" + domain + "'" + ' from ' + person + '. Take a look at your verified websites below.';
vm.buildNotification(result, msg);
vm.listSites();
}
if ($location.$$search.token) {
delete $location.$$search.token;
vm.Shares.inviteToken = '';
$location.$$compose();
}
});
};
vm.Shares.list = function (r) {
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.listShares({
@ -389,58 +709,67 @@ app.controller('websiteCtrl', [
, hostname: r.domain
, tld: r.tld
, sld: r.sld
//, sub: r.sub
, sub: r.sub
, path: r.sharePath
}).then(function (result) {
vm.displaySpinner = 'hidden';
console.log('list shares result:');
console.log(result);
r.sharedWith = result.data;
//r.usersnames = r.sharedWith.map().join(',');
});
};
vm.deleteWebsite = function (r, s) {
if (!window.confirm("Delete this site?")) {
return;
}
s.sharePath = '/';
vm.Shares.remove(r, s);
};
vm.Shares.remove = function (r, s) {
console.log('Shares.remove');
var pkg = Auth.oauth3.pkg('www@daplie.com');
return pkg.removeShare({
domain: s.domain
, hostname: s.domain
, tld: s.tld
, sld: s.sld
//, sub: r.sub
, sub: r.sub
, path: s.sharePath
, challenge: s.challenge
}).then(function (result) {
var person = result.data.comment;
var msg = "revoked access from " + person;
vm.buildNotification(result, msg);
console.log('remove share result:');
console.log(result);
var index;
r.sharedWith.forEach(function (_s, i) {
if (s.challenge === _s.challenge) {
index = i;
}
});
if (r.sharedWith !== undefined) {
r.sharedWith.forEach(function (_s, i) {
if (s.challenge === _s.challenge) {
index = i;
}
});
r.sharedWith.splice(index, 1);
//r.usersnames = r.sharedWith.map().join(',');
r.sharedWith.splice(index, 1);
//r.usersnames = r.sharedWith.map().join(',');
}
});
};
vm.listSites = function () {
var sites = [];
return $q.all(Auth.sessions.map(function (session) {
return Auth.get(session).then(function (oauth3) {
var pkg = oauth3.pkg('www@daplie.com');
return pkg.list().then(function (result) {
var _sites = result.data;
if (Array.isArray(_sites)) {
sites = _sites.concat(sites);
return;
}
console.error('_sites is not an array');
console.error(_sites);
}, function (err) {
@ -455,16 +784,30 @@ app.controller('websiteCtrl', [
console.log('[listSites] sites:');
console.log(sites);
vm.sites = sites;
vm.sites.forEach(function(site) {
site.urlSafeDomain = "https://" + site.domain;
site.urlSafeDomain = $sce.trustAsResourceUrl(site.urlSafeDomain);
});
});
};
//vm.getDomains();
Auth.api('domains.list', {}).then(function (els) {
console.log('[init] domains.list els:');
console.log(els);
vm.domains = els;
$scope.domain = vm.domains;
// console.log('[init] domains.list els:');
// console.log(els);
if (vm.referrerSelectedDomain) {
Object.keys(els).forEach(function (key) {
if (els[key]['domain'] === vm.referrerSelectedDomainName) {
$scope.domain = [];
$scope.domain.push(els[key]);
}
})
} else {
vm.domains = els;
$scope.domain = vm.domains;
}
});
vm.listSites();
vm.triggerDropdown = function() {
@ -474,12 +817,76 @@ app.controller('websiteCtrl', [
}, 0);
};
vm.cleanArrays = function () {
vm.breadcrumbsPath = [];
vm.breadcrumbs = [];
vm.siteFiles = [];
vm.siteDirectories = [];
if (vm.previousSearchQuery === undefined) {
vm.previousSearchQuery = '';
}
var getBreadcrumbsPath = vm.previousSearchQuery;
vm.breadcrumbsPath = getBreadcrumbsPath.split('/');
var getBreadcrumbs = vm.previousSearchQuery.split('/');
getBreadcrumbs.forEach(function(crumb){
if(crumb !== '') {
vm.breadcrumbs.push(crumb);
}
});
if (vm.copyR !== undefined) {
if (vm.copyR.shareAccess.path !== '/') {
} else {
vm.breadcrumbs.unshift('root');
}
}
};
vm.checkShareRights = function (r) {
if (r.invitedBy) {
r.shareAccess = { write: false, read: false, invite: false };
if (r.mode.includes('w')) {
r.shareAccess.write = true;
}
if (r.mode.includes('r')) {
r.shareAccess.read = true;
}
if (r.mode.includes('x')) {
r.shareAccess.invite = true;
}
r.shareAccess.path = r.path;
vm.strictPath = r.shareAccess.path;
vm.previousSearchQuery = vm.strictPath;
console.log(r.shareAccess);
} else {
r.shareAccess = { write: true, read: true, invite: true, path: '/' };
}
};
$scope.$watch('vm.selectedDomain', function (domainSelected) {
if (domainSelected !== undefined) {
vm.selectDomain(vm.selectedDomain.description);
vm.dom = domainSelected;
if (domainSelected.description === undefined) {
vm.selectDomain(domainSelected);
} else {
vm.selectDomain(vm.selectedDomain.description);
}
}
});
vm.getSharedAccess = function (access) {
vm.accessLevelArry = [];
vm.prettyAccessArray = [];
access.forEach(function(letter) {
vm.prettyAccessArray.push(letter.name);
vm.accessLevelArry.push(letter.value);
});
vm.prettyShareMode = vm.prettyAccessArray.join(", ");
vm.copiedShareMode = vm.accessLevelArry.join(",");
};
$scope.selectedAccess = [];
$scope.accessLevel = [{ name: 'Read', value: 'r' }, { name: 'Write', value: 'w' }, { name: 'Invite', value: 'x' }];
$scope.localDomainSearch = function(str, domain) {
var matches = [];
domain.forEach(function(domain) {
@ -489,6 +896,143 @@ app.controller('websiteCtrl', [
});
return matches;
};
vm.showAction = function (action) {
switch(action) {
case 'invite':
vm.showInviteContainer = true;
vm.websiteTiles = true;
vm.showBackBtn = true;
vm.displayFileTree = true;
if (vm.currentFolder === undefined || vm.currentFolder === 'hidden' || vm.currentFolder === 'root') {
vm.currentFolder = 'All Folders/Files';
}
break;
case 'shares':
vm.showSharesContainer = true;
vm.websiteTiles = true;
vm.showBackBtn = true;
break;
case 'files':
vm.showFilesContainer = true;
vm.websiteTiles = true;
vm.showBackBtn = true;
break;
default:
}
};
vm.buildNotification = function (result, msg) {
if (result.data.error) {
vm.alertNotification = {
className: 'danger',
title: 'Error',
hidden: '',
message: msg
};
} else if (result.data.warning) {
vm.alertNotification = {
className: 'warning',
title: 'Warning',
hidden: '',
message: msg
};
} else if (result.data.info) {
vm.alertNotification = {
className: 'info',
title: 'Info',
hidden: '',
message: msg
};
} else {
vm.alertNotification = {
className: 'success',
title: 'Success',
hidden: '',
message: msg
};
}
window.scrollTo(0, 0);
};
vm.closeAllOpenActions = function () {
$timeout(function() {
vm.showInviteContainer = false;
vm.showSharesContainer = false;
vm.showFilesContainer = false;
vm.displayFileTree = false;
vm.websiteTiles = false;
vm.showBackBtn = false;
vm.autoPopulateWebPath = '';
vm.displaySpinner = '';
vm.folderStructure = undefined;
}, 150);
};
}]);
}());
app.filter('stringify', function() {
function getSerialize (fn, decycle) {
var seen = [], keys = [];
decycle = decycle || function(key, value) {
return '[Parent REFERENCE]: ' + value.id;
};
return function(key, value) {
var ret = value;
if (typeof value === 'object' && value) {
if (seen.indexOf(value) !== -1)
ret = decycle(key, value);
else {
seen.push(value);
keys.push(key);
}
}
if (fn) ret = fn(key, ret);
return ret;
};
}
function getPath (value, seen, keys) {
var index = seen.indexOf(value);
var path = [ keys[index] ];
for (index--; index >= 0; index--) {
if (seen[index][ path[0] ] === value) {
value = seen[index];
path.unshift(keys[index]);
}
}
return '~' + path.join('.');
}
function stringify(obj, fn, spaces, decycle) {
return JSON.stringify(obj, getSerialize(fn, decycle), spaces);
}
stringify.getSerialize = getSerialize;
return function(ob) {
return stringify(ob, undefined, 2);
};
});
app.filter('capitalize', function() {
return function(input) {
return (!!input) ? input.charAt(0).toUpperCase() + input.substr(1).toLowerCase() : '';
};
});
app.filter('prettyShareMode', function() {
return function(input) {
var newArry = [];
var arry = input.split(',');
arry.forEach(function(action){
if (action.includes('w')) {
newArry.push('Write');
}
if (action.includes('r')) {
newArry.push('Read');
}
if (action.includes('x')) {
newArry.push('Invite');
}
});
return newArry.join(', ');
};
});

262
js/lib/angular/multiselect-dropdown.js vendored Normal file
View File

@ -0,0 +1,262 @@
angular.module('ui.multiselect', [])
//from bootstrap-ui typeahead parser
.factory('optionParser', ['$parse', function ($parse) {
var TYPEAHEAD_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;
return {
parse: function (input) {
var match = input.match(TYPEAHEAD_REGEXP), modelMapper, viewMapper, source;
if (!match) {
throw new Error(
"Expected typeahead specification in form of '_modelValue_ (as _label_)? for _item_ in _collection_'" +
" but got '" + input + "'.");
}
return {
itemName: match[3],
source: $parse(match[4]),
viewMapper: $parse(match[2] || match[1]),
modelMapper: $parse(match[1])
};
}
};
}])
.directive('multiselect', ['$parse', '$document', '$compile', 'optionParser',
function ($parse, $document, $compile, optionParser) {
return {
restrict: 'E',
require: 'ngModel',
link: function (originalScope, element, attrs, modelCtrl) {
var exp = attrs.options,
parsedResult = optionParser.parse(exp),
isMultiple = attrs.multiple ? true : false,
required = false,
scope = originalScope.$new(),
changeHandler = attrs.change || anguler.noop;
scope.items = [];
scope.header = 'Select';
scope.multiple = isMultiple;
scope.disabled = false;
originalScope.$on('$destroy', function () {
scope.$destroy();
});
var popUpEl = angular.element('<multiselect-popup></multiselect-popup>');
//required validator
if (attrs.required || attrs.ngRequired) {
required = true;
}
attrs.$observe('required', function(newVal) {
required = newVal;
});
//watch disabled state
scope.$watch(function () {
return $parse(attrs.disabled)(originalScope);
}, function (newVal) {
scope.disabled = newVal;
});
//watch single/multiple state for dynamically change single to multiple
scope.$watch(function () {
return $parse(attrs.multiple)(originalScope);
}, function (newVal) {
isMultiple = newVal || false;
});
//watch option changes for options that are populated dynamically
scope.$watch(function () {
return parsedResult.source(originalScope);
}, function (newVal) {
if (angular.isDefined(newVal))
parseModel();
});
//watch model change
scope.$watch(function () {
return modelCtrl.$modelValue;
}, function (newVal, oldVal) {
//when directive initialize, newVal usually undefined. Also, if model value already set in the controller
//for preselected list then we need to mark checked in our scope item. But we don't want to do this every time
//model changes. We need to do this only if it is done outside directive scope, from controller, for example.
if (angular.isDefined(newVal)) {
markChecked(newVal);
scope.$eval(changeHandler);
}
getHeaderText();
modelCtrl.$setValidity('required', scope.valid());
}, true);
function parseModel() {
scope.items.length = 0;
var model = parsedResult.source(originalScope);
for (var i = 0; i < model.length; i++) {
var local = {};
local[parsedResult.itemName] = model[i];
scope.items.push({
label: parsedResult.viewMapper(local),
model: model[i],
checked: false
});
}
}
parseModel();
element.append($compile(popUpEl)(scope));
function getHeaderText() {
var edit = "edit";
if (!modelCtrl.$modelValue || !modelCtrl.$modelValue.length) return scope.header = 'Can ' + edit;
if (isMultiple) {
edit = '';
var accessLevelArray = [];
modelCtrl.$modelValue.forEach(function(level) {
accessLevelArray.push(level.name);
});
scope.header = "Can " + accessLevelArray.join(', ');
} else {
var local = {};
local[parsedResult.itemName] = modelCtrl.$modelValue;
scope.header = parsedResult.viewMapper(local);
}
}
scope.valid = function validModel() {
if(!required) return true;
var value = modelCtrl.$modelValue;
return (angular.isArray(value) && value.length > 0) || (!angular.isArray(value) && value != null);
};
function selectSingle(item) {
if (item.checked) {
scope.uncheckAll();
} else {
scope.uncheckAll();
item.checked = !item.checked;
}
setModelValue(false);
}
function selectMultiple(item) {
item.checked = !item.checked;
setModelValue(true);
}
function setModelValue(isMultiple) {
var value;
if (isMultiple) {
value = [];
angular.forEach(scope.items, function (item) {
if (item.checked) value.push(item.model);
});
} else {
angular.forEach(scope.items, function (item) {
if (item.checked) {
value = item.model;
return false;
}
});
}
modelCtrl.$setViewValue(value);
}
function markChecked(newVal) {
if (!angular.isArray(newVal)) {
angular.forEach(scope.items, function (item) {
if (angular.equals(item.model, newVal)) {
item.checked = true;
return false;
}
});
} else {
angular.forEach(newVal, function (i) {
angular.forEach(scope.items, function (item) {
if (angular.equals(item.model, i)) {
item.checked = true;
}
});
});
}
}
scope.checkAll = function () {
if (!isMultiple) return;
angular.forEach(scope.items, function (item) {
item.checked = true;
});
setModelValue(true);
};
scope.uncheckAll = function () {
angular.forEach(scope.items, function (item) {
item.checked = false;
});
setModelValue(true);
};
scope.select = function (item) {
if (isMultiple === false) {
selectSingle(item);
scope.toggleSelect();
} else {
selectMultiple(item);
}
};
}
};
}])
.directive('multiselectPopup', ['$document', function ($document) {
return {
restrict: 'E',
scope: false,
replace: true,
templateUrl: 'templates/widgets/share-access-multiselect.html',
link: function (scope, element, attrs) {
scope.isVisible = false;
scope.toggleSelect = function () {
if (element.hasClass('open')) {
element.removeClass('open');
$document.unbind('click', clickHandler);
} else {
element.addClass('open');
scope.focus();
$document.bind('click', clickHandler);
}
};
function clickHandler(event) {
if (elementMatchesAnyInArray(event.target, element.find(event.target.tagName)))
return;
element.removeClass('open');
$document.unbind('click', clickHandler);
scope.$digest();
}
scope.focus = function focus(){
var searchBox = element.find('input')[0];
searchBox.focus();
};
var elementMatchesAnyInArray = function (element, elementArray) {
for (var i = 0; i < elementArray.length; i++)
if (element == elementArray[i])
return true;
return false;
};
}
};
}]);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
angular.module("ez.object2array",[]).filter("object2array",[function(){return function(a){if("[object Array]"===Object.prototype.toString.call(a))return a;var b=[];for(var c in a)b.push(a[c]);return b}}]);

View File

@ -12,7 +12,10 @@ OAUTH3._pkgs['www@daplie.com'] = {
method: 'POST'
, url: OAUTH3.url.normalize(providerUri)
+ '/api/www@daplie.com/acl/sites/' + opts.hostname
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld/*, sub: opts.sub*/, unzip: opts.unzip, strip: opts.strip, path: opts.path })
+ '?' + OAUTH3.utils.query.stringify({
tld: opts.tld, sld: opts.sld, sub: opts.sub, unzip: opts.unzip
, strip: opts.strip, path: opts.path
})
, session: session
, multipart: opts.multipart // special property to be figured out by browser request code
, progress: opts.progress
@ -25,7 +28,7 @@ OAUTH3._pkgs['www@daplie.com'] = {
return OAUTH3.url.normalize(providerUri.replace(/api\./, 'assets.'))
+ '/assets/www@daplie.com/acl/archives/' + opts.hostname
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld/*, sub: opts.sub*/, strip: opts.strip, path: opts.path })
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld, sub: opts.sub, strip: opts.strip, path: opts.path })
;
}
, listShares: function (opts) {
@ -37,7 +40,7 @@ OAUTH3._pkgs['www@daplie.com'] = {
method: 'GET'
, url: OAUTH3.url.normalize(providerUri)
+ '/api/www@daplie.com/acl/shares/' + (opts.domain || opts.hostname)
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld/*, sub: opts.sub*/, path: opts.path })
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld, sub: opts.sub, path: opts.path })
, session: session
}).then(function (result) {
return result;
@ -52,7 +55,7 @@ OAUTH3._pkgs['www@daplie.com'] = {
method: 'DELETE'
, url: OAUTH3.url.normalize(providerUri)
+ '/api/www@daplie.com/acl/shares/' + (opts.domain || opts.hostname) + '/' + (opts.challenge || opts.token)
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld/*, sub: opts.sub*/, path: opts.path })
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld, sub: opts.sub, path: opts.path })
, session: session
}).then(function (result) {
return result;
@ -90,7 +93,7 @@ OAUTH3._pkgs['www@daplie.com'] = {
method: 'POST'
, url: OAUTH3.url.normalize(providerUri)
+ '/api/www@daplie.com/acl/shares/accept/' + opts.token
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld/*, sub: opts.sub*/ })
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld, sub: opts.sub })
, session: session
}).then(function (result) {
return result;
@ -112,12 +115,11 @@ OAUTH3._pkgs['www@daplie.com'] = {
, archive: function (opts) {
var providerUri = opts.audience;
var session = opts.session;
return OAUTH3.request({
method: 'POST'
, url: OAUTH3.url.normalize(providerUri)
+ '/api/www@daplie.com/acl/archives/' + opts.hostname
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld/*, sub: opts.sub*/, strip: opts.strip, path: opts.path })
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld, sub: opts.sub, strip: opts.strip, path: opts.path })
, session: session
}).then(function (result) {
return result;
@ -131,7 +133,22 @@ OAUTH3._pkgs['www@daplie.com'] = {
method: 'GET'
, url: OAUTH3.url.normalize(providerUri)
+ '/api/www@daplie.com/acl/fs/' + opts.hostname
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld/*, sub: opts.sub*/, path: opts.path })
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld, sub: opts.sub, path: opts.path })
, session: session
}).then(function (result) {
return result;
});
}
, contentRange: function (opts) {
var providerUri = opts.audience;
var session = opts.session;
return OAUTH3.request({
method: 'GET'
, url: OAUTH3.url.normalize(providerUri)
+ '/api/www@daplie.com/acl/fs/' + opts.hostname
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld, sub: opts.sub, path: opts.path
, offset: opts.offset, length: opts.length, json: true })
, session: session
}).then(function (result) {
return result;
@ -145,7 +162,10 @@ OAUTH3._pkgs['www@daplie.com'] = {
method: 'DELETE'
, url: OAUTH3.url.normalize(providerUri)
+ '/api/www@daplie.com/acl/sites/' + opts.hostname
+ '?' + OAUTH3.utils.query.stringify({ tld: opts.tld, sld: opts.sld/*, sub: opts.sub*/, path: opts.path })
+ '?' + OAUTH3.utils.query.stringify({
tld: opts.tld, sld: opts.sld, sub: opts.sub
, path: opts.path, confirm: opts.confirm
})
, session: session
, multipart: opts.multipart // special property to be figured out by browser request code
}).then(function (result) {
@ -181,7 +201,6 @@ OAUTH3._pkgs['www@daplie.com'] = {
, session: session
}).then(function (result) {
// result.data
return result;
});
}

View File

@ -57,7 +57,7 @@
<span ng-bind="session.subject"></span>
<p class="text-muted small" ng-bind="session.issuer"></p>
<div class="divider"></div>
<button type="button" class="btn btn-default" disabled ng-if="vm.session.subject == session.subject">Current Profile</button>
<button type="button" class="btn btn-default" disabled ng-if="vm.session.subject == session.subject && vm.session.issuer == session.issuer">Current Profile</button>
</div>
</div>
</div>
@ -68,7 +68,7 @@
<a class="btn btn-default btn-sm" ng-click="vm.selectSession(session);">Use Account</a>
</div>
<div class="col-md-6">
<a class="btn btn-default btn-sm pull-right" ng-if="vm.session.subject == session.subject" ng-click="vm.signOut()">Sign Out</a>
<a class="btn btn-default btn-sm pull-right" ng-if="vm.session.subject == session.subject && vm.session.issuer == session.issuer" ng-click="vm.signOut()">Sign Out</a>
</div>
</div>
</div>

View File

@ -0,0 +1,2 @@
<h1>applications</h1>
<span class="text-danger">ps... you need a controller, nothing is hooked up.</span>

2
templates/devices.html Normal file
View File

@ -0,0 +1,2 @@
<h1>DEVICES</h1>
<span class="text-danger">ps... you need a controller, nothing is hooked up.</span>

View File

@ -1,35 +1,32 @@
<div class="panel panel-default">
<div class="panel-body">
<div class="media">
<h5 class="media-heading">System Message > <span ng-bind="vm.session.subject"></span></h5>
<hr>
<div class="media-left">
<div class="image-thing"><i class="fa fa-bullhorn fa-3x" aria-hidden="true"></i></div>
</div>
<div class="media-body">
<h3 class="media-heading">What to do?</h3>
<p>This is a prototype. It's essentially like a bunch of pictures that you can click through. You can type
in certain areas, but not all of the buttons "work". It's mostly just clickable "screenshots".</p>
<p>For this demo you are "Jane Smith".
As part of the setup for this device you chose
<a href="feed.html">https://jane.smith.net</a> as your personal page
and jane@smith.net as your messaging address.</p>
<p>Choose a few of these goals to "test out" in a few different ways:</p>
<ul>
<li>Share a photo with a family member</li>
<li>Send an email</li>
<li>Share a family vacation album with someone</li>
<li>Whatever reason you might have bought the Daplie personal server</li>
</ul>
<p>Your public feed is available at </p>
<div ng-controller="loginCtrl as vm" ng-init="vm.referrerInit()">
<referrer-notification></referrer-notification>
<div class="panel panel-default">
<div class="panel-body">
<div class="media">
<h5 class="media-heading">System Message > <span ng-bind="vm.session.subject"></span></h5>
<hr>
<div class="media-left">
<div class="image-thing"><i class="fa fa-bullhorn fa-3x" aria-hidden="true"></i></div>
</div>
<div class="media-body">
<h3 class="media-heading">What to do?</h3>
<p>This is a prototype. It's essentially like a bunch of pictures that you can click through. You can type in certain areas, but not all of the buttons "work". It's mostly just clickable "screenshots".</p>
<p>For this demo you are "Jane Smith".As part of the setup for this device you chose <a href="feed.html">https://jane.smith.net</a> as your personal page and jane@smith.net as your messaging address.</p>
<p>Choose a few of these goals to "test out" in a few different ways:</p>
<ul>
<li>Share a photo with a family member</li>
<li>Send an email</li>
<li>Share a family vacation album with someone</li>
<li>Whatever reason you might have bought the Daplie personal server</li>
</ul>
<p>Your public feed is available at </p>
</div>
</div>
</div>
</div>
<div class="panel-footer">
<div class="button-group flex-row space-around">
<button ng-click="vm.hide_welcome_msg = true" type="button" name="button" class="btn btn-default"><i class="fa fa-thumbs-up" aria-hidden="true"></i> Okay</button>
<div class="panel-footer">
<div class="button-group flex-row space-around">
<button ng-click="vm.hide_welcome_msg = true" type="button" name="button" class="btn btn-default"><i class="fa fa-thumbs-up" aria-hidden="true"></i> Okay</button>
</div>
</div>
</div>
</div>

View File

@ -1,64 +1,75 @@
<div class="side-menu">
<div class="button-container" ui-sref-active="active">
<a ui-sref=".home">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-home fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Home</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".bolt">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-bolt fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Bolt</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".contacts">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-users fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Contacts</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".files">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-file-text-o fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Files</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".music">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-music fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Music</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".email">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-envelope-o fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Email</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".website">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-globe fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Website</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".dns">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-connectdevelop fa-2x" aria-hidden="true"></i></button>
<p class="button-title">DNS</p>
</a>
</div>
<!--
<div class="button-container" ui-sref-active="active">
<a ui-sref=".sync">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-tablet fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Sync</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".photo">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-picture-o fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Photo</p>
</a>
</div>
-->
<div class="button-container" ui-sref-active="active">
<a ui-sref=".home">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-home fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Home</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".devices">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-desktop fa-2x" aria-hidden="true"></i></button>
<p class="button-title">devices</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".applications">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-th-large fa-2x" aria-hidden="true"></i></button>
<p class="button-title">apps</p>
</a>
</div>
<!--
<div class="button-container" ui-sref-active="active">
<a ui-sref=".bolt">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-bolt fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Bolt</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".contacts">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-users fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Contacts</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".files">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-file-text-o fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Files</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".music">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-music fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Music</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".email">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-envelope-o fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Email</p>
</a>
</div> -->
<div class="button-container" ui-sref-active="active">
<a ui-sref=".website">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-folder fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Shares</p>
</a>
</div>
<!-- <div class="button-container" ui-sref-active="active">
<a ui-sref=".dns">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-connectdevelop fa-2x" aria-hidden="true"></i></button>
<p class="button-title">DNS</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".sync">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-tablet fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Sync</p>
</a>
</div>
<div class="button-container" ui-sref-active="active">
<a ui-sref=".photo">
<button type="button" name="button" class="btn btn-default side-menu-button"><i class="fa fa-picture-o fa-2x" aria-hidden="true"></i></button>
<p class="button-title">Photo</p>
</a>
</div> -->
</div>

View File

@ -3,7 +3,7 @@
<h4 class="text-center">Sign in</h4>
<a href="#!/home" class="current-user-container" ng-repeat="profile in vm.Auth.sessions track by $index" ng-click="vm.selectSession(profile);">
<div class="current-user-split"><i class="fa fa-user"></i></div>
<div class="current-user-text">Resume with {{ profile.email }}</div>
<div class="current-user-text">Resume with {{ profile.email }} | {{ profile.issuer }}</div>
</a>
<div class="form-group">
<label for="dap-address">Address</label>

View File

@ -1,139 +1,259 @@
<style>
.panel{
box-shadow: none;
border: none;
}
</style>
<div class="home-container">
<div class="white-well">
<h1>Create a new Website</h1>
<h3>Select a Domain</h3>
<div class="input-group">
<input type="text" class="form-control" placeholder="www" ng-model="vm.newRecord" ng-change="vm.setRecord()" />
<div class="input-group-btn">
<!-- Single button -->
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li ng-repeat="record in vm.records track by $index"><button class="btn btn-link" ng-bind="record.sub" ng-click="vm.selectRecord(record)">www</button></li>
</ul>
</div>
</div>
<span class="input-group-addon">.</span>
<div angucomplete-alt
placeholder="Select a domain"
pause="300"
selected-object="vm.selectedDomain"
local-data="domain"
local-search="localDomainSearch"
title-field="domain"
minlength="0"
input-class="form-control trigger-dropdown"
match-class="highlight">
</div>
<!-- <input type="text" class="form-control" placeholder="Select a domain" aria-label="Domain Name" ng-model="vm.newDomain" ng-change="vm.setDomain()" /> -->
<div class="input-group-btn">
<div class="btn-group">
<button type="button" class="btn btn-default trigger-dropdown" aria-haspopup="true" aria-expanded="false" ng-click="vm.triggerDropdown()"><span class="caret"></span>
</button>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
<!--
Choose or create a public shared folder <button class="btn btn-default">Select Daplie Folder</button>
<br>
-->
<div class="input-group">
<div><label>Select .zip upload</label> <input type="file" ng-model="vm.newFile" daplie-file-change="vm.Sites.setUpload(vm)" /></div>
<div ng-if="vm.isZip" ><label><input type="checkbox" ng-model="vm.unzip" /> Unpack .zip</label></div>
<div ng-if="vm.unzip" ><label><input type="checkbox" ng-model="vm.stripZip" /> Strip zip directory root</label></div>
<!-- div ng-if="vm.isZip" ><label>Unzip directory</label> <input type="text" ng-model="vm.unzipPath" /></div -->
<div ng-if="vm.uploadTotal"><span ng-bind="vm.uploadPercent">99</span>% | <span ng-bind="vm.uploadProgress">1</span> MiB / <span ng-bind="vm.uploadTotal">100</span> MiB</div>
<div><label>Web path</label> <input type="text" ng-model="vm.uploadPath" /></div>
</div>
</div>
</div>
<!--
<div class="panel panel-default">
<div class="panel-body">
Who can edit and upload to this site? <input placeholder="Type contact name or email address" type="text" class="form-control">
</div>
</div>
-->
<!-- <div class="form-group">
<div class="pull-right"> -->
<button ng-click="vm.Sites.create()" type="button" name="button" class="btn btn-default">Create Website</button>
<!-- </div>
</div> -->
<div class="input-group">
<div><label>Invite Code</label> <input type="text" ng-model="vm.Shares.inviteToken" /></div>
<button ng-click="vm.Shares.accept()" type="button" name="button" class="btn btn-default">Accept Invite</button>
</div>
<div class="container" ng-init="vm.paramInit()">
<div class="row">
<notification-bar></notification-bar>
</div>
<div class="white-well">
<h1>Your Websites</h1>
<div ng-repeat="r in vm.sites">
<table class="table">
<tbody>
<tr>
<td>
<a ng-href="https://{{r.domain}}" target="_blank" ng-bind="r.domain">example.com</a>
<span ng-if="r.pending">(pending)</span>
<a ng-href="{{r.download}}" target="_blank">Download</a>
<!-- button class="btn btn-link" ng-click="vm.Sites.archive(r)">download</button -->
<button class="btn btn-link" ng-click="vm.Sites.remove(r, { path: '/', confirm: true })">Clear</button>
</td>
<td>
<input type="text" ng-model="r.newPath" placeholder="/" />
<button class="btn btn-default" ng-click="vm.Sites.contents(r)">List Files</button>
</td>
<td ng-bind="r.path">Sites > blogs > blog.jane.smith.net</td>
<td>
<div ng-repeat="share in r.sharedWith" ng-if="!share.me">
<span ng-bind="share.path">/</span>
<span ng-bind="share.comment">friend@email.com</span>
<em ng-if="share.pending">pending</em>
(<span ng-bind="share.mode">rwx</span>)
<button class="btn btn-link" ng-click="vm.Shares.remove(r, share)">[X]</button>
<div class="row">
<h1>Create Share</h1>
<button class="btn btn-primary btn-lg create-share-btn" title="..." data-toggle="modal" data-target=".create-website-modal">
Create Share
</button>
<hr>
<div class="modal fade create-website-modal" tabindex="-1" role="dialog" aria-labelledby="create-website-modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">Create a new Website</h4>
</div>
<div class="modal-body">
<h4>Select a domain</h4>
<div class="input-group">
<div angucomplete-alt
placeholder="Select a domain"
pause="300"
selected-object="vm.selectedDomain"
local-data="domain"
local-search="localDomainSearch"
title-field="domain"
minlength="0"
input-class="form-control trigger-dropdown"
match-class="highlight">
</div>
</td>
<td>
<input type="text" ng-model="r.shareEmail" placeholder="ex: john@example.com" />
<input type="text" ng-model="r.sharePath" placeholder="/" />
<input type="text" ng-model="r.shareMode" placeholder="rwx (read, write, invite)" />
<button class="btn btn-default" ng-click="vm.Shares.invite(r)">Invite</button>
<button class="btn btn-default" ng-click="vm.Shares.list(r)">List Shares</button>
</td>
</tr>
</tbody>
</table>
<div class="input-group">
<div><label>Select upload</label> <input type="file" ng-model="r.newFile" daplie-file-change="vm.Sites.setUpload(r)" /></div>
<!-- <input type="text" class="form-control" placeholder="Select a domain" aria-label="Domain Name" ng-model="vm.newDomain" ng-change="vm.setDomain()" /> -->
<div class="input-group-btn">
<div class="btn-group">
<button type="button" class="btn btn-default trigger-dropdown" aria-haspopup="true" aria-expanded="false" ng-click="vm.triggerDropdown()"><span class="caret"></span>
</button>
</div>
</div>
</div>
<div ng-if="r.isZip" ><label><input type="checkbox" ng-model="r.unzip" /> Unpack .zip</label></div>
<div class="input-group">
<input type="text" class="form-control" placeholder="www" ng-model="vm.newRecord" ng-change="vm.setRecord()" ng-blur="vm.setRecordDomain(vm.selectedDomain)" />
<div class="input-group-btn">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li ng-repeat="record in vm.records track by $index"><button class="btn btn-link" ng-bind="record.sub" ng-click="vm.selectRecord(record)">www</button></li>
</ul>
</div>
</div>
</div>
<div ng-if="r.unzip" ><label><input type="checkbox" ng-model="r.stripZip" /> Strip zip directory root</label></div>
<!-- div ng-if="vm.isZip" ><label>Unzip directory</label> <input type="text" ng-model="vm.unzipPath" /></div -->
<div ng-if="r.uploadTotal"><span ng-bind="r.uploadPercent">99</span>% | <span ng-bind="r.uploadProgress">1</span> MiB / <span ng-bind="r.uploadTotal">100</span> MiB</div>
<div><label>Web path</label> <input type="text" ng-model="r.uploadPath" /></div>
<button ng-click="vm.Sites.upload(r)" type="button" name="button" class="btn btn-default">Add File</button>
<div class="input-group">
<div>
<label>Select .zip upload</label>
<input type="file" ng-model="vm.newFile" class="form-control" daplie-file-change="vm.Sites.setUpload(vm.domain)" />
</div>
<div ng-if="vm.isZip" >
<label>
<input type="checkbox" ng-model="vm.unzip" />
Unpack .zip
</label>
</div>
<div ng-if="vm.unzip" >
<label>
<input type="checkbox" ng-model="vm.stripZip" />
Strip zip directory root
</label>
</div>
<!-- <div ng-if="vm.isZip" ><label>Unzip directory</label> <input type="text" ng-model="vm.unzipPath" /></div -->
<div ng-if="vm.uploadTotal">
<span ng-bind="vm.uploadPercent">99</span>% | <span ng-bind="vm.uploadProgress">1</span> MiB / <span ng-bind="vm.uploadTotal">100</span> MiB
</div>
<div>
<label>Web path</label>
<input type="text" class="form-control" ng-model="vm.uploadPath" />
</div>
<button ng-click="vm.Sites.create()" type="button" name="button" class="btn btn-default">Create Website</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" ng-click="vm.showSharesList = false; vm.showListFiles = false;">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="invite-card-container">
<div class="invite-option">
<h1>Enter Invite Code</h1>
<hr />
<input type="text" class="form-control" ng-model="vm.Shares.inviteToken" />
<hr />
<div class="price">
<div class="front">
<span class="price">&nbsp;</span>
</div>
<div class="">
<a class="btn btn-primary" ng-click="vm.Shares.accept()">Accept Invite</a>
</div>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="websites-tile">
<h1>Your Verified Websites</h1>
<ul class="cards">
<li class="cards__item" ng-repeat="r in vm.sites">
<div class="card">
<div class="card__image card__image--fence avoid-clicks">
<iframe ng-src="{{ r.urlSafeDomain }}" width="350" height="350"></iframe>
</div>
<div class="card__content">
<div class="card__title text-center"><a ng-href="https://{{ r.domain }}" target="_blank" ng-bind="r.domain">example.com</a></div>
<div class="cards__title text-center"><span ng-if="r.pending" class="text-muted">(pending)</span></div>
<button class="btn btn--block card__btn" data-toggle="modal" data-target=".{{ r.challenge }}" ng-click="vm.closeAllOpenActions(); vm.checkShareRights(r);">Edit</button>
</div>
</div>
</li>
</ul>
</div>
<div class="modal fade {{ r.challenge }}" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" ng-repeat="r in vm.sites">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" ng-click="vm.closeAllOpenActions()"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title"><a ng-href="https://{{ r.domain }}" target="_blank" ng-bind="r.urlSafeDomain">example.com</a></h4>
</div>
<div class="modal-body">
<notification-bar></notification-bar>
<div class="website-menu container" ng-hide="vm.websiteTiles">
<div class="row">
<div class="col-md-3">
<div class="square-service-block">
<a ng-click="vm.showAction('invite'); vm.closeFileUploadsContainers();" class="cp">
<div class="ssb-icon"><i class="fa fa-share-square-o" aria-hidden="true"></i></div>
<h2 class="ssb-title">Invite</h2>
</a>
</div>
</div>
<div class="col-md-3">
<div class="square-service-block">
<a ng-click="vm.showAction('shares'); vm.Shares.list(r); vm.closeFileUploadsContainers();" class="cp">
<div class="ssb-icon"> <i class="fa fa-list-alt" aria-hidden="true"></i> </div>
<h2 class="ssb-title">Shares</h2>
</a>
</div>
</div>
<div class="col-md-3">
<div class="square-service-block">
<a ng-click="vm.showAction('files'); vm.Sites.allContents(r); vm.cleanArrays(); vm.closeFileUploadsContainers();" class="cp trigger-files-list-refresh">
<div class="ssb-icon"><i class="fa fa-sitemap" aria-hidden="true"></i></div>
<h2 class="ssb-title">Files</h2>
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="square-service-block">
<a ng-href="https://{{ r.domain }}" target="_blank" class="cp">
<div class="ssb-icon"><i class="fa fa-globe" aria-hidden="true"></i></div>
<h2 class="ssb-title">Website</h2>
</a>
</div>
</div>
<div class="col-md-3">
<div class="square-service-block">
<a ng-click="vm.Sites.archive(r); vm.closeFileUploadsContainers();" class="cp">
<div class="ssb-icon"><i class="fa fa-file-archive-o" aria-hidden="true"></i></div>
<h2 class="ssb-title">Download</h2>
</a>
</div>
</div>
<div class="col-md-3">
<div class="square-service-block">
<a ng-click="vm.deleteWebsite(r, r); vm.closeFileUploadsContainers();" class="cp">
<div class="ssb-icon"><i class="fa fa-trash" aria-hidden="true"></i></div>
<h2 class="ssb-title">Delete</h2>
</a>
</div>
</div>
</div>
</div>
<div ng-show="vm.showInviteContainer">
<div ng-if="r.shareAccess.invite">
<h1><i class="fa fa-folder"></i> {{ vm.currentFolder | capitalize }}</h1>
<form class="form-horizontal">
<div class="form-group">
<label class="col-md-1 control-label" for="">To:</label>
<div class="col-md-8">
<input type="text" ng-model="r.shareEmail" class="form-control" placeholder="ex: john@example.com" />
<input type="hidden" ng-model="vm.autoPopulateWebPath" class="form-control" placeholder="/" disabled />
</div>
<div class="col-md-3">
<multiselect class="input-xlarge" multiple="true"
ng-model="selectedAccess"
options="c.name for c in accessLevel"
change="selected()"
ng-change="showShareBtn = true; vm.getSharedAccess(selectedAccess)">
</multiselect>
</div>
</div>
<div class="text-right" ng-show="showShareBtn">
<button type="submit" class="btn btn-success text-center" ng-click="vm.shareFolderFrom(r, opts)">Share</button>
</div>
</form>
</div>
<div ng-if="!r.shareAccess.invite">
<h3 class="text-muted">You do not have the correct permissions to invite or share files...</h3>
</div>
</div>
<div ng-show="vm.showSharesContainer">
<div class="text-center {{ vm.displaySpinner }}">
<i class="fa fa-spinner fa-spin fa-5x"></i>
</div>
<h3 class="text-muted text-center">{{ vm.notSharedMessage }}</h3>
<ul class="shares-container" ng-repeat="share in r.sharedWith" ng-if="!share.me">
<li>
<div class="media">
<div class="media-left align-self-center">
<img class="rounded-circle" src="http://s3.amazonaws.com/37assets/svn/765-default-avatar.png">
</div>
<div class="media-body">
<h4 ng-bind="share.comment">friend@email.com</h4>
<p><b>Share Path:</b> <span ng-bind="share.path" class="text-muted">/</span></p>
<p><b>Actions Allowed:</b> <span ng-bind="share.mode | prettyShareMode" class="text-muted">wrx</span></p>
<p><b>Invite:</b> <em ng-if="share.pending" class="text-muted">pending</em> <span ng-if="!share.pending" class="text-muted">Accepted</span></p>
</div>
<div class="media-right align-self-center">
<button ng-if="r.shareAccess.invite" class="btn btn-danger" ng-click="vm.Shares.remove(r, share)">Remove Access</button>
</div>
</div>
</li>
</ul>
</div>
<div ng-show="vm.showFilesContainer">
<file-tree r="r"></file-tree>
</div>
</div>
<div class="modal-footer ">
<button type="button" class="btn btn-primary pull-left" ng-show="vm.showBackBtn" ng-click="vm.closeAllOpenActions();">Back</button>
<button type="button" class="btn btn-default" data-dismiss="modal" ng-click="vm.closeAllOpenActions();">Close</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,89 @@
<div class="text-left" ng-hide="vm.displayFileTree">
<div class="row">
<ul class="breadcrumb">
<li ng-repeat="breadcrumb in vm.breadcrumbs track by $index" ng-click="vm.getDirectoriesFromBreadcrumbs(breadcrumb); vm.closeFileUploadsContainers();" data="{{ breadcrumb }}" class="cp breadcrumbs-list">
{{ breadcrumb | capitalize }}
</li>
</ul>
</div>
<div class="row">
<div class="col-lg-6">
<div class="text-center {{ vm.displaySpinner }}">
<i class="fa fa-spinner fa-spin fa-5x"></i>
</div>
<ul class="tree ls-none">
<li class="directories-go-here" ng-repeat="directory in vm.siteDirectories track by $index">
<input type="checkbox" id="{{ r.challenge }}{{ $index }}" />
<label class="tree_label" for="{{ r.challenge }}{{ $index }}" ng-click="vm.getDirectories(directory); vm.closeFileUploadsContainers();" data="{{ directory }}">{{ directory }}</label><span class="pull-right"><button ng-if="r.shareAccess.write" type="button" class="btn btn-danger btn-xs" ng-click="vm.deleteFilesFrom(r, directory); vm.closeFileUploadsContainers();" data="{{ directory }}" ><i class="fa fa-trash"></i></button></span>
</li>
</ul>
<ul class="tree files-only ls-none">
<li ng-repeat="file in vm.siteFiles track by $index">
<span class="tree_label filez">{{ file }}</span><span class="pull-right"><button ng-if="r.shareAccess.read" type="button" class="btn btn-default btn-xs" ng-click="vm.Sites.fileContents(file, r);" data="{{ file }}" ><i class="fa fa-code"></i></button> <button ng-if="r.shareAccess.write" type="button" class="btn btn-danger btn-xs" ng-click="vm.deleteFilesFrom(r, file); vm.closeFileUploadsContainers();" data="{{ file }}" ><i class="fa fa-trash"></i></button></span><br>
</li>
</ul>
<div class="folder-actions">
<hr>
<div>
<button ng-if="r.shareAccess.invite" type="button" name="button" class="btn btn-block btn-primary" ng-click="vm.showAction('invite');">Share folder</button>
<button type="button" name="button" class="btn btn-block btn-primary" ng-click="vm.Sites.archive(r)">Download folder</button>
<ul class="ls-none folder-actions-list">
<li ng-if="r.shareAccess.write"><span><i class="fa fa-upload cp"></i> <a ng-click="vm.autoPopulateFolderName(); vm.uploadFileContainer = true; vm.uploadFolderContainer = false; vm.cleanUploads(r);" class="cp">Upload files</a></span></li>
<li ng-if="r.shareAccess.write"><span><i class="fa fa-folder cp"></i> <a ng-click="vm.uploadFolderContainer = true; vm.uploadFileContainer = false; vm.cleanUploads(r);" class="cp">New folder</a></span></li>
<li ng-if="r.shareAccess.write"><span><i class="fa fa-trash cp"></i> <a ng-click="vm.triggerDeleteFolder(vm.currentFolder, r); vm.cleanUploads(r);" data="{{ vm.currentFolder }}" class="cp">Delete {{ vm.currentFolder | capitalize }} folder</a></span></li>
</ul>
</div>
</div>
<div class="upload-container">
<form ng-show="vm.uploadFileContainer">
<hr>
<div>
<input type="file" ng-model="r.newFile" class="form-control" daplie-file-change="vm.Sites.setUpload(r)" />
<div ng-if="!r.isZip"><label><input type="checkbox" ng-model="r.indexableFile" /> Indexable?</label></div>
<div ng-if="!r.isZip"><label><input type="checkbox" ng-model="r.publicFile" /> Public?</label></div>
<div ng-if="r.isZip"><label><input type="checkbox" ng-model="r.unzip" /> Unpack .zip</label></div>
<div ng-if="r.unzip"><label><input type="checkbox" ng-model="r.stripZip" /> Strip zip directory root</label></div>
<div ng-if="vm.isZip" ><label>Unzip directory</label> <input type="text" ng-model="vm.unzipPath" /></div>
<div ng-if="r.uploadTotal"><span ng-bind="r.uploadPercent">99</span>% | <span ng-bind="r.uploadProgress">1</span> MiB / <span ng-bind="r.uploadTotal">100</span> MiB</div>
<input type="text" class="form-control hidden" ng-model="vm.autoPopulateWebPath" placeholder="/js/config/config.js" disabled/>
<button ng-click="vm.Sites.upload(r)" type="button" name="button" class="btn btn-success" >Add File</button>
</div>
</form>
<form class="form-inline" ng-show="vm.uploadFolderContainer">
<hr>
<ul class="ls-none">
<li class="add-folder">
<span>
<i class="fa fa-folder"></i> <input type="text" class="form-control {{ vm.hideFolderInput }}" ng-model="vm.folderName" ng-blur="vm.createNewFolder(r);" style="width: 85%;"/>
<label>{{ vm.autoPopulateWebPath }}</label>
</span>
</li>
<li class="text-center">
<input type="file" ng-model="r.newFile" class="form-control" daplie-file-change="vm.Sites.setUpload(r)" />
<div ng-if="r.isZip"><label><input type="checkbox" ng-model="r.unzip" /> Unpack .zip</label></div>
<div ng-if="r.unzip"><label><input type="checkbox" ng-model="r.stripZip" /> Strip zip directory root</label></div>
<!-- div ng-if="vm.isZip" ><label>Unzip directory</label> <input type="text" ng-model="vm.unzipPath" /></div -->
<div ng-if="r.uploadTotal"><span ng-bind="r.uploadPercent">99</span>% | <span ng-bind="r.uploadProgress">1</span> MiB / <span ng-bind="r.uploadTotal">100</span> MiB</div>
</li>
<li>
<button ng-click="vm.Sites.upload(r)" type="button" name="button" class="btn btn-success">Add File</button>
</li>
</ul>
</form>
</div>
</div>
<div class="col-lg-6">
<pre style="font-size: 10px;">
<div class="text-center {{ vm.displaySpinner }}">
<i class="fa fa-spinner fa-spin fa-5x"></i>
</div>
{{ vm.folderStructure | stringify }}
</pre>
</div>
</div>
<div class="row">
<div class="padding-side-15">
<button ng-if="r.shareAccess.write" type="button" class="btn btn-danger pull-right" ng-click="vm.removeAllFiles(r, opts)"><i class="fa fa-trash"></i> Remove all Files</button>
</div>
</div>
</div>

View File

@ -0,0 +1,9 @@
<div class="referrer-modal {{ vm.hideReferrerNotification }}">
<div class="referrer-pop-up">
<h4>{{ vm.referrerAlert.title }}</h4>
<p>{{ vm.referrerAlert.msg }}</p>
<a class="btn btn-danger close-referrer-pop-up" ng-click="vm.closeReferrerModal()">Close</a>
<a class="btn btn-default" ng-click="vm.closeReferrerModal()">Maybe later</a>
<a class="btn btn-success" ng-click="vm.sendToShares()">Do it now</a>
</div>
</div>

View File

@ -0,0 +1,20 @@
<div class="dropdown">
<button class="btn" ng-click="toggleSelect()" ng-disabled="disabled" ng-class="{ 'error': !valid() }">
<span class="pull-left">{{ header }}</span>
<span class="caret pull-right"></span>
</button>
<ul class="dropdown-menu">
<li class="hidden">
<input class="input-block-level" type="text" ng-model="searchText.label" autofocus="autofocus" placeholder="Filter" />
</li>
<li ng-show="multiple" class="">
<button class="btn-link btn-small" ng-click="checkAll()"><i class="icon-ok"></i> Check all</button>
<button class="btn-link btn-small" ng-click="uncheckAll()"><i class="icon-remove"></i> Uncheck all</button>
</li>
<li role="separator" class="divider"></li>
<li ng-repeat="i in items | filter:searchText">
<a ng-click="select(i); focus()">
<i ng-class="{ 'icon-ok': i.checked, 'icon-empty': !i.checked }"></i> {{ i.label }}</a>
</li>
</ul>
</div>

View File

@ -0,0 +1,6 @@
<div class="error-notice">
<div class="oaerror {{ vm.alertNotification.className }} {{ vm.alertNotification.hidden }}">
<strong>{{ vm.alertNotification.title }}</strong> - {{ vm.alertNotification.message }}
<button type="button" class="close" ng-click="vm.alertNotification.hidden = 'hidden'"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
</div>
</div>