diff --git a/bin/backup_omva.sh b/bin/backup_omva.sh index 5a02d24..bba299f 100755 --- a/bin/backup_omva.sh +++ b/bin/backup_omva.sh @@ -1,25 +1,68 @@ #!/bin/bash # Backup script for the OpenManage Virtual Appliance. -# Today: Generates a tarball with the important-to-backup data. -# Tomorrow: This will eventually send the tarball automatically for secure offsite backup. + +if [ "$EUID" -ne 0 ] + then echo "Please run as root" + exit +fi . /etc/default/openmanage -backup_workspace=$HOME/omva-backup -backup_date=`date -u +%Y%m%d_%H%M` -# Stage one: prepare the destination -mkdir -p $backup_workspace +BACKUP_HASH_FILE=$OPENMANAGE_ROOT/.backup_hashes + +lock() { + exec 200>/var/lock/.myscript.exclusivelock + + flock -n 200 \ + && return 0 \ + || return 1 +} + +eexit() { + local error_str="$@" + + echo $error_str + exit 1 +} -# Stage two: Collect the trivial stuff. -cp $OPENMANAGE_CONFIGDIR/agent_config.json $backup_workspace -cp -r $SPIDEROAK_ESCROW_KEYS_PATH $backup_workspace -cp -r $SPIDEROAK_ESCROW_LAYERS_PATH $backup_workspace +set_current_values() { + md5=($(md5sum $OPENMANAGE_ROOT/etc/agent_config.json)) + echo "export AGENT_CONFIG_MD5=$md5" > $BACKUP_HASH_FILE + md5=($(echo "select datname, tup_inserted, tup_updated, tup_deleted from pg_stat_database where datname='openmanage';" | sudo -u postgres psql openmanage | md5sum)) + echo "export DB_MD5=$md5" >> $BACKUP_HASH_FILE +} -# Stage three: collect the DB contents. -su postgres -c "pg_dump openmanage" > $backup_workspace/db_dump.sql +need_backup() { + if ! [ -a $BACKUP_HASH_FILE ] + then + set_current_values + echo "Backup needed." + return 0 + fi + . $BACKUP_HASH_FILE + md5=($(md5sum $OPENMANAGE_ROOT/etc/agent_config.json)) + if [ $AGENT_CONFIG_MD5 != $md5 ] + then + echo "agent_config doesn't match last backup. Backup needed." + return 0 + fi + md5=($(echo "select datname, tup_inserted, tup_updated, tup_deleted from pg_stat_database where datname='openmanage';" | sudo -u postgres psql openmanage | md5sum)) + if [ $DB_MD5 != $md5 ] + then + echo "Database doesn't match last backup. Backup needed." + return 0 + fi + return 1 +} -pushd $HOME -tar czf $HOME/omva-backup-$backup_date.tar.gz ./omva-backup -rm -r $backup_workspace -popd +main() { + lock || eexit "Script is already running. Exiting..." + need_backup || eexit "Nothing has changed since last backup. Exiting..." + number=$(( ( RANDOM % 45 ) + 1 )) + echo "sleeping for $number minutes to spread out backups" + sleep ${number}m + set_current_values + python $OPENMANAGE_ROOT/bin/update_backup.py +} +main diff --git a/bin/create_backup.sh b/bin/create_backup.sh new file mode 100755 index 0000000..07d4bad --- /dev/null +++ b/bin/create_backup.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. /etc/default/openmanage + +CURRENT_DATE=$1 + +BACKUP_BASE=$OPENMANAGE_ROOT/tmp_backup +BACKUP_DIR=openmanage-backup-$CURRENT_DATE +BACKUP_BZ2=openmanage-backup-$CURRENT_DATE.tar.bz2 + +rm -rf $BACKUP_BASE +mkdir $BACKUP_BASE +cd $BACKUP_BASE +mkdir $BACKUP_DIR + +cp -r $SPIDEROAK_ESCROW_LAYERS_PATH $BACKUP_DIR +cp -r $SPIDEROAK_ESCROW_KEYS_PATH $BACKUP_DIR +cp $OPENMANAGE_CONFIGDIR/agent_config.json $BACKUP_DIR +sudo -u postgres pg_dump openmanage > $BACKUP_DIR/openmanage.sql + +tar cjf $BACKUP_BZ2 $BACKUP_DIR diff --git a/bin/first_setup.sh b/bin/first_setup.sh index 7320600..e675e71 100755 --- a/bin/first_setup.sh +++ b/bin/first_setup.sh @@ -1,6 +1,7 @@ #!/bin/bash -if [ -e ~/.ran_firstsetup ]; then +if [ -e /opt/openmanage/etc/.ran_firstsetup ]; then + echo "Keys already generated. Exiting" exit 0 fi @@ -15,10 +16,6 @@ if [ ! -f /var/lib/openmanage/keys/base.cfg ]; then $OPENMANAGE_ROOT/bin/make_keys.sh $OPENMANAGE_BRAND fi -#sudo mkdir -p /etc/service/openmanage/supervise -#sudo ln -s $OPENMANAGE_ROOT/etc/service/openmanage/run /etc/service/openmanage/run -#sudo sv start openmanage - -touch ~/.ran_firstsetup +touch /opt/openmanage/etc/.ran_firstsetup echo "finished" diff --git a/bin/gather_logs.sh b/bin/gather_logs.sh index 57396d6..7ad0784 100755 --- a/bin/gather_logs.sh +++ b/bin/gather_logs.sh @@ -6,6 +6,7 @@ LOG_BASE=/opt/openmanage/tmp_logs LOG_DIR=$LOG_BASE/openmanage-logs-$CURRENT_DATE LOG_BZ2=$LOG_BASE/openmanage-logs-$CURRENT_DATE.tar.bz2 +rm -rf $LOG_BASE mkdir $LOG_BASE mkdir $LOG_DIR @@ -13,6 +14,3 @@ cp -r /var/log/admin_console/ $LOG_DIR cp -r /var/log/omva/ $LOG_DIR tar cjf $LOG_BZ2 $LOG_DIR - -#rm -rf $LOG_DIR -#rm -rf $LOG_BZ2 diff --git a/bin/resources/recreate_openmanage.sql b/bin/resources/recreate_openmanage.sql new file mode 100644 index 0000000..cde3f85 --- /dev/null +++ b/bin/resources/recreate_openmanage.sql @@ -0,0 +1,10 @@ +SELECT + pg_terminate_backend (pg_stat_activity.procpid) +FROM + pg_stat_activity +WHERE + pg_stat_activity.datname = 'openmanage' + and procpid != pg_backend_pid() +; +drop database openmanage; +create database openmanage; diff --git a/bin/restore_backup.py b/bin/restore_backup.py new file mode 100644 index 0000000..08701e4 --- /dev/null +++ b/bin/restore_backup.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python + +import os +import datetime +from hashlib import sha256 +import subprocess +from binascii import a2b_base64 +import bcrypt +import nacl.secret + +from netkes import common +from netkes.account_mgr.accounts_api import Api + +config = common.read_config_file() + +api = Api.create( + config["api_root"], + config["api_user"], + config["api_password"], +) + +def create_secret_box(password, username): + key = bcrypt.kdf( + password.encode('utf-8'), + username, + nacl.secret.SecretBox.KEY_SIZE, + 100, + ) + + nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE) + return nacl.secret.SecretBox(key), nonce + +secret_box, nonce = create_secret_box(config['api_password'], config['api_user']) + +date = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') +filename = 'openmanage-backup-%s.tar.bz2' % date +path = '/opt/openmanage/tmp_backup/%s' % filename + +backup = api.backup() + +data = a2b_base64(backup['data']) +data = secret_box.decrypt(data) + +with open(path, 'w') as f: + f.write(data) + +subprocess.call(['/opt/openmanage/bin/restore_omva.sh', path]) diff --git a/bin/restore_omva.sh b/bin/restore_omva.sh old mode 100644 new mode 100755 index 783ceea..2546c51 --- a/bin/restore_omva.sh +++ b/bin/restore_omva.sh @@ -6,29 +6,40 @@ . /etc/default/openmanage +set -x + # Stage Zero: Sanity-check the tarball -file $1 | grep 'gzip compressed data' 2>&1 1>/dev/null +file $1 | grep 'bzip2 compressed data' 2>&1 1>/dev/null if [ $? != 0 ]; then echo "Backup argument $1 not showing as a tarball properly. Aborting." >&2 exit fi # Stage One: Unzip the tarball. -tar xzf $1 -pushd omva-backup +BACKUP_BASE=$OPENMANAGE_ROOT/tmp_backup + +cd $BACKUP_BASE + +tar xjfv $1 +pushd openmanage-backup* # Stage Two: move the configuration and keys back into place. mkdir -p $SPIDEROAK_ESCROW_KEYS_PATH mkdir -p $SPIDEROAK_ESCROW_LAYERS_PATH -cp -r omva-backup/keys/* $SPIDEROAK_ESCROW_KEYS_PATH -cp -r omva-backup/layers/* $SPIDEROAK_ESCROW_LAYERS_PATH +cp -r keys/* $SPIDEROAK_ESCROW_KEYS_PATH +cp -r layers/* $SPIDEROAK_ESCROW_LAYERS_PATH -cp agent-config.json $OPENMANAGE_CONFIGDIR +cp agent_config.json $OPENMANAGE_CONFIGDIR # Stage Three: Re-load the DB SQL. -su postgres -c "psql -f db_dump.sql openmanage" +sudo -u postgres psql -f /opt/openmanage/bin/resources/recreate_openmanage.sql +sudo -u postgres psql --single-transaction --pset pager=off -f openmanage.sql openmanage + +# We already have keys so we don't need to run first setup +touch /opt/openmanage/etc/.ran_firstsetup # Clean up. popd -rm -r omva-backup +rm -r openmanage-backup* +sudo sv restart admin_console diff --git a/bin/run_restore_omva.sh b/bin/run_restore_omva.sh new file mode 100755 index 0000000..3ad815c --- /dev/null +++ b/bin/run_restore_omva.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Backup script for the OpenManage Virtual Appliance. + +if [ "$EUID" -ne 0 ] + then echo "Please run as root" + exit +fi + +. /etc/default/openmanage + +BACKUP_BASE=$OPENMANAGE_ROOT/tmp_backup + +rm -rf $BACKUP_BASE +mkdir $BACKUP_BASE + + +python $OPENMANAGE_ROOT/bin/restore_backup.py diff --git a/bin/set_version.py b/bin/set_version.py new file mode 100644 index 0000000..318c658 --- /dev/null +++ b/bin/set_version.py @@ -0,0 +1,18 @@ +import sys +from netkes import common +from netkes.account_mgr.accounts_api import Api + +config = common.read_config_file() + +if len(sys.argv) != 2: + print "version is required" + print "python set_version.py 1.2.3" + sys.exit(0) + +if config['api_password']: + api = Api.create( + config["api_root"], + config["api_user"], + config["api_password"], + ) + api.update_enterprise_settings(dict(api_version=sys.argv[1])) diff --git a/bin/update_backup.py b/bin/update_backup.py new file mode 100644 index 0000000..1b052e2 --- /dev/null +++ b/bin/update_backup.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +import os +import datetime +from hashlib import sha256 +import subprocess +from binascii import b2a_base64 + +os.environ['DJANGO_SETTINGS_MODULE'] = 'omva.settings' + +from openmanage.views import create_secret_box +from netkes import common +from netkes.account_mgr.accounts_api import Api + +config = common.read_config_file() + +# Only back up active vms. If no one has claimed the vm there's +# nothing to back up. +if config['api_password']: + api = Api.create( + config["api_root"], + config["api_user"], + config["api_password"], + ) + + secret_box, nonce = create_secret_box(config['api_password'], config['api_user']) + + date = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + filename = 'openmanage-backup-%s.tar.bz2' % date + path = '/opt/openmanage/tmp_backup/%s' % filename + + subprocess.call(['/opt/openmanage/bin/create_backup.sh', date]) + + with open(path) as f: + data = secret_box.encrypt(f.read(), nonce) + data = b2a_base64(data) + + backup = { + 'sha256': sha256(data).hexdigest(), + 'data': data, + } + + api.update_backup(backup) diff --git a/deploy/make_tarball.sh b/deploy/make_tarball.sh index e4731e4..462edb2 100755 --- a/deploy/make_tarball.sh +++ b/deploy/make_tarball.sh @@ -46,7 +46,7 @@ mkdir $buildit_dir mkdir $buildit_dir/bin find $source_dir/bin/*.pyc -delete 2> /dev/null || true # hack to make pipefail not fail -cp $source_dir/bin/* $buildit_dir/bin +cp -r $source_dir/bin/* $buildit_dir/bin # Copy libraries cp -r $source_dir/netkes $buildit_dir @@ -65,6 +65,10 @@ popd > /dev/null #$buildit_dir/django # Copy over the upgrades cp -r $source_dir/upgrade $buildit_dir +# Copy keys +mkdir $buildit_dir/upgrade/keys +cp $management_files/server.* $buildit_dir/upgrade/keys + # Setup the SQL package mkdir $buildit_dir/sql cp $source_dir/sql/*.sql $buildit_dir/sql @@ -94,7 +98,7 @@ echo echo Making tarball... echo pushd $deploy_dir > /dev/null -tar cjf openmanage-$version.tar.bz2 openmanage +tar cjf openmanage-$version.tar.bz2 openmanage-$version popd > /dev/null echo Done setting up! diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/500.html b/django/apps/blue_management/blue_mgnt/mako_templates/500.html deleted file mode 100644 index 59fd4d6..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/500.html +++ /dev/null @@ -1 +0,0 @@ -Error diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/admin_groups.html b/django/apps/blue_management/blue_mgnt/mako_templates/admin_groups.html deleted file mode 100644 index 2bc16cd..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/admin_groups.html +++ /dev/null @@ -1,116 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Admin Groups - ${parent.title()} - -<%def name="head()"> - - - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">admin_groups ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
- -% if saved: - -% endif -
-
-

Create New Admin Group

-
- - - %for field in new_admin_group.visible_fields(): - - - %endfor - - -
- ${field.label_tag()} - ${field} - %if field.errors: -
- %for error in field.errors: - - ${error} - - %endfor - %endif -
- -
- - %for hidden in new_admin_group.hidden_fields(): - ${hidden} - %endfor -
-
-
-

Admin Groups

-
-${admin_groups.management_form} - - - - - - - - - - - % if admin_groups.non_form_errors(): - - % endif - % for form in admin_groups.forms: - - % for x, field in enumerate(form.visible_fields()): - - % endfor - - % endfor - -
NameLDAP DNPermissionsDelete Group
${admin_groups.non_form_errors()}
- % if not x: - % for hidden in form.hidden_fields(): - ${hidden} - % endfor - % endif - % if field.name == 'DELETE': - ${field} - % else: - ${field} - %if field.errors: -
- %for error in field.errors: - - ${error} - - %endfor - %endif - %endif -
-
- - -
-
-
- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/authcodes.html b/django/apps/blue_management/blue_mgnt/mako_templates/authcodes.html deleted file mode 100644 index 125b6d6..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/authcodes.html +++ /dev/null @@ -1,114 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Auth Codes - ${parent.title()} - -<%def name="head()"> - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">auth_codes ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
-
-
-

Create New Setup Code

-
- - - %for field in new_code.visible_fields(): - - - %endfor - - -
- ${field.label_tag()} - ${field} - %if field.errors: -
- %for error in field.errors: - - ${error} - - %endfor - %endif -
- -
- - %for hidden in new_code.hidden_fields(): - ${hidden} - %endfor -
-
-
-

Auth Codes

- - - ${'Hide Inactive' if show_inactive else 'Show Inactive'} - - - - - - - - - - - - - - - % for code in codes: - - - - - - - - - - % endfor - -
TokenCreatedExpiresSingle Use OnlyNo Devices OnlyUsed
${code.token}${code.date_created.strftime('%Y-%m-%d %H:%M:%S')}${code.expiry.strftime('%Y-%m-%d %H:%M:%S')}${code.no_devices_only}${code.single_use_only}${code.used} - % if code.active: -
- - - -
- % endif -
- -
- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/base.html b/django/apps/blue_management/blue_mgnt/mako_templates/base.html deleted file mode 100644 index 7451a5d..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/base.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - <%def name="top_of_head()"> - ${self.top_of_head()} - - <%def name="title()">SpiderOak:Blue - ${self.title()} - <%def name="icon()"> - <%def name="meta_description()"> - - <%def name="meta_keywords()"> - - <%def name="meta_bots()">noindex, nofollow - - - <%def name="base_styles()"> - - - - - ${self.base_styles()} - <%def name="styles()"> - ${self.styles()} - - <%def name="jquery()"> - - - ${self.jquery()} - - - - - - - - ${next.head()} - - -<%def name="img_path()">/static/v0.1/images/index/ -<%def name="body_classes()"> - -<%def name="top_of_body()"> - -${self.top_of_body()} -
- - <%def name="progressbar()"> - - - -
-
-
-
- - <%def name="join_button()"> -
- -
- - <%def name="videotutorials_button()"> -
- -
- - <%def name="container()"> - - ${next.body()} - - - ${self.container()} -
- -${next.scripts()} - - -<%def name="bottom_of_body()"> - -${self.bottom_of_body()} - - - diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/blue_stuff.html b/django/apps/blue_management/blue_mgnt/mako_templates/blue_stuff.html deleted file mode 100644 index 3b3d88b..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/blue_stuff.html +++ /dev/null @@ -1,5 +0,0 @@ -<%inherit file="business.html" /> - -<%def name="body_classes()">home ${parent.body_classes()} -

Hello World

- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/business.html b/django/apps/blue_management/blue_mgnt/mako_templates/business.html deleted file mode 100644 index a50dda8..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/business.html +++ /dev/null @@ -1,36 +0,0 @@ -<%inherit file="base.html" /> - -<%def name="navigation()"> - - SpiderOak - - - -<%def name="head()">${next.head()} -<%def name="scripts()">${next.scripts()} -<%def name="title()">${parent.title()} -<%def name="body_classes()">${parent.body_classes()} -<%def name="meta_keywords()">${parent.meta_keywords()} - -${next.body()} diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/csv.html b/django/apps/blue_management/blue_mgnt/mako_templates/csv.html deleted file mode 100644 index d072905..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/csv.html +++ /dev/null @@ -1,37 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">SpiderOak Online Backup and Sync White Label Program - ${parent.title()} - -<%def name="head()"> - -<%def name="top_of_head()"> - - - - -<%def name="scripts()"> - - - -<%def name="body_classes()">csv ${parent.body_classes()} grassy - -
- Logout -
- -

CSV Format

- -email_addr: required - The user's current email address. This uniquely identifies the user.
-new_email: optional - This email must be available (not be in use by another SpiderOak user).
-given_name: optional - Must be between 1 and 45 characters.
-surname: optional - Must be between 1 and 45 characters.
-group_id: optional - Must match an existing group.
- -

-

Example CSV File

- -email_addr,given_name,surname,group_id,new_email
-so+1@spideroak.com,,,10,
-so+2@spideroak.com,b,c,,
-so+3@spideroak.com,d,d,5,so+4@spideroak.com
diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/features.html b/django/apps/blue_management/blue_mgnt/mako_templates/features.html deleted file mode 100644 index 8192233..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/features.html +++ /dev/null @@ -1,42 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Features - ${parent.title()} - -<%def name="head()"> - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">udetail ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
-% if saved: -

Changes saved successfully!

-% endif - -
-
-

- Features -

- - ${form.as_table()} -
- -
- - -
- - - diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/groups.html b/django/apps/blue_management/blue_mgnt/mako_templates/groups.html deleted file mode 100644 index 5f1653e..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/groups.html +++ /dev/null @@ -1,208 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Groups - ${parent.title()} - -<%def name="head()"> - - - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">groups ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
- -% if saved and not search_back: - -% endif -
-% if user.has_perm('blue_mgnt.can_manage_groups'): -
-

Create New Group

-
- - - %for field in new_group.visible_fields(): - - - %endfor - - -
- ${field.label_tag()} - ${field} - %if field.errors: -
- %for error in field.errors: - - ${error} - - %endfor - %endif -
- -
- - %for hidden in new_group.hidden_fields(): - ${hidden} - %endfor -
-
- -%if 1 or not features['ldap']: -
-

Delete Group

-
- - % if delete_group.non_field_errors(): - - % endif - - - %for field in delete_group.visible_fields(): - - %endfor - - -
${delete_group.non_field_errors()}
- ${field.label_tag()} - ${field} - - -
- - %for hidden in new_group.hidden_fields(): - ${hidden} - %endfor -
-
- - -%endif -%endif -
-

Groups

- -
-${groups.management_form} - - - - % if config['enable_local_users']: - - % endif - - - - % if features['ldap']: - - - % endif - - - - - % if groups.non_form_errors(): - - % endif - % for y, form in enumerate(groups.forms): - - % if config['enable_local_users']: - - % endif - % for x, field in enumerate(form.visible_fields()): - - % endfor - - % endfor - -
User SourceNamePlanAllow WebAPIRequire Domain for Windows InstallLDAP DNPriority
${groups.non_form_errors()}
${initial[y]['user_source']} - % if not x: - % for hidden in form.hidden_fields(): - ${hidden} - % endfor - % endif - % if field.name == 'DELETE': - ${field} - % else: - ${field} - %if field.errors: -
- %for error in field.errors: - - ${error} - - %endfor - %endif - % endif -
-
- % if user.has_perm('blue_mgnt.can_manage_groups'): - - % if show_force: - - % endif - - - % endif -
-
-
- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/index.html b/django/apps/blue_management/blue_mgnt/mako_templates/index.html deleted file mode 100644 index f81fcfd..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/index.html +++ /dev/null @@ -1,99 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Management Console - ${parent.title()} - -<%def name="head()"> -<%def name="scripts()"> - - - - -<%def name="body_classes()">home ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
- - - -
-
- -
-
-
- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/login.html b/django/apps/blue_management/blue_mgnt/mako_templates/login.html deleted file mode 100644 index 99b07e2..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/login.html +++ /dev/null @@ -1,62 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Login - ${parent.title()} - -<%def name="head()"> - - - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - -<%def name="body_classes()">login ${parent.body_classes()} -<%def name="container()"> -

 

-
-
-
-

Log In

-
-
- - % if form.non_field_errors(): - - % endif - %for field in form: - - - - %if field.errors: - %for error in field.errors: - ${error} - %endfor - %else: - - %endif - - - %endfor -
${form.non_field_errors()}
-
- ${field.label_tag()} -
- ${field} -
-
- -
-
- - -
- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/logs.html b/django/apps/blue_management/blue_mgnt/mako_templates/logs.html deleted file mode 100644 index 184d61a..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/logs.html +++ /dev/null @@ -1,65 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Logs - ${parent.title()} - -<%def name="head()"> - - - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">logs ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
- -
-

Logs

- - - - - - - - - % for log in log_entries: - - - - % endfor - -
Log
- ${log} -
- -
- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/main.html b/django/apps/blue_management/blue_mgnt/mako_templates/main.html deleted file mode 100644 index b17c23c..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/main.html +++ /dev/null @@ -1,10 +0,0 @@ -<%inherit file="business.html" /> - -<%def name="head()"> - ${next.head()} - - -<%def name="scripts()">${next.scripts()} - -<%def name="body_classes()">enterprise_mgnt partners ${parent.body_classes()} -${next.body()} diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/old_index.html b/django/apps/blue_management/blue_mgnt/mako_templates/old_index.html deleted file mode 100644 index f38a145..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/old_index.html +++ /dev/null @@ -1,203 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">SpiderOak Online Backup and Sync White Label Program - ${parent.title()} - -<%def name="head()"> - -<%def name="top_of_head()"> - - - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">home ${parent.body_classes()} grassy - -
- Logout -
- -

Enterprise Partner: ${user.username}

- -Promo Code: ${promo} - -% if saved: -
Changes saved successfully!
-% endif - -
-

Options

-
-
- %for field in options: -
- ${field.label_tag()} -
- ${field} - - %if field.errors: - %for error in field.errors: - ${error} - %endfor - %else: - - %endif - - -
-
- %endfor -
-
-% if features.group_permissions: - ${groups.management_form} -

Groups

- - - - - - - - - - - - % for form in groups.forms: - - - % for x, field in enumerate(form.visible_fields()): - - % endfor - - % endfor - -
Group IDPlanAllow WebAPIRequire Domain for Windows InstallDelete Group
${form.initial.get('group_id', '')} - % if not x: - % for hidden in form.hidden_fields(): - ${hidden} - % endfor - % endif - ${field} -
- -% endif -% if features.signup_restrictions: - ${ip_blocks.management_form} -

Consumer Signup Restriction Netblocks

- - - - - - - - - - % for y, form in enumerate(ip_blocks.forms): - - - % for x, field in enumerate(form.visible_fields()): - - % endfor - - % endfor - -
IP Block IDIP BlockDelete IP Block
${form.initial.get('id', '')} - % if not x: - % for hidden in form.hidden_fields(): - ${hidden} - % endfor - % endif - ${field} - ${field.errors} -
- -

-% endif - - -
-

Change Password

-
-
- %for field in password_form: -
- ${field.label_tag()} -
- ${field} - - %if field.errors: - %for error in field.errors: - ${error} - %endfor - %else: - - %endif - - -
-
- %endfor -
- - -
diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/password.html b/django/apps/blue_management/blue_mgnt/mako_templates/password.html deleted file mode 100644 index 441b779..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/password.html +++ /dev/null @@ -1,85 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Settings - ${parent.title()} - -<%def name="head()"> - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">password ${parent.body_classes()} grassy -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
-
-% if saved: -

Changes saved successfully!

-% endif -
-

Change Password

-
-
- - %for field in password_form: - - %if field.errors: - - %for error in field.errors: - ${error} - %endfor - %else: - - - %endif - %endfor -
- ${field.label_tag()} - - ${field} -
-
- - -
-
- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/settings.old b/django/apps/blue_management/blue_mgnt/mako_templates/settings.old deleted file mode 100644 index e8611d6..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/settings.old +++ /dev/null @@ -1,179 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Settings - ${parent.title()} - -<%def name="head()"> - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">settings ${parent.body_classes()} grassy -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
- ${parent.progressbar()} -
- -% if saved: -

Changes saved successfully!

-% endif - - % if not features['ldap']: -
- % else: -
- % endif -
-

Options

-
-
- - %for field in options: - - - - - %endfor -
-
- ${field.label_tag()} -
-
- ${field} - %if field.errors: - %for error in field.errors: - - ${error} - - %endfor - %endif -
-
-
- % if user.has_perm('blue_mgnt.can_manage_settings'): - - % endif -
-
- -
-
- -
-Change Password -% if features['ldap'] and user.has_perm('blue_mgnt.can_manage_settings'): -
- - -
-
- ${command_output} -
-
- - -
-
- - -
-
- - -
-% endif -
- - - -% if not private_cloud: -
-
- ${ip_blocks.management_form} -

Consumer Signup Restriction Netblocks - -

-
- - - - - - - - - % for y, form in enumerate(ip_blocks.forms): - - % for x, field in enumerate(form.visible_fields()): - - % endfor - - % endfor - -
IP BlockDelete IP Block
- % if not x: - % for hidden in form.hidden_fields(): - ${hidden} - % endfor - % endif - ${field} - %if field.errors: -
- %for error in field.errors: - - ${error} - - %endfor - %endif -
- -
- % if user.has_perm('blue_mgnt.can_manage_settings'): - - % endif -
-
-
- -% endif - - -
- - diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/shares.html b/django/apps/blue_management/blue_mgnt/mako_templates/shares.html deleted file mode 100644 index 7da740b..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/shares.html +++ /dev/null @@ -1,124 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Shares - ${parent.title()} - -<%def name="head()"> - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">shares ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
-
-
-

Shares

-
- - - - - % if features['email_as_username']: - - % else: - - % endif - - - - - % for user in users: - - - % if features['email_as_username']: - - % else: - - % endif - - - - % endfor - -
NameEmailUsernameShares
${user['name']}${user['email']}${user['username']}${len(user['shares'])}
- - - - - - - - - - - - - - % for share in user['shares']: - - - - - - - - - - % endfor - -
NameRoom KeyURLDescriptionCreation TimeUpdate Time
${share['name']}${share['room_key']} - - ${share_url}/browse/share/${user['share_identifier']}/${share['room_key']} - ${share['description'] if share['description'] else ''}${datetime.datetime.fromtimestamp(share['creation_time'])}${datetime.datetime.fromtimestamp(share['update_time'])} - - - - - - - -
-
- - -
-
- - - -
-
-
- diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/user_detail.html b/django/apps/blue_management/blue_mgnt/mako_templates/user_detail.html deleted file mode 100644 index 6d77032..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/user_detail.html +++ /dev/null @@ -1,205 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Users - ${parent.title()} - -<%def name="head()"> - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">udetail ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
-% if saved: -

Changes saved successfully!

-% endif - -
-
-

- User Details -

-
-
- - % if not features['email_as_username']: - - - - - % endif - % for field in user_form: - - - - - % endfor - - - - - - - - - - - - - - - - - - - - - - % if devices: - - % endif - % for device in devices: - - - - - - - - - - - - - - - - - - - - - - - - - % endfor - % if shares: - - % for share in shares: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % endfor - % endif -
${api_user['username']}
-
- ${field.label_tag()} -
-
- ${field} - %if field.errors: -
- %for error in field.errors: - - ${error} - - %endfor - %else: - - %endif -
${api_user['num_devices']}
${round(api_user['bytes_stored'] / (10.0 ** 9), 2)}
${api_user['storage_bytes'] / (10 ** 9)}
${datetime.datetime.fromtimestamp(api_user['creation_time'])}
${datetime.datetime.fromtimestamp(api_user['last_login']) if api_user['last_login'] else ''}
- - - -

Devices

${device['device_id']}
${device['name']}
${datetime.datetime.fromtimestamp(device['creation_time'])}
- % if device['reinstalled']: - ${datetime.datetime.fromtimestamp(device['reinstalled'])} - % endif -
- % if device['last_login']: - ${datetime.datetime.fromtimestamp(device['last_login'])} - % endif -
- % if device['last_backup_complete']: - ${datetime.datetime.fromtimestamp(device['last_backup_complete'])} - % endif -

Shares

${share['room_key']}
- - ${share_url}/browse/share/${api_user['share_identifier']}/${share['room_key']} - -
${share['description']}
${share['password_required']}
- % if share['creation_time']: - ${datetime.datetime.fromtimestamp(share['creation_time'])} - % endif -
- % if share['update_time']: - ${datetime.datetime.fromtimestamp(share['update_time'])} - % endif -
${'Enabled' if share['enabled'] else 'Disabled'}
-
- - - - -
-
-
-
-
-
-% if not features['ldap']: - % if not api_user['num_devices']: -
- - -
- % endif -% endif -
-
- - diff --git a/django/apps/blue_management/blue_mgnt/mako_templates/users.html b/django/apps/blue_management/blue_mgnt/mako_templates/users.html deleted file mode 100644 index 43e8c6b..0000000 --- a/django/apps/blue_management/blue_mgnt/mako_templates/users.html +++ /dev/null @@ -1,220 +0,0 @@ -<%inherit file="main.html" /> - -<%def name="title()">Users - ${parent.title()} - -<%def name="head()"> - - - - -<%def name="top_of_head()"> - - -<%def name="scripts()"> - - - - -<%def name="body_classes()">users ${parent.body_classes()} -<%def name="container()"> -

Enterprise Partner: ${username}

-
-
-${parent.progressbar()} -
-% if saved and not search_back: - -% endif - -% if config['enable_local_users']: -
-

Create New User

-
- - - %for field in new_user.visible_fields(): - - %else: - - %endif - - %endfor - - -
- ${field.label_tag()} - ${field} - - %if field.errors: -
- - %for error in field.errors: - ${error} - %endfor - -
- -
- - %for hidden in new_user.hidden_fields(): - ${hidden} - %endfor -
-
-% endif -% if not features['ldap']: -
-

Upload CSV

-
-
- %for field in user_csv: - - - %else: - - - %endif - - %endfor - - - -
- ${field.label_tag()} - ${field} - %if field.errors: -
- - %for error in field.errors: - ${error} - %endfor - -
- -
- -
-% endif -
- -
- -

Users

- - - - Download CSV - - - ${'Hide Disabled' if show_disabled else 'Show Disabled'} -
-
- ${users.management_form} - ${delete_user_formset.management_form} - ${tmp_user_formset.management_form} - - - - % if not features['email_as_username']: - - % endif - - - - - - - - % if features['ldap'] and user.has_perm('blue_mgnt.can_view_user_data'): - - % endif - - - - - - <% local_index = 0 %> - % for x, curr_user in enumerate(all_users): - - % for hidden in delete_user_formset[x].hidden_fields(): - ${hidden} - % endfor - % if not features['email_as_username']: - - % endif - % if curr_user['is_local_user']: - % for hidden in tmp_user_formset[local_index].hidden_fields(): - ${hidden} - % endfor - % for field in tmp_user_formset[local_index].visible_fields(): - - % endfor - % else: - - - - - % endif - - - - - - - - % if curr_user['is_local_user']: - <% local_index += 1 %> - % endif - % endfor - -
UsernameNameEmailGroupEnabledGBs StoredCreation TimeLast LoginStorage LoginUser DetailDelete User
- -
${curr_user['username']} - ${field} - % if field.errors: -
- - % for error in field.errors: - ${error} - % endfor - - % endif -
${curr_user['name']}${curr_user['email']}${curr_user['group_name']}${curr_user['enabled']}${curr_user['gigs_stored']}${curr_user['creation_time']}${curr_user['last_login'] if curr_user['last_login'] else ''}Login - - Detail - - - % if (not curr_user['enabled'] or curr_user['is_local_user']) and user.has_perm('blue_mgnt.can_manage_users'): - ${delete_user_formset[x]['DELETE']} - % endif -
-
- - -
-
- -
- diff --git a/django/apps/blue_management/blue_mgnt/static/css/console-min.css b/django/apps/blue_management/blue_mgnt/static/css/console-min.css index 2d4962b..fdae2fd 100644 --- a/django/apps/blue_management/blue_mgnt/static/css/console-min.css +++ b/django/apps/blue_management/blue_mgnt/static/css/console-min.css @@ -1 +1 @@ -@import "../css/fonts.css";*{margin:0;padding:0}html,button,input,select,textarea{color:#222}body{font-size:1em;line-height:1.4}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}img{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{background-color:transparent;border:0;overflow:hidden;*text-indent:-9999px}.ir:before{content:"";display:block;width:0;height:150%}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.clearfix{*zoom:1}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.widget-table-details tr td:first-of-type>label label{font-family:ProximaNovaA-Semibold}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body{font-size:16px;font-family:ProximaNova-Regular;color:#505050;text-rendering:optimizeLegibility}h1,h2,h3,h4,h5,h6{font-family:ProximaNovaA-Semibold;color:#505050}a{color:#268bc9}strong,.strong,table thead th{font-family:ProximaNovaA-Semibold}::-webkit-input-placeholder{color:#c8c8c8}::-moz-placeholder{color:#c8c8c8}:-moz-placeholder{color:#c8c8c8}::-ms-input-placeholder{color:#c8c8c8}.overlord{width:880px;margin:0 auto;position:relative}#bg-gradient{width:100%}#bg-gradient div{width:100%;position:absolute;top:43px;height:277px;background-image:url(/static/blue_mgnt/img/bg_gradient.png);background-repeat:repeat-x;background-position:0 0}header{height:45px;background-color:#363636;position:relative;overflow:hidden}header div{width:880px;margin:0 auto}header h1{float:left}header h1 img{height:38px;width:48px;position:relative;top:-2px}header ul{float:right;font-size:14px;line-height:45px;list-style-type:none;font-family:ProximaNova-Bold}header ul li{float:left;color:#aeaeae;margin-left:30px}header ul li.line{border-left:1px solid #e0e0e0;padding:0 10px 0 7px}header ul li.line:last-of-type{border-right:1px solid #e0e0e0;margin-left:6px}header ul li a{cursor:pointer;color:#aeaeae;text-decoration:none}header ul li a .ss-icon{font-size:10px;padding:0 5px}nav{width:100%}.navtab-widget{height:78px;list-style-type:none;padding:0;margin:0 auto;border-bottom:1px solid #e0e0e0;overflow:hidden}.navtab-widget li{float:left;margin-right:1px;font-family:ProximaNova-Bold;position:relative}.navtab-widget li a{float:left;width:219px;height:70px;text-decoration:none;cursor:pointer;-webkit-transition:height .2s;-moz-transition:height .2s;-ms-transition:height .2s;-o-transition:height .2s;transition:height .2s}.navtab-widget li a:hover{height:78px}.navtab-widget li.active a{height:78px}.navtab-widget li img,.navtab-widget li i{position:absolute}.navtab-widget li img{top:-4px;right:5px}.navtab-widget li i{top:0;right:5px;color:#fff;font-size:45px;opacity:.3}.navtab-widget li span{padding-top:43px;padding-left:10px;display:block;color:#fff;text-transform:uppercase;font-size:16px;text-shadow:0 -1px 0 rgba(0,0,0,0.4),0 1px 0 rgba(255,255,255,0.3)}.navtab-widget li.navtab-item-users a{background-color:#0d50a1}.navtab-widget li.navtab-item-shares a{background-color:#2089ca}.navtab-widget li.navtab-item-manage a{background-color:#21b1e6}.navtab-widget li.navtab-item-reports a{background-color:#5ac5f1}.account-overview{height:50px;color:#bcbcbc}.account-overview ul{text-align:center;list-style-type:none;padding-top:8px;font-size:13px}.account-overview ul li{display:inline-block;margin-left:3em;white-space:nowrap}.account-overview ul li i{margin-right:5px;position:relative;top:2px}.account-overview ul li:first-child{margin-left:0}div.breadcrumb{height:35px;font-size:10px}h1.page-header{height:50px;position:relative}h1.page-header:after{display:block;clear:both;content:""}h1.page-header .ss-icon{font-size:23px;color:#929292}h1.page-header .actions{float:right;margin-bottom:20px}h1.page-header .actions form{display:inline-block;position:relative}h1.page-header .actions:after{display:block;clear:both;content:""}h1.page-header .actions .widget-search-input{width:300px;height:39px;border-radius:5px;border:1px solid #e0e0e0;padding-left:12px;color:#767677;font:15px / 19px ProximaNova-Regular;overflow:hidden}h1.page-header .actions .search-button{height:37px;width:34px;font-size:16px;position:absolute;top:9px;right:1px;background-color:#f4f4f4;border:none;border-top-right-radius:3px;border-bottom-right-radius:3px;color:#c7c7c7}h1.page-header .actions .search-button:hover{color:#fff;background-color:#929292}.footer{margin-top:60px;margin-bottom:30px;padding-top:20px;border-top:1px solid #ddd;color:#ccc;font-size:14px}.footer a{color:#ccc;text-decoration:none}.footer p{float:left}.footer ul{list-style-type:none;float:right}.footer ul li{float:left;padding:0 10px;border-left:1px solid #ddd}.footer ul li:first-child{border-left:none}.widget-table{border-collapse:collapse;border-spacing:0;width:100%;table-layout:auto;border:1px solid #ddd;background-color:#fff;font-size:15px}.widget-table:after{display:block;clear:both;content:""}.widget-table>thead>tr>th{padding:16px 8px 4px 8px;border-bottom:2px solid #ddd;text-align:left;font-weight:bold}.widget-table>thead>tr>th:hover{text-decoration:underline}.widget-table>tbody>tr:hover>td{background-color:#e6e6e6}.widget-table>tbody>tr:hover>td .fixWidth-fader{display:none}.widget-table>tbody>tr>td{padding:14px 4px 14px 8px;border-bottom:1px solid #ddd;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-table>tbody>tr:nth-child(odd){background-color:#fafafa}.widget-table input[type='text'],.widget-table select,.widget-table textarea,.widget-table input[type='password']{width:auto;height:30px;border-radius:5px;border:1px solid #e0e0e0;padding-left:7px;color:#767677;font:13px / 23px ProximaNova-Regular}.widget-table td>label,.widget-table td>div>label{font-family:ProximaNova-Bold}.widget-table li>label{font-family:ProximaNova-Regular}.widget-manage-blocks{width:425px;border:1px solid #e0e0e0;border-radius:4px;margin-bottom:18px;background-color:#fff;position:relative}.widget-manage-blocks .manage-icon{font-size:60px;color:#c7c7c7;padding:10px;text-align:center;vertical-align:top;display:inline-block;position:relative;top:18px;left:10px;width:24%}.widget-manage-blocks .manage-icon i{margin:0 auto;vertical-align:baseline}.widget-manage-blocks div.manage-content{border-left:1px solid #e0e0e0;padding:10px 10px 10px 18px;display:inline-block;width:65%;position:relative;left:17px;min-height:125px}.widget-manage-blocks div.manage-content h3{font-size:16px}.widget-manage-blocks div.manage-content h3 span{float:right;font-size:10px;font-family:ProximaNova-Regular}.widget-manage-blocks div.manage-content p{font-size:12px;margin:3px 0 8px;min-height:32px}.widget-manage-blocks div.manage-content a.button{display:inline-block;width:170px;text-align:center;padding:8px 10px}.widget-add-user{display:none}.widget-add-user-option{text-align:center}.modal-wrapper{background-color:rgba(0,0,0,0.5);position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;display:none;z-index:9000}.modal-content{position:absolute;width:600px;border:1px solid #e0e0e0;border-radius:8px;background-color:#fff}.modal-content.confirm{width:330px}.modal-content.confirm h2{height:45px}.modal-content input#expiry_interval_days{width:100px;display:inline}.modal-content .cancel-action{position:relative;left:20px}.modal-content label{font-family:ProximaNovaA-Semibold}.modal-content input[type='text'],.modal-content select,.modal-content textarea,.modal-content input[type='password']{width:auto;height:30px;border-radius:5px;border:1px solid #e0e0e0;padding-left:12px;color:#767677;font:13px / 23px ProximaNova-Regular}.modal-content select{max-width:135px;display:inline-block}.modal-content input[type='submit']{float:right;position:relative;right:20px}.modal-content .modal-table-label{width:30%;padding-left:20px}.modal-content h2.page-header{border-bottom:1px solid #e0e0e0;text-align:left;padding:10px}.modal-content h2.page-header i{padding-right:10px;font-size:18px}.modal-content h2.page-header .actions{float:right;cursor:pointer;margin-bottom:20px}.modal-content h2.page-header .actions:hover{color:#e5e5e5}.modal-content .lower-content{padding:20px}.modal-content .lower-content .description{margin-bottom:20px}.modal-content .option-box{position:relative;display:inline-block;margin:10px;border-radius:4px;border:1px solid #e0e0e0;text-align:center;padding:40px}.modal-content .option-box p{font-family:ProximaNovaA-Semibold;margin-bottom:20px}.modal-content .permissions ul{height:145px;list-style:none;column-fill:auto;column-width:140px;column-gap:0;-moz-column-fill:auto;-moz-column-width:140px;-moz-column-gap:0;-webkit-column-fill:auto;-webkit-column-width:140px;-webkit-column-gap:0}.modal-content .permissions ul label{font-size:12px}.widget-pagination{padding:20px 0}.widget-pagination ul{text-align:center;list-style-type:none;font-size:13px}.widget-pagination ul li{display:inline-block;padding:2px 5px;color:#4b4b4b}.widget-pagination ul li.active{background-color:#4b4b4b;color:#fff}.widget-actions{margin:20px 0}.widget-actions.center-left{width:160px;margin:20px auto;display:inline-block}.widget-actions.center-right{width:160px;margin:20px auto;display:inline-block;float:right}.widget-actions.short-right{float:right;width:250px}.widget-actions .rhs{float:right}.widget-actions:after{display:block;clear:both;content:""}.widget-splitactions.float{width:625px;float:left;margin:20px 0}.widget-splitactions form{display:inline-block;position:relative;z-index:1}.widget-splitactions .rhs{float:right}.widget-splitactions .lhs a{margin:0 8px}.widget-fieldset{border:1px solid #ccc;margin-bottom:1em;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.widget-fieldset>div{border-top:1px solid #ccc;padding:20px 20px 20px 200px;position:relative}.widget-fieldset>div:first-child{border-top:none}.widget-fieldset label{font-family:ProximaNova-Bold;font-size:18px;position:absolute;left:20px}button,.button{font-family:ProximaNova-Bold;font-size:16px;padding:10px 15px;text-decoration:none;cursor:pointer;border-radius:4px}button.thin,.button.thin{padding:1px 18px;font-family:ProximaNova-Regular;font-size:14px}.button-primary-basic{color:#fff;background-color:#22a2d9;border:1px solid #22a2d9}.button-primary-basic:hover{background-color:#219bd0}.button-secondary{color:#fff;background-color:#cf3940;border:1px solid #cf3940}.button-secondary:hover{background-color:#cc3239}.button-muted{color:#fff;background-color:#a0a0a0;border:1px solid #a0a0a0}.button-muted:hover{background-color:#9b9b9b}.code-extra-info{margin-top:8px}#usage-report{width:520px;text-align:center;margin:20px auto}body.home td:first-of-type input{width:130px}body.home .delete-fill{color:#aeaeae}body.errors{text-align:center}body.errors .content{margin:18% auto}body.errors h1{font:42px / 62px ProximaNova-Light;margin-bottom:20px}body.errors p{font:18px / 22px ProximaNova-Regular}body.errors p a{text-decoration:none}body.errors p a:hover{text-decoration:underline}.log-toggle{font-size:8px;cursor:pointer}#delete-group th{width:30%}.user_detail .widget-table{table-layout:fixed}body.logs .widget-table td{overflow:visible;text-overflow:clip;white-space:normal;padding:5px 14px;font:12px / 22px monospace}header li>a[href='/logout/']:hover,header li>a[href='']:hover{color:#c0c0c0}.permissions td{vertical-align:top}.permissions ul{min-height:145px;column-fill:auto;column-width:180px;column-gap:0;-moz-column-fill:auto;-moz-column-width:180px;-moz-column-gap:0;-webkit-column-fill:auto;-webkit-column-width:180px;-webkit-column-gap:0}.group_detail .widget-table tr>td:last-of-type,.group_detail .widget-table tr>td:first-of-type{width:25%}.shares_detail .widget-table tr>td:first-of-type{width:28%}#add_ip_block{margin-left:20px}body.admin_groups th{width:22%}body.admin_groups th#perms{width:38%}body.admin_groups th:last-child{width:90px}body.admin_groups td{vertical-align:top}.radio-submit{vertical-align:middle;margin:0 1px}.radio-submit:nth-of-type(2){margin:0 1px 0 14px}.error{color:#cc3239}body.login h1{font-family:ProximaNovaT-Thin;font-size:42px;text-align:center;margin-bottom:30px}body.login h2{font-family:ProximaNova-Light;text-align:center;font-size:20px}body.login h3{font-family:ProximaNova-Regular;font-weight:100;font-size:22px;line-height:48px}body.login .content{margin:4% auto}body.login:after{display:block;clear:both;content:""}body.login .login-wrapper{margin:3% auto;width:750px;background-color:#fff}body.login .login-wrapper .right-col{width:385px;margin-left:50px}body.login .login-wrapper .right-col div:first-of-type{margin-bottom:40px}body.login .login-wrapper .right-col img{float:left;margin-right:18px;margin-bottom:85px;position:relative;top:18px}body.password .login-wrapper{margin-top:50px;background-color:#fff;width:860px;padding:45px 0 0 45px;position:relative;top:-20px}body.password .login-wrapper .login-form-wrapper input:first-of-type{margin-bottom:20px}body.password .login-wrapper .right-col{width:385px;margin-left:75px;margin-top:18px}body.password .login-wrapper .right-col h3{font-family:ProximaNova-Regular;font-weight:100;font-size:22px;line-height:48px}body.password .login-wrapper .right-col div:first-of-type{margin-bottom:40px}body.password .login-wrapper .right-col img{float:left;margin-right:18px;margin-bottom:85px;position:relative;top:18px}body.login .image-wrapper,body.errors .image-wrapper,body.password .image-wrapper{width:120px;margin:2% auto}body.login .image-wrapper img,body.errors .image-wrapper img,body.password .image-wrapper img{width:120px}body.login label,body.errors label,body.password label{font-family:ProximaNovaA-Semibold}body.login input[type='text'],body.errors input[type='text'],body.password input[type='text'],body.login select,body.errors select,body.password select,body.login textarea,body.errors textarea,body.password textarea,body.login input[type='password'],body.errors input[type='password'],body.password input[type='password']{width:auto;height:30px;border-radius:5px;border:1px solid #e0e0e0;padding-left:12px;color:#767677;font:13px / 23px ProximaNova-Regular}body.login select,body.errors select,body.password select{max-width:135px;display:inline-block}body.login input[type='submit'],body.errors input[type='submit'],body.password input[type='submit']{float:right;position:relative;right:20px}body.login .widget-login label,body.errors .widget-login label,body.password .widget-login label{display:block;text-transform:uppercase;font-family:ProximaNova-Regular;font-size:14px;color:#b7b7b7}body.login .widget-login input[type='text'],body.errors .widget-login input[type='text'],body.password .widget-login input[type='text'],body.login .widget-login input[type='password'],body.errors .widget-login input[type='password'],body.password .widget-login input[type='password']{width:300px;height:40px;font-size:18px}body.login input[type='submit'],body.errors input[type='submit'],body.password input[type='submit']{padding:12px 30px;float:left;right:0;font-size:16px}.widget-usage-info{width:520px;position:relative;top:-30px}.widget-usage-info .digits{text-align:center;width:100%;margin:0 auto}.widget-usage-info .digits p{width:100px;display:inline;font-size:12px}.widget-usage-info .digits p.space-used{color:#0d50a1;font-family:ProximaNova-Bold}.widget-usage-info .digits p.space-used span{font-family:ProximaNova-Regular}.widget-usage-info .digits p.space-allocated{color:#5ac5f1;font-family:ProximaNova-Bold}.widget-usage-info .digits p.space-allocated span{font-family:ProximaNova-Regular}.widget-usage-info .usage-bar-wrapper{position:relative;overflow:hidden;height:24px;width:518px;background-color:#5ac5f1;background:-moz-linear-gradient(#5ac5f1, #21b1e6);background:-webkit-linear-gradient(#5ac5f1, #21b1e6);background:-o-linear-gradient(#5ac5f1, #21b1e6);background:linear-gradient(#5ac5f1, #21b1e6);border-radius:4px;border:1px solid #e0e0e0}.widget-usage-info .usage-bar-wrapper .usage-bar-space-used{position:absolute;height:26px;width:519px;top:-1px;background-color:#2089ca;background:-moz-linear-gradient(#2089ca, #0d50a1);background:-webkit-linear-gradient(#2089ca, #0d50a1);background:-o-linear-gradient(#2089ca, #0d50a1);background:linear-gradient(#2089ca, #0d50a1)}.widget-usage-info .usage-bar-wrapper .usage-bar-space-used.usage-warning{background-color:#fcdc3b;background:-moz-linear-gradient(#fcdc3b, #ecc504);background:-webkit-linear-gradient(#fcdc3b, #ecc504);background:-o-linear-gradient(#fcdc3b, #ecc504);background:linear-gradient(#fcdc3b, #ecc504)}.widget-usage-info .usage-bar-wrapper .usage-bar-space-used.usage-danger{background-color:#f00;background:-moz-linear-gradient(#f00, #b80000);background:-webkit-linear-gradient(#f00, #b80000);background:-o-linear-gradient(#f00, #b80000);background:linear-gradient(#f00, #b80000)}.widget-usage-info .usage-bar-wrapper .usage-bar-space-used.usage-danger span{color:#fff;font:14px / 16px ProximaNova-Regular;float:right;padding:4px;margin-right:10px;text-shadow:#5e2612 1px 1px 4px}.tag{padding:8px 10px;font-size:.62em;color:#fff;background-color:#4c4c4c;text-transform:uppercase;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.enabled{font-weight:bold}.spacer{clear:both;height:1px;margin-top:-1px}.left-col{display:inline-block;margin-right:9px;vertical-align:top}.right-col{display:inline-block;margin-left:9px;vertical-align:top}.set-top{vertical-align:top}.permissions-options{max-width:180px;display:inline-block;font-size:12px}.space-20none{margin:20px 0}#hint{white-space:normal;overflow:visible}#hint span{font-size:12px}.link-primary{font-family:ProximaNova-Bold;color:#2089ca}.link-primary:visited{color:#2089ca}.toggle-controller{cursor:pointer;font-size:14px}.toggle-controller i{font-size:8px}.toggle-controller:hover{text-decoration:underline}.status-message{background-color:#fff;border-radius:4px;border:1px solid #e0e0e0;max-width:800px;margin:20px auto;padding:10px;display:inline-block}.status-message .actions{float:right;cursor:pointer}.status-message .actions:hover{color:#e5e5e5}.status-message .status-content code{font-size:12px}.status-message i{vertical-align:middle;margin-right:12px;font-size:18px}.status-message h2{border-bottom:1px solid #e0e0e0}.shield{position:absolute;z-index:10000;height:100%;width:100%;background-color:rgba(240,240,240,0.7);top:0;left:0;right:0;bottom:0}.collapse{overflow:hidden !important;text-overflow:ellipsis !important;white-space:nowrap !important;padding:5px 14px !important}.edit-status{display:inline-block;font-size:12px;color:#bababa;vertical-align:bottom;margin-right:5px}.cancel-action{padding:10px 35px}.delete-notice{text-align:center;font:16px / 22px ProximaNovaA-Semibold}.loader{position:relative}select{max-width:135px}#saved{background-color:#28a32e;color:#fff;margin-bottom:10px;padding:10px;border-radius:4px}.error-alert{border:1px solid #cc3239;background-color:#d75a60;padding:10px;border-radius:4px;margin:10px 0}.error-alert p{color:#fff;white-space:nowrap}.error-alert p.error-list{position:relative;left:20px}span.error-highlight input{border-color:#cc3239 !important;background-color:#f5d5d7}span.error-highlight .error-tag{border:1px solid #cc3239;background-color:#d14248;padding:4px;border-radius:4px;color:#fff;font-size:12px;vertical-align:middle;margin-left:10px;text-shadow:0 0 1px #000}#clear-search{font:14px / 16px ProximaNova-Regular;display:block;position:absolute;right:8px;top:-8px}tr>td{height:60px}.csv-note{margin:10px auto;width:565px}.csv-note p{margin:20px}.csv-note pre{font-size:14px;color:#444;margin-left:60px}.row{display:block;margin:20px auto;height:127px;width:855px}.row:first-of-type{margin-top:0}.row div{display:inline-block}.row .widget-manage-blocks{margin:0 10px}.report-stat{border:1px solid #e0e0e0;width:180px;height:100%;border-radius:4px;margin:0 10px;text-align:center;padding:18px 5px;background-color:#fff;vertical-align:top}.report-stat .stat-number{font:50px / 55px ProximaNova-Light;color:#c7c7c7}.report-stat .stat-description{font:14px / 16px ProximaNova-Bold}.reboot-message-wrapper{display:none;position:absolute;top:0;right:0;bottom:0;left:0}.reboot-message-wrapper .reboot-message{width:300px;background-color:#fff;text-align:center;padding:20px;border:1px solid #000;position:absolute}.reboot-message-wrapper .reboot-message img{width:60px;margin:10px auto}.reboot-message-wrapper .reboot-message .reboot-message-close{font-size:10px;float:right;display:none;position:relative;top:-18px;right:-16px;cursor:pointer}.reboot-message-wrapper .reboot-message .reboot-message-close:hover{color:#e0e0e0} \ No newline at end of file +@import "../css/fonts.css";*{margin:0;padding:0}html,button,input,select,textarea{color:#222}body{font-size:1em;line-height:1.4}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}img{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{background-color:transparent;border:0;overflow:hidden;*text-indent:-9999px}.ir:before{content:"";display:block;width:0;height:150%}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.clearfix{*zoom:1}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}#widget-table-details{width:880px}#widget-table-details tr td:first-of-type>label label{font-family:ProximaNovaA-Semibold}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body{font-size:16px;font-family:ProximaNova-Regular;color:#505050;text-rendering:optimizeLegibility}h1,h2,h3,h4,h5,h6{font-family:ProximaNovaA-Semibold;color:#505050}a{color:#268bc9}strong,.strong,table thead th{font-family:ProximaNovaA-Semibold}::-webkit-input-placeholder{color:#c8c8c8}::-moz-placeholder{color:#c8c8c8}:-moz-placeholder{color:#c8c8c8}::-ms-input-placeholder{color:#c8c8c8}.overlord{width:880px;margin:0 auto;position:relative}#bg-gradient{width:100%}#bg-gradient div{width:100%;position:absolute;top:43px;height:277px;background-image:url(/static/blue_mgnt/img/bg_gradient.png);background-repeat:repeat-x;background-position:0 0}header{height:45px;background-color:#363636;position:relative;overflow:hidden}header div{width:880px;margin:0 auto}header h1{float:left}header h1 img{height:38px;width:48px;position:relative;top:-2px}header ul{float:right;font-size:14px;line-height:45px;list-style-type:none;font-family:ProximaNova-Bold}header ul li{float:left;color:#aeaeae;margin-left:30px}header ul li.line{border-left:1px solid #e0e0e0;padding:0 10px 0 7px}header ul li.line:last-of-type{border-right:1px solid #e0e0e0;margin-left:6px}header ul li a{cursor:pointer;color:#aeaeae;text-decoration:none}header ul li a .ss-icon{font-size:10px;padding:0 5px}nav{width:100%}.navtab-widget{height:78px;list-style-type:none;padding:0;margin:0 auto;border-bottom:1px solid #e0e0e0;overflow:hidden}.navtab-widget li{float:left;margin-right:1px;font-family:ProximaNova-Bold;position:relative}.navtab-widget li a{float:left;width:219px;height:70px;text-decoration:none;cursor:pointer;-webkit-transition:height .2s;-moz-transition:height .2s;-ms-transition:height .2s;-o-transition:height .2s;transition:height .2s}.navtab-widget li a:hover{height:78px}.navtab-widget li.active a{height:78px}.navtab-widget li img,.navtab-widget li i{position:absolute}.navtab-widget li img{top:-4px;right:5px}.navtab-widget li i{top:0;right:5px;color:#fff;font-size:45px;opacity:.3}.navtab-widget li span{padding-top:43px;padding-left:10px;display:block;color:#fff;text-transform:uppercase;font-size:16px;text-shadow:0 -1px 0 rgba(0,0,0,0.4),0 1px 0 rgba(255,255,255,0.3)}.navtab-widget li.navtab-item-users a{background-color:#0d50a1}.navtab-widget li.navtab-item-shares a{background-color:#2089ca}.navtab-widget li.navtab-item-manage a{background-color:#21b1e6}.navtab-widget li.navtab-item-reports a{background-color:#5ac5f1}.account-overview{height:50px;color:#bcbcbc}.account-overview ul{text-align:center;list-style-type:none;padding-top:8px;font-size:13px}.account-overview ul li{display:inline-block;margin-left:3em;white-space:nowrap}.account-overview ul li i{margin-right:5px;position:relative;top:2px}.account-overview ul li:first-child{margin-left:0}div.breadcrumb{height:35px;font-size:10px}h1.page-header{height:50px;position:relative}h1.page-header:after{display:block;clear:both;content:""}h1.page-header .ss-icon{font-size:23px;color:#929292}h1.page-header .actions{float:right;margin-bottom:20px}h1.page-header .actions form{display:inline-block;position:relative}h1.page-header .actions:after{display:block;clear:both;content:""}h1.page-header .actions .widget-search-input{width:300px;height:39px;border-radius:5px;border:1px solid #e0e0e0;padding-left:12px;color:#767677;font:15px / 19px ProximaNova-Regular;overflow:hidden}h1.page-header .actions .search-button{height:37px;width:34px;font-size:16px;position:absolute;top:9px;right:1px;background-color:#f4f4f4;border:none;border-top-right-radius:3px;border-bottom-right-radius:3px;color:#c7c7c7}h1.page-header .actions .search-button:hover{color:#fff;background-color:#929292}.footer{margin-top:60px;margin-bottom:30px;padding-top:20px;border-top:1px solid #ddd;color:#ccc;font-size:14px}.footer a{color:#ccc;text-decoration:none}.footer p{float:left}.footer ul{list-style-type:none;float:right}.footer ul li{float:left;padding:0 10px;border-left:1px solid #ddd}.footer ul li:first-child{border-left:none}.widget-table{border-collapse:collapse;border-spacing:0;width:100%;table-layout:auto;border:1px solid #ddd;background-color:#fff;font-size:15px}.widget-table:after{display:block;clear:both;content:""}.widget-table>thead>tr>th{padding:16px 8px 4px 8px;border-bottom:2px solid #ddd;text-align:left;font-weight:bold}.widget-table>thead>tr>th:hover{text-decoration:underline}.widget-table>tbody>tr:hover>td{background-color:#e6e6e6}.widget-table>tbody>tr:hover>td .fixWidth-fader{display:none}.widget-table>tbody>tr>td{padding:14px 4px 14px 8px;border-bottom:1px solid #ddd;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-table>tbody>tr:nth-child(odd){background-color:#fafafa}.widget-table input[type='text'],.widget-table select,.widget-table textarea,.widget-table input[type='password']{width:auto;height:30px;border-radius:5px;border:1px solid #e0e0e0;padding-left:7px;color:#767677;font:13px / 23px ProximaNova-Regular}.widget-table td>label,.widget-table td>div>label{font-family:ProximaNova-Bold}.widget-table li>label{font-family:ProximaNova-Regular}.widget-manage-blocks{width:425px;border:1px solid #e0e0e0;border-radius:4px;margin-bottom:18px;background-color:#fff;position:relative}.widget-manage-blocks .manage-icon{font-size:60px;color:#c7c7c7;padding:10px;text-align:center;vertical-align:top;display:inline-block;position:relative;top:18px;left:10px;width:24%}.widget-manage-blocks .manage-icon i{margin:0 auto;vertical-align:baseline}.widget-manage-blocks div.manage-content{border-left:1px solid #e0e0e0;padding:10px 10px 10px 18px;display:inline-block;width:65%;position:relative;left:17px;min-height:125px}.widget-manage-blocks div.manage-content h3{font-size:16px}.widget-manage-blocks div.manage-content h3 span{float:right;font-size:10px;font-family:ProximaNova-Regular}.widget-manage-blocks div.manage-content p{font-size:12px;margin:3px 0 8px;min-height:32px}.widget-manage-blocks div.manage-content a.button{display:inline-block;width:170px;text-align:center;padding:8px 10px}.widget-add-user{display:none}.widget-add-user-option{text-align:center}.modal-wrapper{background-color:rgba(0,0,0,0.5);position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;display:none;z-index:9000}.modal-content{position:absolute;width:600px;border:1px solid #e0e0e0;border-radius:8px;background-color:#fff}.modal-content.confirm{width:330px}.modal-content.confirm h2{height:45px}.modal-content input#expiry_interval_days{width:100px;display:inline}.modal-content .cancel-action{position:relative;left:20px}.modal-content label{font-family:ProximaNovaA-Semibold}.modal-content input[type='text'],.modal-content select,.modal-content textarea,.modal-content input[type='password']{width:auto;height:30px;border-radius:5px;border:1px solid #e0e0e0;padding-left:12px;color:#767677;font:13px / 23px ProximaNova-Regular}.modal-content select{max-width:135px;display:inline-block}.modal-content input[type='submit']{float:right;position:relative;right:20px}.modal-content .modal-table-label{width:30%;padding-left:20px}.modal-content h2.page-header{border-bottom:1px solid #e0e0e0;text-align:left;padding:10px}.modal-content h2.page-header i{padding-right:10px;font-size:18px}.modal-content h2.page-header .actions{float:right;cursor:pointer;margin-bottom:20px}.modal-content h2.page-header .actions:hover{color:#e5e5e5}.modal-content .lower-content{padding:20px}.modal-content .lower-content .description{margin-bottom:20px}.modal-content .option-box{position:relative;display:inline-block;margin:10px;border-radius:4px;border:1px solid #e0e0e0;text-align:center;padding:40px}.modal-content .option-box p{font-family:ProximaNovaA-Semibold;margin-bottom:20px}.modal-content .permissions ul{height:145px;list-style:none;column-fill:auto;column-width:140px;column-gap:0;-moz-column-fill:auto;-moz-column-width:140px;-moz-column-gap:0;-webkit-column-fill:auto;-webkit-column-width:140px;-webkit-column-gap:0}.modal-content .permissions ul label{font-size:12px}.widget-pagination{padding:20px 0}.widget-pagination ul{text-align:center;list-style-type:none;font-size:13px}.widget-pagination ul li{display:inline-block;padding:2px 5px;color:#4b4b4b}.widget-pagination ul li.active{background-color:#4b4b4b;color:#fff}.widget-actions{margin:20px 0}.widget-actions.center-left{width:160px;margin:20px auto;display:inline-block}.widget-actions.center-right{width:160px;margin:20px auto;display:inline-block;float:right}.widget-actions.short-right{float:right;width:250px}.widget-actions .rhs{float:right}.widget-actions:after{display:block;clear:both;content:""}.widget-splitactions.float{width:625px;float:left;margin:20px 0}.widget-splitactions form{display:inline-block;position:relative;z-index:1}.widget-splitactions .rhs{float:right}.widget-splitactions .lhs a{margin:0 8px}.widget-fieldset{border:1px solid #ccc;margin-bottom:1em;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.widget-fieldset>div{border-top:1px solid #ccc;padding:20px 20px 20px 200px;position:relative}.widget-fieldset>div:first-child{border-top:none}.widget-fieldset label{font-family:ProximaNova-Bold;font-size:18px;position:absolute;left:20px}button,.button{font-family:ProximaNova-Bold;font-size:16px;padding:10px 15px;text-decoration:none;cursor:pointer;border-radius:4px}button.thin,.button.thin{padding:1px 18px;font-family:ProximaNova-Regular;font-size:14px}.button-primary-basic{color:#fff;background-color:#22a2d9;border:1px solid #22a2d9}.button-primary-basic:hover{background-color:#219bd0}.button-secondary{color:#fff;background-color:#cf3940;border:1px solid #cf3940}.button-secondary:hover{background-color:#cc3239}.button-muted{color:#fff;background-color:#a0a0a0;border:1px solid #a0a0a0}.button-muted:hover{background-color:#9b9b9b}.code-extra-info{margin-top:8px}#usage-report{width:520px;text-align:center;margin:20px auto}body.home td:first-of-type input{width:130px}body.home .delete-fill{color:#aeaeae}body.errors{text-align:center}body.errors .content{margin:18% auto}body.errors h1{font:42px / 62px ProximaNova-Light;margin-bottom:20px}body.errors p{font:18px / 22px ProximaNova-Regular}body.errors p a{text-decoration:none}body.errors p a:hover{text-decoration:underline}.log-toggle{font-size:8px;cursor:pointer}#delete-group th{width:30%}.user_detail .widget-table{table-layout:fixed}body.logs .widget-table td{overflow:visible;text-overflow:clip;white-space:normal;padding:5px 14px;font:12px / 22px monospace}header li>a[href='/logout/']:hover,header li>a[href='']:hover{color:#c0c0c0}.permissions td{vertical-align:top}.permissions ul{min-height:145px;column-fill:auto;column-width:180px;column-gap:0;-moz-column-fill:auto;-moz-column-width:180px;-moz-column-gap:0;-webkit-column-fill:auto;-webkit-column-width:180px;-webkit-column-gap:0}.group_detail .widget-table tr>td:last-of-type,.group_detail .widget-table tr>td:first-of-type{width:25%}.shares_detail .widget-table tr>td:first-of-type{width:28%}#add_ip_block{margin-left:20px}body.admin_groups th{width:22%}body.admin_groups th#perms{width:38%}body.admin_groups th:last-child{width:90px}body.admin_groups td{vertical-align:top}.radio-submit{vertical-align:middle;margin:0 1px}.radio-submit:nth-of-type(2){margin:0 1px 0 14px}.error{color:#cc3239}body.login h1{font-family:ProximaNovaT-Thin;font-size:42px;text-align:center;margin-bottom:30px}body.login h2{font-family:ProximaNova-Light;text-align:center;font-size:20px}body.login h3{font-family:ProximaNova-Regular;font-weight:100;font-size:22px;line-height:48px}body.login .content{margin:4% auto}body.login:after{display:block;clear:both;content:""}body.login .login-wrapper{margin:3% auto;width:750px;background-color:#fff}body.login .login-wrapper .right-col{width:385px;margin-left:50px}body.login .login-wrapper .right-col div:first-of-type{margin-bottom:40px}body.login .login-wrapper .right-col img{float:left;margin-right:18px;margin-bottom:85px;position:relative;top:18px}body.password .login-wrapper{margin-top:50px;background-color:#fff;width:860px;padding:45px 0 0 45px;position:relative;top:-20px}body.password .login-wrapper .login-form-wrapper input:first-of-type{margin-bottom:20px}body.password .login-wrapper .right-col{width:385px;margin-left:75px;margin-top:18px}body.password .login-wrapper .right-col h3{font-family:ProximaNova-Regular;font-weight:100;font-size:22px;line-height:48px}body.password .login-wrapper .right-col div:first-of-type{margin-bottom:40px}body.password .login-wrapper .right-col img{float:left;margin-right:18px;margin-bottom:85px;position:relative;top:18px}body.login .image-wrapper,body.errors .image-wrapper,body.password .image-wrapper{width:120px;margin:2% auto}body.login .image-wrapper img,body.errors .image-wrapper img,body.password .image-wrapper img{width:120px}body.login label,body.errors label,body.password label{font-family:ProximaNovaA-Semibold}body.login input[type='text'],body.errors input[type='text'],body.password input[type='text'],body.login select,body.errors select,body.password select,body.login textarea,body.errors textarea,body.password textarea,body.login input[type='password'],body.errors input[type='password'],body.password input[type='password']{width:auto;height:30px;border-radius:5px;border:1px solid #e0e0e0;padding-left:12px;color:#767677;font:13px / 23px ProximaNova-Regular}body.login select,body.errors select,body.password select{max-width:135px;display:inline-block}body.login input[type='submit'],body.errors input[type='submit'],body.password input[type='submit']{float:right;position:relative;right:20px}body.login .widget-login label,body.errors .widget-login label,body.password .widget-login label{display:block;text-transform:uppercase;font-family:ProximaNova-Regular;font-size:14px;color:#b7b7b7}body.login .widget-login input[type='text'],body.errors .widget-login input[type='text'],body.password .widget-login input[type='text'],body.login .widget-login input[type='password'],body.errors .widget-login input[type='password'],body.password .widget-login input[type='password']{width:300px;height:40px;font-size:18px}body.login input[type='submit'],body.errors input[type='submit'],body.password input[type='submit']{padding:12px 30px;float:left;right:0;font-size:16px}.widget-usage-info{width:520px;position:relative;top:-30px}.widget-usage-info .digits{text-align:center;width:100%;margin:0 auto}.widget-usage-info .digits p{width:100px;display:inline;font-size:12px}.widget-usage-info .digits p.space-used{color:#0d50a1;font-family:ProximaNova-Bold}.widget-usage-info .digits p.space-used span{font-family:ProximaNova-Regular}.widget-usage-info .digits p.space-allocated{color:#5ac5f1;font-family:ProximaNova-Bold}.widget-usage-info .digits p.space-allocated span{font-family:ProximaNova-Regular}.widget-usage-info .usage-bar-wrapper{position:relative;overflow:hidden;height:24px;width:518px;background-color:#5ac5f1;background:-moz-linear-gradient(#5ac5f1, #21b1e6);background:-webkit-linear-gradient(#5ac5f1, #21b1e6);background:-o-linear-gradient(#5ac5f1, #21b1e6);background:linear-gradient(#5ac5f1, #21b1e6);border-radius:4px;border:1px solid #e0e0e0}.widget-usage-info .usage-bar-wrapper .usage-bar-space-used{position:absolute;height:26px;width:519px;top:-1px;background-color:#2089ca;background:-moz-linear-gradient(#2089ca, #0d50a1);background:-webkit-linear-gradient(#2089ca, #0d50a1);background:-o-linear-gradient(#2089ca, #0d50a1);background:linear-gradient(#2089ca, #0d50a1)}.widget-usage-info .usage-bar-wrapper .usage-bar-space-used.usage-warning{background-color:#fcdc3b;background:-moz-linear-gradient(#fcdc3b, #ecc504);background:-webkit-linear-gradient(#fcdc3b, #ecc504);background:-o-linear-gradient(#fcdc3b, #ecc504);background:linear-gradient(#fcdc3b, #ecc504)}.widget-usage-info .usage-bar-wrapper .usage-bar-space-used.usage-danger{background-color:#f00;background:-moz-linear-gradient(#f00, #b80000);background:-webkit-linear-gradient(#f00, #b80000);background:-o-linear-gradient(#f00, #b80000);background:linear-gradient(#f00, #b80000)}.widget-usage-info .usage-bar-wrapper .usage-bar-space-used.usage-danger span{color:#fff;font:14px / 16px ProximaNova-Regular;float:right;padding:4px;margin-right:10px;text-shadow:#5e2612 1px 1px 4px}.tag{padding:8px 10px;font-size:.62em;color:#fff;background-color:#4c4c4c;text-transform:uppercase;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.enabled{font-weight:bold}.spacer{clear:both;height:1px;margin-top:-1px}.left-col{display:inline-block;margin-right:9px;vertical-align:top}.right-col{display:inline-block;margin-left:9px;vertical-align:top}.set-top{vertical-align:top}.permissions-options{max-width:180px;display:inline-block;font-size:12px}.space-20none{margin:20px 0}#hint{white-space:normal;overflow:visible}#hint span{font-size:12px}.link-primary{font-family:ProximaNova-Bold;color:#2089ca}.link-primary:visited{color:#2089ca}.toggle-controller{cursor:pointer;font-size:14px}.toggle-controller i{font-size:8px}.toggle-controller:hover{text-decoration:underline}.status-message{background-color:#fff;border-radius:4px;border:1px solid #e0e0e0;max-width:800px;margin:20px auto;padding:10px;display:inline-block}.status-message .actions{float:right;cursor:pointer}.status-message .actions:hover{color:#e5e5e5}.status-message .status-content code{font-size:12px}.status-message i{vertical-align:middle;margin-right:12px;font-size:18px}.status-message h2{border-bottom:1px solid #e0e0e0}.shield{position:absolute;z-index:10000;height:100%;width:100%;background-color:rgba(240,240,240,0.7);top:0;left:0;right:0;bottom:0}.collapse{overflow:hidden !important;text-overflow:ellipsis !important;white-space:nowrap !important;padding:5px 14px !important}.edit-status{display:inline-block;font-size:12px;color:#bababa;vertical-align:bottom;margin-right:5px}.cancel-action{padding:10px 35px}.delete-notice{text-align:center;font:16px / 22px ProximaNovaA-Semibold}.loader{position:relative}select{max-width:135px}#saved{background-color:#28a32e;color:#fff;margin-bottom:10px;padding:10px;border-radius:4px}.error-alert{border:1px solid #cc3239;background-color:#d75a60;padding:10px;border-radius:4px;margin:10px 0}.error-alert p{color:#fff;white-space:nowrap}.error-alert p.error-list{position:relative;left:20px}span.error-highlight input{border-color:#cc3239 !important;background-color:#f5d5d7}span.error-highlight .error-tag{border:1px solid #cc3239;background-color:#d14248;padding:4px;border-radius:4px;color:#fff;font-size:12px;vertical-align:middle;margin-left:10px;text-shadow:0 0 1px #000}#clear-search{font:14px / 16px ProximaNova-Regular;display:block;position:absolute;right:8px;top:-8px}tr>td{height:60px}.csv-note{margin:10px auto;width:565px}.csv-note p{margin:20px}.csv-note pre{font-size:14px;color:#444;margin-left:60px}.row{display:block;margin:20px auto;height:127px;width:855px}.row:first-of-type{margin-top:0}.row div{display:inline-block}.row .widget-manage-blocks{margin:0 10px}.report-stat{border:1px solid #e0e0e0;width:180px;height:100%;border-radius:4px;margin:0 10px;text-align:center;padding:18px 5px;background-color:#fff;vertical-align:top}.report-stat .stat-number{font:50px / 55px ProximaNova-Light;color:#c7c7c7}.report-stat .stat-description{font:14px / 16px ProximaNova-Bold}.reboot-message-wrapper{display:none;position:absolute;top:0;right:0;bottom:0;left:0}.reboot-message-wrapper .reboot-message{width:300px;background-color:#fff;text-align:center;padding:20px;border:1px solid #000;position:absolute}.reboot-message-wrapper .reboot-message img{width:60px;margin:10px auto}.reboot-message-wrapper .reboot-message .reboot-message-close{font-size:10px;float:right;display:none;position:relative;top:-18px;right:-16px;cursor:pointer}.reboot-message-wrapper .reboot-message .reboot-message-close:hover{color:#e0e0e0}#modal-refer-change_user_password{width:600px}#modal-refer-change_user_password .widget-table{width:100% !important}#modal-refer-change_user_password .widget-table input[type=password]{width:220px}td.first-time-user:hover{background-color:#fff !important}td.first-time-user div{width:600px;margin:30px auto 120px;text-align:center}td.first-time-user div p{font-size:20px;color:#adadad;line-height:34px;padding:60px 0}td.first-time-user div button{margin:0 10px}.inline-short{width:100px;display:inline-block}.inline-medium{max-width:261px;display:inline-block} \ No newline at end of file diff --git a/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_amex.png b/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_amex.png new file mode 100644 index 0000000..6075846 Binary files /dev/null and b/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_amex.png differ diff --git a/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_mc.png b/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_mc.png new file mode 100644 index 0000000..9bc5e28 Binary files /dev/null and b/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_mc.png differ diff --git a/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_visa.png b/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_visa.png new file mode 100644 index 0000000..7220716 Binary files /dev/null and b/django/apps/blue_management/blue_mgnt/static/img/payment_types/cc_visa.png differ diff --git a/django/apps/blue_management/blue_mgnt/static/js/billing.js b/django/apps/blue_management/blue_mgnt/static/js/billing.js new file mode 100644 index 0000000..4f8a1de --- /dev/null +++ b/django/apps/blue_management/blue_mgnt/static/js/billing.js @@ -0,0 +1,806 @@ +(function($, _, Backbone, swig){ + "use strict"; + var state; + var pager; + var alerter; + + var Templates = {}; + swig.setDefaults({ + varControls: ["<%-", "%>"], + tagControls: ["<%", "%>"], + cmtControls: ["<#", "#>"] + //loader: swig.loaders.memory(_templates) + }); + + _.each($("script[type='text/x-swig-template']"), function(el) { + var $el = $(el); + var id = _.str.strRight($el.attr("id"), "-"); + try { + Templates[id] = swig.compile(_.str.trim($el.html())); + } catch (err) { + console.debug(err); + console.log(err.source); + console.log(err.stack); + } + }); + + var scrollTo = function($el) { + $('html, body').stop().animate({ + scrollTop: $el.offset().top + }, 500); + }; + + var toCurrency = function(v) { + // v should already be appropriately rounded to 2 decimals. + // this method only handles string formatting + var ret = _.str.numberFormat(v, 2); + if (_.str.endsWith(ret, ".00")) { + return _.str.numberFormat(v, 0); + } + return ret; + }; + + var trim = String.prototype.trim ? function(s) { + return s.trim(); + } : function(s) { + return this.replace(/^\s+|\s+$/g, ''); + }; + + var $base = $("#billing-dropzone"); + + var COUPON_STATES = { + 'NONE': 0, + 'CHECKING': 1, + 'SUCCESS': 2, + 'FAILURE': 3, + 'ERROR': 4 + }; + + var COUPON_CACHE = {}; + + var calculate_price = function(quantity, frequency, coupon) { + var per, per_str; + var percent_off, cents_off; + if (frequency === "monthly") { + per = 5; + per_str = "/month"; + } else { + per = 60; + per_str = "/year"; + } + var cost = (per * quantity); + var coupon = COUPON_CACHE[coupon]; + if (coupon && coupon.state === COUPON_STATES.SUCCESS) { + if (coupon.data.percent_off) { + cost = Math.floor(cost * (100 - coupon.data.percent_off)) / 100; + } + if (coupon.data.cents_off) { + cost = (cost - (coupon.data.cents_off / 100)); + } + } + return { + 'int': (toCurrency(cost)), + 'str': (toCurrency(cost)) + per_str + }; + }; + + var BillingState = Backbone.Model.extend({ + defaults: { + quantity: 10, + frequency: "monthly", + coupon: null, + coupon_state: COUPON_STATES.NONE, + stripe_token: null, + stripe_type: null, + stripe_last4: null, + payment_method: "new", + has_current_plan: false, + has_cc: false + }, + initialize: function() { + if (SMB.current_plan_quantity && SMB.current_plan_frequency) { + this.set("has_current_plan", true); + this.set("quantity", SMB.current_plan_quantity); + this.set("frequency", SMB.current_plan_frequency.replace(/^smb_/, "")); + // assume that if they have a plan they have a cc on file + this.set("has_cc", true); + this.set("payment_method", "existing"); + } + this.on("change:coupon", this.onPromoCodeChange, this); + }, + onPromoCodeChange: function() { + var coupon_code = this.get("coupon"); + if (!coupon_code) { + this.set("coupon_state", COUPON_STATES.NONE); + return; + } + this.set("coupon_state", COUPON_STATES.CHECKING); + if (COUPON_CACHE[coupon_code]) { + this.set("coupon_state", COUPON_CACHE[coupon_code].state); + return; + } + var xhr = $.ajax("/billing/check_coupon", { + type: "POST", + data: { + 'coupon_code': coupon_code + } + }) + .done(function(data, status, xhr) { + if (data.valid) { + COUPON_CACHE[coupon_code] = {state: COUPON_STATES.SUCCESS, data: data}; + } else { + COUPON_CACHE[coupon_code] = {state: COUPON_STATES.FAILURE, data: null}; + } + }) + .fail(function(xhr, status, err) { + COUPON_CACHE[coupon_code] = {state: COUPON_STATES.ERROR, data: null}; + }) + .always(_.bind(function() { + if (this.get("coupon") === coupon_code) { + this.set("coupon_state", COUPON_CACHE[coupon_code].state); + } + }, this)); + } + }); + var Pager = Backbone.View.extend({ + initialize: function() { + this.pages = {}; + this.currPage = null; + }, + addPage: function(name, view) { + this.pages[name] = view; + view.render(); + view.$el.hide(); + this.$el.append(view.$el); + }, + switchTo: function(name) { + alerter.clear(); + var matched = false; + _.each(this.pages, function(view, key) { + if (key === name) { + view.$el.show(); + matched = true; + } else { + view.$el.hide(); + } + }, this); + if (!matched) { + console.log("No page " + name); + } else { + this.currPage = name; + this.trigger("switchTo", name); + } + } + }); + + var View = Backbone.View.extend({ + template: null, + modelTriggers: ["all"], + initialize: function(options) { + this.model = null; + if (options && options.model) { + this.model = options.model; + _.each(this.modelTriggers, function(spec) { + this.listenTo(this.model, spec, this.render); + }, this); + } + if (options && options.template) { + this.template = options.template; + } + if (_.isNull(Templates[this.template])) { + console.error("Warning, template doesn't exist: " + this.template); + } + _.result(this, "onInitialize"); + }, + render: function() { + var ctx = this.getContext(); + this.$el.html(Templates[this.template](ctx)); + this.$el.addClass(this.template); + _.result(this, "onRender"); + }, + getContext: function() { + return {}; + } + }); + + var AlertView = View.extend({ + template: "billing-alert", + clear: function() { + this.$("div").hide().attr("class", ""); + this.$("p").text(""); + }, + alert: function(msg) { + this.$("p").text(msg); + this.$("div").show().attr("class", "error-alert"); + scrollTo(this.$el); + } + }); + + var Nav = Backbone.View.extend({ + activeClass: "billing-nav-active", + initialize: function() { + this.$el.html(Templates["billing-nav"]()); + this.$el.addClass("billing-nav"); + }, + render: function(page) { + if (page) { + this.$("li").removeClass(this.activeClass); + this.$(".billing-nav-" + page).addClass(this.activeClass); + } + } + }); + + var PlanFrequencyView = View.extend({ + template: "billing-select-frequency", + events: { + "click li": "onFrequencySelect" + }, + onFrequencySelect: function(evt) { + evt.preventDefault(); + var $el = $(evt.currentTarget); + this.model.set("frequency", $el.attr("data-frequency")); + }, + getContext: function() { + return {}; + }, + onRender: function() { + var frequency = this.model.get("frequency"); + this.$("." + frequency + "-frequency").addClass("active"); + } + }); + + var CouponView = View.extend({ + template: "billing-select-coupon", + modelTriggers: ["change:coupon", "change:coupon_state"], + events: { + "submit form": "onFormSubmit" + }, + onRender: function() { + this.$("input").val(this.model.get("coupon")); + }, + onFormSubmit: function(evt) { + evt.preventDefault(); + alerter.clear(); + var $input = this.$("input"); + var val = $input.val(); + this.model.set("coupon", trim(val)); + }, + isValid: function() { + var coupon_state = this.model.get("coupon_state"); + return (coupon_state === COUPON_STATES.NONE || coupon_state === COUPON_STATES.SUCCESS); + }, + getContext: function() { + var msg, msg_class; + var coupon_state = this.model.get("coupon_state"); + switch (coupon_state) { + case COUPON_STATES.NONE: + break; + case COUPON_STATES.CHECKING: + msg = " Validating..." + msg_class = "progress"; + break; + case COUPON_STATES.SUCCESS: + msg = "Code accepted!"; + msg_class = "success"; + break; + case COUPON_STATES.FAILURE: + msg = "Invalid code"; + msg_class = "error"; + break; + case COUPON_STATES.ERROR: + msg = "An error occured"; + msg_class = "error"; + break; + } + return { + msg: msg, + msg_class: msg_class + }; + } + }); + + var CostPreviewView = View.extend({ + template: "billing-cost-preview", + getContext: function() { + var frequency = this.model.get("frequency"); + var quantity = this.model.get("quantity"); + var coupon = this.model.get("coupon"); + return { + has_current_plan: this.model.get("has_current_plan"), + frequency: frequency, + quantity: quantity, + price: calculate_price(quantity, frequency, coupon) + }; + }, + }); + + var NextView = View.extend({ + template: "billing-next", + events: { + "click button": "onClickNext" + }, + onClickNext: function(evt) { + evt.preventDefault(); + this.trigger("onClickNext"); + } + }); + + var BillingOverviewView = View.extend({ + template: "billing-overview", + events: { + "click .edit": "onClickEdit", + "click .billing-next button": "onFormSubmit", + }, + onFormSubmit: function(evt) { + evt.preventDefault(); + alerter.clear(); + if (this.model.get("has_cc") && this.model.get("payment_method") === "existing") { + pager.switchTo("loading"); + var xhr = $.ajax("/billing/create_subscription", { + type: "POST", + data: { + 'coupon': this.model.get("coupon"), + 'quantity': this.model.get("quantity"), + 'frequency': this.model.get("frequency"), + } + }) + .done(function(data, status, xhr) { + if (data.success) { + if (data.msg) { + $("#billing-success-message").text(data.msg); + } + pager.switchTo("success"); + alerter.clear(); + nav.$el.hide(); + } else { + pager.switchTo("summary"); + var msg = "There was an error contacting the server. Please try again later."; + if (data.msg) { + msg = data.msg; + } + alerter.alert(msg); + } + }) + .fail(function(data, status, xhr) { + pager.switchTo("summary"); + alerter.alert("There was an error contacting the server. Please try again later."); + }); + return; + } + var stripe_token = this.model.get("stripe_token"); + if (stripe_token) { + pager.switchTo("loading"); + var xhr = $.ajax("/billing/create_subscription", { + type: "POST", + data: { + 'coupon': this.model.get("coupon"), + 'quantity': this.model.get("quantity"), + 'frequency': this.model.get("frequency"), + 'stripe_token': stripe_token + } + }) + .done(function(data, status, xhr) { + if (data.success) { + if (data.msg) { + $("#billing-success-message").text(data.msg); + } + pager.switchTo("success"); + alerter.clear(); + } else { + pager.switchTo("summary"); + var msg = "There was an error contacting the server. Please try again later."; + if (data.msg) { + msg = data.msg; + } + alerter.alert(msg); + } + }) + .fail(function(data, status, xhr) { + pager.switchTo("summary"); + alerter.alert("There was an error contacting the server. Please try again later."); + }); + return; + } + pager.switchTo("summary"); + alerter.alert("There was an error with the form. Please try again later."); + }, + onClickEdit: function(evt) { + evt.preventDefault(); + var $el = $(evt.currentTarget); + var t = $el.attr("data-target"); + pager.switchTo(t); + }, + getContext: function() { + var frequency = this.model.get("frequency"); + var quantity = this.model.get("quantity"); + var coupon = this.model.get("coupon"); + if (this.model.get("payment_method") === "new") { + return { + has_current_plan: this.model.get("has_current_plan"), + quantity: quantity, + frequency: frequency, + cc_last4: this.model.get("stripe_last4"), + cc_type: this.model.get("stripe_type"), + price: calculate_price(quantity, frequency, coupon) + }; + } else { + return { + has_current_plan: this.model.get("has_current_plan"), + quantity: quantity, + frequency: frequency, + cc_last4: SMB.last4_on_file, + cc_type: "Card on file", + price: calculate_price(quantity, frequency, coupon) + }; + } + } + }); + + var PaymentMethodView = View.extend({ + template: "billing-payment-method", + events: { + "click li": "onMethodSelect" + }, + onMethodSelect: function(evt) { + evt.preventDefault(); + var $el = $(evt.currentTarget); + this.model.set("payment_method", $el.attr("data-method")); + }, + getContext: function() { + return {}; + }, + onRender: function() { + var method = this.model.get("payment_method"); + this.$(".payment-" + method).addClass("active"); + if (method === 'new') { + this.parentView.showCCForm(); + } else { + this.parentView.showOnFileForm(); + } + } + }); + + var StripePaymentView = View.extend({ + template: "billing-stripe-payment", + events: { + "click .billing-next button": "onFormSubmit", + "submit form": "onFormSubmit" + }, + showCCForm: function() { + var $form = this.$('.so-form'); + $(".cc-info", $form).show(); + $(".onfile-info", $form).hide(); + }, + showOnFileForm: function() { + var $form = this.$('.so-form'); + $(".cc-info", $form).hide(); + $(".onfile-info", $form).show(); + }, + onFormSubmit: function(evt) { + evt.preventDefault(); + alerter.clear(); + if (this.model.get("payment_method") === "existing") { + pager.switchTo("summary"); + return; + } + this.model.set({ + stripe_token: null, + stripe_last4: null, + stripe_type: null + }); + var name = this.$name.val(); + var cc = this.$cc.val(); + var csv = this.$csv.val(); + var exp_month = this.$exp_month.val(); + var exp_year = this.$exp_year.val(); + var tests = [this.checkCC(), this.checkCSV(), this.checkName(), this.checkExpiry()]; + if (_.all(tests)) { + Stripe.card.createToken({ + name: name, + number: cc, + cvc: csv, + exp_month: exp_month, + exp_year: exp_year + }, _.bind(this.onStripeResponse, this)); + } + }, + onStripeResponse: function(status, data) { + if (status === 200 && data.card) { + this.model.set({ + stripe_token: data.id, + stripe_last4: data.card.last4, + stripe_type: data.card.type + }); + pager.switchTo("summary"); + } else { + console.log(data); + } + }, + clearMessage: function($child) { + var $el = $child.closest("div").find("div"); + $el.attr("class", ""); + $el.find("p").text(""); + }, + showCCType: function($child, type) { + if (type) { + type = type.toLowerCase(); + } + var $el = $("div", $child.closest("div")); + var $p = $("p", $el); + $el.attr("class", ""); + $p.html(Templates["billing-cc-type"]()); + if (type) { + $("li[data-value=" + type + "]").addClass("active"); + } + }, + setMessage: function($child, msg_class, msg) { + var $el = $child.closest("div").find("div"); + if (msg_class) { + $el.attr("class", "alert alert-" + msg_class); + } else { + $el.attr("class", ""); + } + $el.find("p").html(msg); + $el.stop().hide().fadeIn(); + }, + checkName: function() { + var val = this.$name.val(); + var valid = false; + if (val) { + valid = true; + } + if (valid) { + this.clearMessage(this.$name); + } else { + this.setMessage(this.$name, "error", "Required field"); + } + return valid; + }, + checkCC: function() { + var val = this.$cc.val(); + var valid = Stripe.card.validateCardNumber(val); + var type = null; + if (valid) { + type = Stripe.card.cardType(val); + this.showCCType(this.$cc, type); + } else { + this.setMessage(this.$cc, "error", "Invalid Card Number"); + } + return valid; + }, + checkCSV: function() { + var val = this.$csv.val(); + var valid = Stripe.card.validateCVC(val); + if (valid) { + //this.setMessage(this.$csv, "success", ""); + this.clearMessage(this.$csv); + } else { + this.setMessage(this.$csv, "error", "Invalid CVC"); + } + return valid; + }, + checkExpiry: function() { + var mon = this.$exp_month.val(); + var year = this.$exp_year.val(); + var valid = Stripe.card.validateExpiry(mon, year); + if (valid) { + this.clearMessage(this.$exp_month); + } else { + this.setMessage(this.$exp_month, "error", "Invalid Expiration"); + } + return valid; + }, + initialize: function(options) { + this.options = options || {}; + this.$el.html(Templates[this.template]()); + this.$el.addClass(this.template); + this.$name = this.$("#stripe_name"); + this.$cc = this.$("#stripe_cc"); + this.$csv = this.$("#stripe_csv"); + this.$exp_month = this.$("#stripe_exp_month"); + this.$exp_year = this.$("#stripe_exp_year"); + + this.$cc.payment("formatCardNumber"); + this.$csv.payment("formatCardCVC"); + this.$cc.on("focus", _.bind(function(evt) { + var val = this.$cc.val(); + var valid = Stripe.card.validateCardNumber(val); + var type = null; + if (valid) { + type = Stripe.card.cardType(val); + } + this.showCCType(this.$cc, type); + }, this)); + this.$csv.on("focus", _.bind(function(evt) { + this.clearMessage(this.$csv); + }, this)); + this.$name.on("focus", _.bind(function(evt) { + this.clearMessage(this.$name); + }, this)); + this.$cc.on("change blur", _.bind(this.checkCC, this)); + this.$csv.on("change blur", _.bind(this.checkCSV, this)); + this.$name.on("change blur", _.bind(this.checkName, this)); + this.$exp_month.on("change blur", _.bind(this.checkExpiry, this)); + this.$exp_year.on("change blur", _.bind(this.checkExpiry, this)); + this.showCCType(this.$cc); + + if (!this.options.force_cc_mode) { + this.paymentMethod = new PaymentMethodView({model: this.model}); + this.paymentMethod.parentView = this; + if (this.model.get("has_cc")) { + this.paymentMethod.$el.prependTo(this.$(".so-form")); + } + } + }, + render: function(page) { + var now = new Date(); + this.$exp_month.val(now.getMonth() + 1); + this.$exp_year.val(now.getFullYear()); + if (this.paymentMethod) { + this.paymentMethod.render(); + } + } + }); + + var HistoryState = Backbone.Model.extend({ + pageOrder: ["plan", "payment", "summary"], + defaults: { + seenPage: 0 + }, + str2page: function(s) { + var ret = _.indexOf(this.pageOrder, s); + if (ret === -1) { + return null; + } + return ret; + }, + page2str: function(i) { + return this.pageOrder[i]; + }, + markSeen: function(page) { + var i = this.str2page(page); + this.set("seenPage", Math.max(this.get("seenPage"), i)); + }, + start: function(pager) { + this.pager = pager; + this.listenTo(this.pager, "switchTo", this.markSeen); + window.h = this; + if (history.pushState) { + this.bindHistory(); + } + }, + bindHistory: function() { + history.pushState(-1, null); + history.pushState(0, null); + window.addEventListener("popstate", _.bind(function(evt) { + if (evt.state === 1) { + // nothing to do for forward + } else if (evt.state === -1) { + if (this.handleBack()) { + history.go(-evt.state); + } else { + history.go(-2); + } + } + }, this), false); + }, + handleBack: function() { + var i = this.str2page(this.pager.currPage); + if (i === 0) { + return false; + } + if (i > 0) { + var page = this.page2str(i - 1); + this.pager.switchTo(page); + } + return true; + } + }); + + window.init_billing = function() { + state = new BillingState(); + pager = new Pager(); + pager.render(); + pager.addPage("plan", new View({template: "billing-plan"})); + pager.addPage("payment", new View({template: "billing-payment"})); + pager.addPage("summary", new View({template: "billing-summary"})); + pager.addPage("loading", new View({template: "billing-loading"})); + pager.addPage("success", new View({template: "billing-success"})); + + var couponview = new CouponView({model:state}); + var planfrequencyview = new PlanFrequencyView({model:state}); + var costpreview = new CostPreviewView({model:state}); + var nextview = new NextView({model:state}); + couponview.render(); + planfrequencyview.render(); + costpreview.render(); + nextview.render(); + + var stripepaymentview = new StripePaymentView({model: state}); + stripepaymentview.render(); + + var billingoverviewview = new BillingOverviewView({model: state}); + billingoverviewview.render(); + + var nav = new Nav(); + nav.render(); + nav.listenTo(pager, "switchTo", function(v) { + this.render(v); + }); + + alerter = new AlertView(); + alerter.render(); + + $base.append(nav.$el); + $base.append(alerter.$el); + $base.append(pager.$el); + pager.pages.plan.$el.append(planfrequencyview.$el); + pager.pages.plan.$el.append(couponview.$el); + pager.pages.plan.$el.append(costpreview.$el); + pager.pages.plan.$el.append(nextview.$el); + + pager.pages.payment.$el.append(stripepaymentview.$el); + + pager.pages.summary.$el.append(billingoverviewview.$el); + + nav.listenTo(pager, "switchTo", function(page) { + switch(page) { + case "success": + $(".page-header").hide(); + nav.$el.hide(); + case "loading": + this.$el.hide(); + break; + default: + this.$el.show(); + break; + } + }); + pager.listenTo(nextview, "onClickNext", function(){ + if (couponview.isValid()) { + this.switchTo("payment"); + scrollTo(pager.$el); + } else { + alerter.alert("Please enter a valid coupon"); + } + }); + + var historyState = new HistoryState(); + historyState.start(pager); + + pager.switchTo("plan"); + }; + + window.init_update_cc = function() { + state = new BillingState(); + state.set("payment_method", "new"); + pager = new Pager(); + pager.render(); + pager.addPage("payment", new View({template: "billing-payment"})); + pager.addPage("summary", new View({template: "billing-summary"})); + pager.addPage("loading", new View({template: "billing-loading"})); + pager.addPage("success", new View({template: "update-cc-success"})); + + var costpreview = new CostPreviewView({model:state}); + var nextview = new NextView({model:state}); + costpreview.render(); + nextview.render(); + + var stripepaymentview = new StripePaymentView({model: state, force_cc_mode: true}); + stripepaymentview.render(); + stripepaymentview.showCCForm(); + + var billingoverviewview = new BillingOverviewView({model: state, template: "update-cc-overview"}); + billingoverviewview.render(); + + alerter = new AlertView(); + alerter.render(); + + $base.append(alerter.$el); + $base.append(pager.$el); + + pager.pages.payment.$el.append(stripepaymentview.$el); + pager.pages.summary.$el.append(billingoverviewview.$el); + pager.switchTo("payment"); + }; +}(jQuery, _, Backbone, swig)); diff --git a/django/apps/blue_management/blue_mgnt/static/js/console.js b/django/apps/blue_management/blue_mgnt/static/js/console.js index 8de1554..b076a85 100644 --- a/django/apps/blue_management/blue_mgnt/static/js/console.js +++ b/django/apps/blue_management/blue_mgnt/static/js/console.js @@ -1,13 +1,21 @@ function posModal(obj) { obj = $(obj); if ( obj.is(':visible') ) { + + if ( obj.css('left') > 0 ) { + obj.css({ + 'left' : '0', + 'top' : '0' + }); + } pos_left = Math.round(($(window).width() - obj.outerWidth()) / 2) + ($(document).scrollLeft()); pos_top = Math.round(($(window).height() - obj.outerHeight()) / 2) + ($(document).scrollTop()); obj.css({ 'left' : pos_left, - 'top' : pos_top + 'top' : pos_top, + 'z-index' : '10000' }); } } @@ -15,7 +23,7 @@ function posModal(obj) { $(function() { // Shorten numeric inputs $(window).load(function() { - $input = $("input[type='text']").not('.widget-search-input, #id_username'); + $input = $("input[type='text']").not('.widget-search-input, #id_username, #promo_code_field'); var $size; $input.each(function() { if ( $(this).val().length < 1 ) { @@ -35,39 +43,70 @@ $(function() { posModal('.modal-content'); if ($('.widget-add-user .error-highlight').length) { $('.widget-add-user').show(); - $('.widget-add-user-option').hide(); } if ($('.widget-upload-csv .error-highlight').length) { $('.widget-upload-csv').show(); - $('.widget-add-user-option').hide(); } } - $('#add-widget').click(function(e){ + $('#add-widget').click(function(e){ //TODO: Depreciate this e.preventDefault(); $('.modal-wrapper').show().css('height', $(document).height()); posModal('.modal-content'); }); - $('#option-add-user button').click(function(){ - $('.widget-add-user-option').hide(); - $('.widget-add-user').show(); + $('[id^=modal-trigger-]').click(function(e) { + e.preventDefault(); + var this_id = $(this).attr('id'); + var this_name = this_id.lastIndexOf('-'); + var this_refer = '#modal-refer-' + this_id.substring(this_name + 1); + console.log(this_id + ',' + this_refer); + + var other_modals = $('[id^=modal-refer-]').not(this_refer); + if ( other_modals.is(':visible') ){ + other_modals.hide(); + } + + $(this_refer).closest('.modal-wrapper').show().css('height', $(document).height()); + $(this_refer).show(); + posModal(this_refer); }); - $('#option-upload-csv button').click(function(){ - $('.widget-add-user-option').hide(); - $('.widget-upload-csv').show(); - }); + (function() { + function exposeWidget(trgt){ + var $modal = $('.modal-wrapper'); + $(".modal-item", $modal).each(function(i, el) { + $el = $(el); + $el.toggle($el.hasClass(trgt)); + }); + $modal.show().css('height', $(document).height()); + posModal('.modal-content'); + } + + $('#option-add-user button').click(function(e){ + e.preventDefault(); + exposeWidget('widget-add-user'); + }); + + $('#option-upload-csv button').click(function(e){ + e.preventDefault(); + exposeWidget('widget-upload-csv'); + }); + }()); $('h2.page-header .actions').click(function() { + var thing = $(this).closest('[id^=modal-refer-]'); + thing.hide(); + console.log(thing.attr('id') + ' was hidden.'); $('.widget-add-user').hide() $('.widget-upload-csv').hide(); - $('.widget-add-user-option').show(); + $('.modal-wrapper .modal-item').hide(); $('.modal-wrapper').hide(); }); // Confirm delete $('.cancel-action').click(function() { + $(this).closest('[id^=modal-refer-]').hide(); $('.modal-wrapper').hide(); }); @@ -99,7 +138,7 @@ $(function() { 'position' : 'relative', 'z-index' : '1', }); - $('.shield').css({ + $('.shield').not('.reboot-message-wrapper').css({ 'position' : 'absolute', 'z-index' : '10000' }).toggle(); @@ -179,4 +218,19 @@ function getCookie(name) { return cookieValue; } var csrftoken = getCookie('csrftoken'); + +function csrfSafeMethod(method) { + // these HTTP methods do not require CSRF protection + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); +} + +$.ajaxSetup({ + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && !this.crossDomain) { + xhr.setRequestHeader("X-CSRFToken", csrftoken); + } + } }); +}); + +console.log("Console.js Loaded"); diff --git a/django/apps/blue_management/blue_mgnt/static/less/style.less b/django/apps/blue_management/blue_mgnt/static/less/style.less index 73db06d..dddf813 100644 --- a/django/apps/blue_management/blue_mgnt/static/less/style.less +++ b/django/apps/blue_management/blue_mgnt/static/less/style.less @@ -33,80 +33,86 @@ /* MIXINS */ .clear() { - &:after { - display: block; - clear: both; - content: ""; - } + &:after { + display: block; + clear: both; + content: ""; + } } .gradient(@col1; @col2) { - background-color: @col1; - background: -moz-linear-gradient(@col1, @col2); - background: -webkit-linear-gradient(@col1, @col2); - background: -o-linear-gradient(@col1, @col2); - background: linear-gradient(@col1, @col2); + background-color: @col1; + background: -moz-linear-gradient(@col1, @col2); + background: -webkit-linear-gradient(@col1, @col2); + background: -o-linear-gradient(@col1, @col2); + background: linear-gradient(@col1, @col2); } .inline_inputs() { - label { - font-family: @FONTFAMILY_SB; - } - input[type='text'], - select, - textarea, - input[type='password'] { - width: auto; - height: 30px; - border-radius: 5px; - border: 1px solid @NAVTAB_BORDER_COLOR; - padding-left: 12px; - color: @INPUT_EDIT_COLOR; - font: 13px~"/"23px @FONTFAMILY_R; - /* display: block; */ - } + label { + font-family: @FONTFAMILY_SB; + } + input[type='text'], + select, + textarea, + input[type='password'] { + width: auto; + height: 30px; + border-radius: 5px; + border: 1px solid @NAVTAB_BORDER_COLOR; + padding-left: 12px; + color: @INPUT_EDIT_COLOR; + font: 13px~"/"23px @FONTFAMILY_R; + /* display: block; */ + } - select { - max-width: 135px; - display: inline-block; - } + select { + max-width: 135px; + display: inline-block; + } - input[type='submit'] { - float: right; - position: relative; - right: 20px; - } + input[type='submit'] { + float: right; + position: relative; + right: 20px; + } } .widget-table-details { - tr { - td:first-of-type > label { - label { - font-family: @FONTFAMILY_SB; - } - } - } + width: 880px; + tr { + td:first-of-type > label { + label { + font-family: @FONTFAMILY_SB; + } + } + } } /* apply a natural box layout model to all elements */ *, *:before, *:after { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; } body { font-size: 16px; font-family: @FONTFAMILY_R; color: #505050; - text-rendering: optimizeLegibility; + text-rendering: optimizeLegibility; } h1, h2, h3, h4, h5, h6 { font-family: @FONTFAMILY_SB; color: #505050; + span.header-note { + float: right; + font-weight: normal; + font-size: 12px; + } } a { @@ -114,7 +120,7 @@ a { } strong, .strong, table thead th { - font-family: @FONTFAMILY_SB; + font-family: @FONTFAMILY_SB; } ::-webkit-input-placeholder { color: lighten(@INPUT_EDIT_COLOR, 32%) } @@ -169,14 +175,14 @@ header { float: left; color: #aeaeae; margin-left: 30px; - &.line { - border-left: 1px solid @NAVTAB_BORDER_COLOR; - padding: 0 10px 0 7px; - &:last-of-type { - border-right: 1px solid @NAVTAB_BORDER_COLOR; - margin-left: 6px; - } - } + &.line { + border-left: 1px solid @NAVTAB_BORDER_COLOR; + padding: 0 10px 0 7px; + &:last-of-type { + border-right: 1px solid @NAVTAB_BORDER_COLOR; + margin-left: 6px; + } + } a { cursor: pointer; color: #aeaeae; @@ -272,7 +278,7 @@ nav { li { display: inline-block; margin-left: 3em; - white-space: nowrap; + white-space: nowrap; i { margin-right: 5px; position: relative; @@ -293,53 +299,53 @@ div.breadcrumb { h1.page-header { height: @PAGEHEADER_HEIGHT; position: relative; - .clear(); + .clear(); .ss-icon { font-size: 23px; color: #929292; } .actions { float: right; - margin-bottom: 20px; - - form { - display: inline-block; - position: relative; - } + margin-bottom: 20px; + + form { + display: inline-block; + position: relative; + } - &:after { - display: block; - clear: both; - content:""; - } + &:after { + display: block; + clear: both; + content:""; + } - .widget-search-input { - width: 300px; - height: 39px; - border-radius: 5px; - border: 1px solid @NAVTAB_BORDER_COLOR; - padding-left: 12px; - color: @INPUT_EDIT_COLOR; - font: 15px~"/"19px @FONTFAMILY_R; - overflow: hidden; - } - .search-button { - height: 37px; - width: 34px; - font-size: 16px; - position: absolute; - top: 9px; - right: 1px; - background-color: lighten(@NAVTAB_BORDER_COLOR, 8%); - border: none; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - color: darken(@NAVTAB_BORDER_COLOR, 10%); - &:hover { - color: #FFF; - background-color: #929292; - } - } + .widget-search-input { + width: 300px; + height: 39px; + border-radius: 5px; + border: 1px solid @NAVTAB_BORDER_COLOR; + padding-left: 12px; + color: @INPUT_EDIT_COLOR; + font: 15px~"/"19px @FONTFAMILY_R; + overflow: hidden; + } + .search-button { + height: 37px; + width: 34px; + font-size: 16px; + position: absolute; + top: 9px; + right: 1px; + background-color: lighten(@NAVTAB_BORDER_COLOR, 8%); + border: none; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + color: darken(@NAVTAB_BORDER_COLOR, 10%); + &:hover { + color: #FFF; + background-color: #929292; + } + } } } @@ -382,7 +388,7 @@ h1.page-header { border: 1px solid #dddddd; background-color: #ffffff; font-size: 15px; - .clear(); + .clear(); &>thead>tr>th { padding: 16px 8px 4px 8px; border-bottom: 2px solid #dddddd; @@ -401,205 +407,204 @@ h1.page-header { &>tbody>tr>td { padding: 14px 4px 14px 8px; border-bottom: 1px solid #dddddd; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } &>tbody>tr:nth-child(odd) { background-color: @ZEBRA_STRIPE; } - input[type='text'], - select, - textarea, - input[type='password'] { - width: auto; - height: 30px; - border-radius: 5px; - border: 1px solid @NAVTAB_BORDER_COLOR; - padding-left: 7px; - color: @INPUT_EDIT_COLOR; - font: 13px~"/"23px @FONTFAMILY_R; - } - - td > label, - td > div > label { - font-family: @FONTFAMILY_B; - } + input[type='text'], + select, + textarea, + input[type='password'] { + width: auto; + height: 30px; + border-radius: 5px; + border: 1px solid @NAVTAB_BORDER_COLOR; + padding-left: 7px; + color: @INPUT_EDIT_COLOR; + font: 13px~"/"23px @FONTFAMILY_R; + } + + td > label, + td > div > label { + font-family: @FONTFAMILY_B; + } - li > label { - font-family: @FONTFAMILY_R; - } + li > label { + font-family: @FONTFAMILY_R; + } } .widget-manage-blocks { - width: 425px; - border: 1px solid @NAVTAB_BORDER_COLOR; - border-radius: 4px; - margin-bottom: 18px; - background-color: #FFF; - position: relative; - - .manage-icon { - font-size: 60px; - color: darken(@NAVTAB_BORDER_COLOR, 10%); - padding: 10px; - text-align: center; - vertical-align: top; - display: inline-block; - position: relative; - top: 18px; - left: 10px; - width: 24%; - - i { - margin:0 auto; - vertical-align: baseline; - } - } + width: 425px; + border: 1px solid @NAVTAB_BORDER_COLOR; + border-radius: 4px; + margin-bottom: 18px; + background-color: #FFF; + position: relative; + + .manage-icon { + font-size: 60px; + color: darken(@NAVTAB_BORDER_COLOR, 10%); + padding: 10px; + text-align: center; + vertical-align: top; + display: inline-block; + position: relative; + top: 18px; + left: 10px; + width: 24%; - div.manage-content { - border-left: 1px solid @NAVTAB_BORDER_COLOR; - padding: 10px 10px 10px 18px; - display: inline-block; - width: 65%; - position: relative; - left: 17px; - min-height: 125px; - - h3 { - font-size: 16px; - span { - float: right; - font-size: 10px; - font-family: @FONTFAMILY_R; - } - } - p { - font-size: 12px; - margin: 3px 0 8px; - min-height: 32px; - } - a.button { - display: inline-block; - width: 170px; - text-align: center; - padding: 8px 10px; - } - } + i { + margin:0 auto; + vertical-align: baseline; + } + } + + div.manage-content { + border-left: 1px solid @NAVTAB_BORDER_COLOR; + padding: 10px 10px 10px 18px; + display: inline-block; + width: 65%; + position: relative; + left: 17px; + min-height: 125px; + + h3 { + font-size: 16px; + span { + float: right; + font-size: 10px; + font-family: @FONTFAMILY_R; + } + } + p { + font-size: 12px; + margin: 3px 0 8px; + min-height: 32px; + } + a.button { + display: inline-block; + text-align: center; + padding: 8px 10px; + } + } } .widget-add-user { - display: none; + display: none; } .widget-add-user-option { - text-align: center; + text-align: center; } .modal-wrapper { - background-color:rgba(0,0,0,.5); - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - width: 100%; - height: 100%; - display: none; - z-index: 9000; + background-color:rgba(0,0,0,.5); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + display: none; + z-index: 9000; } .modal-content { - position: absolute; - width: 600px; - border: 1px solid @NAVTAB_BORDER_COLOR; - border-radius: 8px; - background-color: #FFF; - - &.confirm { - width: 330px; - h2 { - height: 45px; - } - } - - input#expiry_interval_days { - width: 100px; - display: inline; - } - .cancel-action { - position: relative; - left: 20px; - } + position: absolute; + width: 600px; + border: 1px solid @NAVTAB_BORDER_COLOR; + border-radius: 8px; + background-color: #FFF; + + &.confirm { + width: 330px; + h2 { + height: 45px; + } + } - .inline_inputs(); + input#expiry_interval_days { + width: 100px; + display: inline; + } + .cancel-action { + position: relative; + left: 20px; + } - .modal-table-label { - width: 30%; - padding-left: 20px; - } + .inline_inputs(); - h2.page-header { - border-bottom: 1px solid @NAVTAB_BORDER_COLOR; - text-align: left; - padding: 10px; - i { - padding-right: 10px; - font-size: 18px; - } + .modal-table-label { + width: 30%; + padding-left: 20px; + } - .actions { - float: right; - cursor: pointer; - margin-bottom: 20px; - &:hover { - color: lighten(@NAVTAB_BORDER_COLOR, 2%); - } - } - } + h2.page-header { + border-bottom: 1px solid @NAVTAB_BORDER_COLOR; + text-align: left; + padding: 10px; + i { + padding-right: 10px; + font-size: 18px; + } - .lower-content { - padding: 20px; + .actions { + float: right; + cursor: pointer; + margin-bottom: 20px; + &:hover { + color: lighten(@NAVTAB_BORDER_COLOR, 2%); + } + } + } - .description { - margin-bottom: 20px; - } + .lower-content { + padding: 20px; - } + .description { + margin-bottom: 20px; + } - .option-box { - position: relative; - display: inline-block; - margin: 10px; - border-radius: 4px; - border: 1px solid @NAVTAB_BORDER_COLOR; - text-align: center; - padding: 40px; + } - p { - font-family: @FONTFAMILY_SB; - margin-bottom: 20px; - } - } - .permissions { - ul { - height: 145px; - list-style: none; - column-fill: auto; - column-width: 140px; - column-gap: 0px; - -moz-column-fill: auto; - -moz-column-width: 140px; - -moz-column-gap: 0px; - -webkit-column-fill: auto; - -webkit-column-width: 140px; - -webkit-column-gap: 0px; - label { - font-size: 12px; - } - } - } + .option-box { + position: relative; + display: inline-block; + margin: 10px; + border-radius: 4px; + border: 1px solid @NAVTAB_BORDER_COLOR; + text-align: center; + padding: 40px; + + p { + font-family: @FONTFAMILY_SB; + margin-bottom: 20px; + } + } + .permissions { + ul { + height: 145px; + list-style: none; + column-fill: auto; + column-width: 140px; + column-gap: 0px; + -moz-column-fill: auto; + -moz-column-width: 140px; + -moz-column-gap: 0px; + -webkit-column-fill: auto; + -webkit-column-width: 140px; + -webkit-column-gap: 0px; + label { + font-size: 12px; + } + } + } } .widget-pagination { @@ -621,47 +626,47 @@ h1.page-header { } .widget-actions { - margin: 20px 0; - &.center-left { - width: 160px; - margin: 20px auto; - display: inline-block; - } - &.center-right { - width: 160px; - margin: 20px auto; - display: inline-block; - float: right; - } - &.short-right { - float: right; - width: 250px; - } - .rhs { - float: right; - } - .clear(); + margin: 20px 0; + &.center-left { + width: 160px; + margin: 20px auto; + display: inline-block; + } + &.center-right { + width: 160px; + margin: 20px auto; + display: inline-block; + float: right; + } + &.short-right { + float: right; + width: 250px; + } + .rhs { + float: right; + } + .clear(); } .widget-splitactions { - &.float { - width: 625px; - float: left; - margin: 20px 0; - } - form { - display: inline-block; - position: relative; - z-index: 1; - } - .rhs { - float: right; - } - .lhs { - a { - margin: 0 8px; - } - } + &.float { + width: 625px; + float: left; + margin: 20px 0; + } + form { + display: inline-block; + position: relative; + z-index: 1; + } + .rhs { + float: right; + } + .lhs { + a { + margin: 0 8px; + } + } } .widget-fieldset { @@ -688,370 +693,370 @@ h1.page-header { button, .button { font-family: @FONTFAMILY_B; font-size: 16px; - padding: 10px 15px; - text-decoration: none; + padding: 10px 15px; + text-decoration: none; cursor: pointer; - border-radius: 4px; - &.thin { - padding: 1px 18px; - font-family: @FONTFAMILY_R; - font-size: 14px; - } + border-radius: 4px; + &.thin { + padding: 1px 18px; + font-family: @FONTFAMILY_R; + font-size: 14px; + } } .button-primary-basic { color: #fff; background-color: #22A2D9; - border: 1px solid #22A2D9; - &:hover { - background-color: darken(#22A2D9, 2%); - } + border: 1px solid #22A2D9; + &:hover { + background-color: darken(#22A2D9, 2%); + } } .button-secondary { color: #fff; background-color: #CF3940; - border: 1px solid #CF3940; - &:hover { - background-color: darken(#CF3940, 2%); - } + border: 1px solid #CF3940; + &:hover { + background-color: darken(#CF3940, 2%); + } } .button-muted { color: #fff; background-color: #a0a0a0; - border: 1px solid #a0a0a0; - &:hover { - background-color: darken(#a0a0a0, 2%); - } + border: 1px solid #a0a0a0; + &:hover { + background-color: darken(#a0a0a0, 2%); + } } /* Special case */ .code-extra-info { - margin-top: 8px; + margin-top: 8px; } #usage-report { - width: 520px; - text-align: center; - margin: 20px auto; + width: 520px; + text-align: center; + margin: 20px auto; } body.home { - td:first-of-type { - input { - width: 130px; - } - } - .delete-fill { - color: #aeaeae; - } + td:first-of-type { + input { + width: 130px; + } + } + .delete-fill { + color: #aeaeae; + } } body.errors { - text-align: center; - .content { - margin: 18% auto; - } - h1 { - font:42px~"/"62px ProximaNova-Light; - margin-bottom: 20px; - } - p { - font:18px~"/"22px @FONTFAMILY_R; - a { - text-decoration: none; - &:hover { - text-decoration: underline; - } - } - } + text-align: center; + .content { + margin: 18% auto; + } + h1 { + font:42px~"/"62px ProximaNova-Light; + margin-bottom: 20px; + } + p { + font:18px~"/"22px @FONTFAMILY_R; + a { + text-decoration: none; + &:hover { + text-decoration: underline; + } + } + } } .log-toggle { - font-size: 8px; - cursor: pointer; + font-size: 8px; + cursor: pointer; } .start-pos, .end-pos { } #delete-group { - th { - width: 30%; - } + th { + width: 30%; + } } .user_detail { - .widget-table { - table-layout: fixed; - } + .widget-table { + table-layout: fixed; + } } body.logs .widget-table td { - overflow: visible; - text-overflow: clip; - white-space: normal; - padding: 5px 14px; - font: 12px~'/'22px monospace; + overflow: visible; + text-overflow: clip; + white-space: normal; + padding: 5px 14px; + font: 12px~'/'22px monospace; } header li>a[href='/logout/']:hover, header li>a[href='']:hover { - color: lighten(#aeaeae, 7%); + color: lighten(#aeaeae, 7%); } .permissions { - td { - vertical-align: top; - } - ul { - min-height: 145px; - column-fill: auto; - column-width: 180px; - column-gap: 0px; - -moz-column-fill: auto; - -moz-column-width: 180px; - -moz-column-gap: 0px; - -webkit-column-fill: auto; - -webkit-column-width: 180px; - -webkit-column-gap: 0px; - } + td { + vertical-align: top; + } + ul { + min-height: 145px; + column-fill: auto; + column-width: 180px; + column-gap: 0px; + -moz-column-fill: auto; + -moz-column-width: 180px; + -moz-column-gap: 0px; + -webkit-column-fill: auto; + -webkit-column-width: 180px; + -webkit-column-gap: 0px; + } } .group_detail { - .widget-table { - tr > td:last-of-type, - tr > td:first-of-type { - width: 25%; - } - } + .widget-table { + tr > td:last-of-type, + tr > td:first-of-type { + width: 25%; + } + } } .shares_detail { - .widget-table { - tr > td:first-of-type { - width: 28%; - } - } + .widget-table { + tr > td:first-of-type { + width: 28%; + } + } } #add_ip_block { - margin-left: 20px; + margin-left: 20px; } body.admin_groups { - th { - width: 22%; - &#perms { - width: 38%; - } - &:last-child { - width: 90px; - } - } - td { - vertical-align: top; - } + th { + width: 22%; + &#perms { + width: 38%; + } + &:last-child { + width: 90px; + } + } + td { + vertical-align: top; + } } .radio-submit { - &:nth-of-type(2) { - margin:0 1px 0 14px; - } - vertical-align: middle; - margin:0 1px; + &:nth-of-type(2) { + margin:0 1px 0 14px; + } + vertical-align: middle; + margin:0 1px; } /* login & password*/ - .error { - color: #CC3239; - } + .error { + color: #CC3239; + } body.login { - h1 { - font-family: ProximaNovaT-Thin; - font-size: 42px; - text-align: center; - margin-bottom: 30px; - } - h2 { - font-family: ProximaNova-Light; - text-align: center; - font-size: 20px; - } - h3 { - font-family: ProximaNova-Regular; - font-weight: 100; - font-size: 22px; - line-height: 48px; - } - .content { - margin: 4% auto; - } - .clear(); - .login-wrapper { - margin: 3% auto; - width: 750px; - background-color: #fff; - .right-col { - width: 385px; - margin-left: 50px; - div:first-of-type { - margin-bottom: 40px; - } - img { - float: left; - margin-right: 18px; - margin-bottom: 85px; - position: relative; - top: 18px; - } - } - } + h1 { + font-family: ProximaNovaT-Thin; + font-size: 42px; + text-align: center; + margin-bottom: 30px; + } + h2 { + font-family: ProximaNova-Light; + text-align: center; + font-size: 20px; + } + h3 { + font-family: ProximaNova-Regular; + font-weight: 100; + font-size: 22px; + line-height: 48px; + } + .content { + margin: 4% auto; + } + .clear(); + .login-wrapper { + margin: 3% auto; + width: 750px; + background-color: #fff; + .right-col { + width: 385px; + margin-left: 50px; + div:first-of-type { + margin-bottom: 40px; + } + img { + float: left; + margin-right: 18px; + margin-bottom: 85px; + position: relative; + top: 18px; + } + } + } } body.password { - .login-wrapper { - margin-top: 50px; - background-color: #fff; - width: 860px; - padding: 45px 0 0 45px; - position: relative; - top: -20px; - .login-form-wrapper { - input:first-of-type { - margin-bottom: 20px; - } - } - .right-col { - h3 { - font-family: ProximaNova-Regular; - font-weight: 100; - font-size: 22px; - line-height: 48px; - } - width: 385px; - margin-left: 75px; - margin-top: 18px; - div:first-of-type { - margin-bottom: 40px; - } - img { - float: left; - margin-right: 18px; - margin-bottom: 85px; - position: relative; - top: 18px; - } - } - } + .login-wrapper { + margin-top: 50px; + background-color: #fff; + width: 860px; + padding: 45px 0 0 45px; + position: relative; + top: -20px; + .login-form-wrapper { + input:first-of-type { + margin-bottom: 20px; + } + } + .right-col { + h3 { + font-family: ProximaNova-Regular; + font-weight: 100; + font-size: 22px; + line-height: 48px; + } + width: 385px; + margin-left: 75px; + margin-top: 18px; + div:first-of-type { + margin-bottom: 40px; + } + img { + float: left; + margin-right: 18px; + margin-bottom: 85px; + position: relative; + top: 18px; + } + } + } } body.login, body.errors, body.password { - .image-wrapper { - width: 120px; - margin: 2% auto; - img { - width: 120px; - } + .image-wrapper { + width: 120px; + margin: 2% auto; + img { + width: 120px; + } - } - .inline_inputs(); - - .widget-login { - label { - display: block; - text-transform: uppercase; - font-family: @FONTFAMILY_R; - font-size: 14px; - color: darken(@NAVTAB_BORDER_COLOR, 16%); - } - input[type='text'], - input[type='password'] { - width: 300px; - height: 40px; - font-size: 18px; - } - } - input[type='submit'] { - padding: 12px 30px; - float: left; - right: 0; - font-size: 16px; - } + } + .inline_inputs(); + + .widget-login { + label { + display: block; + text-transform: uppercase; + font-family: @FONTFAMILY_R; + font-size: 14px; + color: darken(@NAVTAB_BORDER_COLOR, 16%); + } + input[type='text'], + input[type='password'] { + width: 300px; + height: 40px; + font-size: 18px; + } + } + input[type='submit'] { + padding: 12px 30px; + float: left; + right: 0; + font-size: 16px; + } } /* Usage Info Bar */ .widget-usage-info { - width: 520px; - position: relative; - top: -30px; - - .digits { - text-align: center; - width: 100%; - margin: 0 auto; - p { - width: 100px; - display: inline; - font-size: 12px; - - &.space-used { - color: @NAVTAB_BGCOLOR_USERS; - font-family: @FONTFAMILY_B; - - span { - font-family: @FONTFAMILY_R; - } - } - &.space-allocated { - color: @NAVTAB_BGCOLOR_REPORTS; - font-family: @FONTFAMILY_B; - - span { - font-family: @FONTFAMILY_R; - } - } - } - } - .usage-bar-wrapper { - position: relative; - overflow: hidden; - height: 24px; - width: 518px; - .gradient(@NAVTAB_BGCOLOR_REPORTS; @NAVTAB_BGCOLOR_MANAGE); - border-radius: 4px; - border: 1px solid @NAVTAB_BORDER_COLOR; - - .usage-bar-space-used { - position: absolute; - height: 26px; - width: 519px; - top: -1px; - .gradient(@NAVTAB_BGCOLOR_SHARES; @NAVTAB_BGCOLOR_USERS); - - &.usage-warning { - .gradient(#FCDC3B; darken(#FCDC3B, 14%)); - } - - &.usage-danger { - .gradient(#FF0000; darken(#FF0000, 14%)); - span { - color: #ffffff; - font: 14px~'/'16px @FONTFAMILY_R; - float: right; - padding: 4px; - margin-right: 10px; - text-shadow: #5E2612 1px 1px 4px; - } - } - } - } + width: 520px; + position: relative; + top: -30px; + + .digits { + text-align: center; + width: 100%; + margin: 0 auto; + p { + width: 100px; + display: inline; + font-size: 12px; + + &.space-used { + color: @NAVTAB_BGCOLOR_USERS; + font-family: @FONTFAMILY_B; + + span { + font-family: @FONTFAMILY_R; + } + } + &.space-allocated { + color: @NAVTAB_BGCOLOR_REPORTS; + font-family: @FONTFAMILY_B; + + span { + font-family: @FONTFAMILY_R; + } + } + } + } + .usage-bar-wrapper { + position: relative; + overflow: hidden; + height: 24px; + width: 518px; + .gradient(@NAVTAB_BGCOLOR_REPORTS; @NAVTAB_BGCOLOR_MANAGE); + border-radius: 4px; + border: 1px solid @NAVTAB_BORDER_COLOR; + + .usage-bar-space-used { + position: absolute; + height: 26px; + width: 519px; + top: -1px; + .gradient(@NAVTAB_BGCOLOR_SHARES; @NAVTAB_BGCOLOR_USERS); + + &.usage-warning { + .gradient(#FCDC3B; darken(#FCDC3B, 14%)); + } + + &.usage-danger { + .gradient(#FF0000; darken(#FF0000, 14%)); + span { + color: #ffffff; + font: 14px~'/'16px @FONTFAMILY_R; + float: right; + padding: 4px; + margin-right: 10px; + text-shadow: #5E2612 1px 1px 4px; + } + } + } + } } /* tags */ @@ -1065,7 +1070,7 @@ body.password { } .enabled { - font-weight: bold; + font-weight: bold; } /* utility classes */ @@ -1077,265 +1082,643 @@ body.password { } .left-col { - display: inline-block; - margin-right: 9px; - vertical-align: top; + display: inline-block; + margin-right: 9px; + vertical-align: top; } .right-col { - display: inline-block; - margin-left: 9px; - vertical-align: top; + display: inline-block; + margin-left: 9px; + vertical-align: top; } .set-top { - vertical-align: top; + vertical-align: top; } .permissions-options { - max-width: 180px; - display: inline-block; - font-size: 12px; + max-width: 180px; + display: inline-block; + font-size: 12px; } .space-20none { - margin: 20px 0; + margin: 20px 0; } #hint { - white-space: normal; - overflow: visible; - span { - font-size: 12px; - } + white-space: normal; + overflow: visible; + span { + font-size: 12px; + } } .link-primary { - font-family: @FONTFAMILY_B; - color: @NAVTAB_BGCOLOR_SHARES; - &:visited { - color: @NAVTAB_BGCOLOR_SHARES; - } + font-family: @FONTFAMILY_B; + color: @NAVTAB_BGCOLOR_SHARES; + &:visited { + color: @NAVTAB_BGCOLOR_SHARES; + } } .toggle-controller { - cursor: pointer; - font-size: 14px; - i { - font-size: 8px; - } - &:hover { - text-decoration: underline; - } + cursor: pointer; + font-size: 14px; + i { + font-size: 8px; + } + &:hover { + text-decoration: underline; + } } .status-message { - background-color: #fff; - border-radius: 4px; - border: 1px solid @NAVTAB_BORDER_COLOR; - max-width: 800px; - margin: 20px auto; - padding: 10px; - display: inline-block; - .actions { - float: right; - cursor: pointer; - &:hover { - color: lighten(@NAVTAB_BORDER_COLOR, 2%); - } - } - .status-content { - code { - font-size: 12px; - } - } - i { - vertical-align: middle; - margin-right: 12px; - font-size: 18px; - } + background-color: #fff; + border-radius: 4px; + border: 1px solid @NAVTAB_BORDER_COLOR; + max-width: 800px; + margin: 20px auto; + padding: 10px; + display: inline-block; + .actions { + float: right; + cursor: pointer; + &:hover { + color: lighten(@NAVTAB_BORDER_COLOR, 2%); + } + } + .status-content { + code { + font-size: 12px; + } + } + i { + vertical-align: middle; + margin-right: 12px; + font-size: 18px; + } - h2 { - border-bottom: 1px solid @NAVTAB_BORDER_COLOR; - } + h2 { + border-bottom: 1px solid @NAVTAB_BORDER_COLOR; + } } .shield { - position: absolute; - z-index: 10000; - height: 100%; - width: 100%; - background-color: rgba(240, 240, 240, .7); - top: 0; - left: 0; - right: 0; - bottom: 0; + position: absolute; + z-index: 10000; + height: 100%; + width: 100%; + background-color: rgba(240, 240, 240, .7); + top: 0; + left: 0; + right: 0; + bottom: 0; } .collapse { - overflow: hidden!important; - text-overflow: ellipsis!important; - white-space: nowrap!important; - padding: 5px 14px!important; + overflow: hidden!important; + text-overflow: ellipsis!important; + white-space: nowrap!important; + padding: 5px 14px!important; } .edit-status { - display: inline-block; - font-size: 12px; - color: darken(@NAVTAB_BORDER_COLOR, 15%); - vertical-align: bottom; - margin-right: 5px; + display: inline-block; + font-size: 12px; + color: darken(@NAVTAB_BORDER_COLOR, 15%); + vertical-align: bottom; + margin-right: 5px; } .cancel-action { - padding: 10px 35px; + padding: 10px 35px; } .delete-notice { - text-align: center; - font: 16px~"/"22px @FONTFAMILY_SB; + text-align: center; + font: 16px~"/"22px @FONTFAMILY_SB; } .loader { - position: relative; + position: relative; } select { - max-width: 135px; + max-width: 135px; } #saved { - background-color: darken(#32CC39, 10%); - color: #fff; - margin-bottom: 10px; - padding: 10px; - border-radius: 4px; -} - - .error-alert { - border: 1px solid #CC3239; - background-color: lighten(#CC3239, 10%); - padding: 10px; - border-radius: 4px; - margin: 10px 0; - p { - color: #fff; - white-space: nowrap; - &.error-list { - position: relative; - left: 20px; - } - } + background-color: darken(#32CC39, 10%); + color: #fff; + margin-bottom: 10px; + padding: 10px; + border-radius: 4px; +} + +.error-alert { + border: 1px solid #CC3239; + background-color: lighten(#CC3239, 10%); + padding: 10px; + border-radius: 4px; + margin: 10px 0; + p { + color: #fff; + white-space: nowrap; + &.error-list { + position: relative; + left: 20px; + } + } } span.error-highlight { - input { - border-color: #CC3239!important; - background-color: lighten(#CC3239, 40%); - } - .error-tag { - border: 1px solid #CC3239; - background-color: lighten(#CC3239, 4%); - padding: 4px; - border-radius: 4px; - color: #fff; - font-size: 12px; - vertical-align: middle; - margin-left: 10px; - text-shadow: 0 0 1px #000; - } + input { + border-color: #CC3239!important; + background-color: lighten(#CC3239, 40%); + } + .error-tag { + border: 1px solid #CC3239; + background-color: lighten(#CC3239, 4%); + padding: 4px; + border-radius: 4px; + color: #fff; + font-size: 12px; + vertical-align: middle; + margin-left: 10px; + text-shadow: 0 0 1px #000; + } } #clear-search { - font: 14px~"/"16px ProximaNova-Regular; - display: block; - position: absolute; - right: 8px; - top: -8px; + font: 14px~"/"16px ProximaNova-Regular; + display: block; + position: absolute; + right: 8px; + top: -8px; } tr > td { - height: 60px; + height: 60px; } .csv-note { - margin: 10px auto; - width: 565px; - p { - margin: 20px; - } - pre { - font-size: 14px; - color: #444; - margin-left: 60px; - } + margin: 10px auto; + width: 565px; + p { + margin: 20px; + } + pre { + font-size: 14px; + color: #444; + margin-left: 60px; + } } .row { - display: block; - margin: 20px auto; - height: 127px; - width: 855px; - &:first-of-type { - margin-top: 0; - } - div { - display: inline-block; - } - - .widget-manage-blocks { - margin: 0 10px; - } + display: block; + margin: 20px auto; + height: 127px; + width: 855px; + &:first-of-type { + margin-top: 0; + } + div { + display: inline-block; + } + + .widget-manage-blocks { + margin: 0 10px; + } } .report-stat { - border: 1px solid @NAVTAB_BORDER_COLOR; - width: 180px; - height: 100%; - border-radius: 4px; - margin: 0 10px; - text-align: center; - padding: 18px 5px; - background-color: #fff; - vertical-align: top; - - .stat-number { - font: 50px~"/"55px ProximaNova-Light; - color: darken(@NAVTAB_BORDER_COLOR, 10%); - } - - .stat-description { - font: 14px~"/"16px @FONTFAMILY_B; - } + border: 1px solid @NAVTAB_BORDER_COLOR; + width: 180px; + height: 100%; + border-radius: 4px; + margin: 0 10px; + text-align: center; + padding: 18px 5px; + background-color: #fff; + vertical-align: top; + + .stat-number { + font: 50px~"/"55px ProximaNova-Light; + color: darken(@NAVTAB_BORDER_COLOR, 10%); + } + + .stat-description { + font: 14px~"/"16px @FONTFAMILY_B; + } } .reboot-message-wrapper { - display: none; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - .reboot-message { - width: 300px; - background-color: #fff; + display: none; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + .reboot-message { + width: 300px; + background-color: #fff; + text-align: center; + padding: 20px; + border: 1px solid #000; + position: absolute; + img { + width: 60px; + margin: 10px auto; + } + .reboot-message-close { + font-size: 10px; + float: right; + display: none; + position: relative; + top: -18px; + right: -16px; + cursor: pointer; + &:hover { + color: @NAVTAB_BORDER_COLOR; + } + } + } + } + + #modal-refer-change_user_password { + width: 600px; + .widget-table { + width: 100%!important; + input[type=password] { + width: 220px; + } + } +} + + td.first-time-user { + &:hover { + background-color: #fff!important; + } + div { + width: 600px; + margin: 30px auto 120px; text-align: center; - padding: 20px; - border: 1px solid #000; - position: absolute; - img { - width: 60px; - margin: 10px auto; + p { + font-size: 20px; + color: darken(@NAVTAB_BORDER_COLOR, 20%); + line-height: 34px; + padding: 60px 0; } - .reboot-message-close { - font-size: 10px; - float: right; - display: none; - position: relative; - top: -18px; - right: -16px; - cursor: pointer; - &:hover { - color: @NAVTAB_BORDER_COLOR; - } + button { + margin: 0 10px; } - } + } + + } + + .inline-short { + width: 100px; + display: inline-block; } + + .inline-medium { + max-width: 261px; + display: inline-block; + } +.billing { + .billing-nav { + @ORDERNAV_WIDTH: 700px; + @ORDERITEM_WIDTH: 45px; + @ORDERITEM_PAD: 5px; + + @ORDERITEM_OUTER: @ORDERITEM_WIDTH + (@ORDERITEM_PAD * 2); + @ORDERITEM_OUTER_HALF: @ORDERITEM_OUTER / 2; + + width: @ORDERNAV_WIDTH; + margin: 60px auto 80px auto; + position: relative; + border: 2px solid #999; + color: #999; + ul { + list-style-type: none; + } + li { + position: absolute; + top: -@ORDERITEM_OUTER_HALF; + &.billing-nav-1 { + left: -@ORDERITEM_OUTER_HALF; + } + &.billing-nav-2 { + left: (@ORDERNAV_WIDTH/2) - @ORDERITEM_OUTER_HALF; + } + &.billing-nav-3 { + right: -@ORDERITEM_OUTER_HALF; + } + span { + display: block; + width: @ORDERITEM_OUTER + 2; + height: @ORDERITEM_OUTER + 2; + .border-radius(@ORDERITEM_OUTER_HALF); + padding: @ORDERITEM_PAD; + background-color: #fff; + border: 1px solid #999; + a { + text-decoration: none; + font-family: @FONTFAMILY_B; + display: block; + width: @ORDERITEM_WIDTH; + height: @ORDERITEM_WIDTH; + .border-radius(@ORDERITEM_WIDTH/2); + background-color: #999; + text-align: center; + line-height: @ORDERITEM_WIDTH; + font-size: 23px; + color: #fff; + } + } + &.billing-nav-active span a { + background-color: #22A2D9; + } + & > a { + font-family: @FONTFAMILY_B; + position: absolute; + display: block; + width: @ORDERITEM_OUTER * 3; + text-align: center; + left: -@ORDERITEM_OUTER; + padding-top: 5px; + text-decoration: none; + color: #999; + } + &.billing-nav-active > a { + color: #22A2D8; + } + } + } + .billing-select-size { + p.size-note { + text-align: center; + font-size: 18px; + margin-top: 20px; + margin-bottom: 30px; + } + .plans { + width: 940px; + position: relative; + margin-top: 10px; + left: -20px; + ul { + list-style-type: none; + li { + cursor: pointer; + font-family: @FONTFAMILY_B; + text-align: center; + border: 1px solid #ccc; + color: #999; + float: left; + width: 130px; + height: 72px; + margin-left: 21px; + margin-bottom: 20px; + } + li:hover, li.active { + background-color: #4c4c4c; + color: #fff; + } + li p { + display: block; + font-size: 19px; + line-height: 20px; + margin-top: 18px; + } + li span { + display: block; + font-size: 14px; + margin-top: 1px; + } + li.over-two-hundred { + span { + font-size: 12px; + } + } + } + } + } + .billing-select-frequency, .billing-payment-method { + margin-bottom: 30px; + ul { + list-style-type: none; + li { + cursor: pointer; + float: left; + font-family: @FONTFAMILY_B; + font-size: 19px; + text-align: center; + border: 1px solid #ccc; + color: #999; + height: 72px; + width: 427px; + line-height: 72px; + } + li:hover, li.active { + background-color: #4c4c4c; + color: #fff; + } + li.monthly-frequency, li.payment-new { + margin-left: 23px; + } + } + } + .billing-select-coupon { + margin-bottom: 30px; + h2 span { + font-size: 18px; + font-family: @FONTFAMILY_R; + margin-left: 10px; + position: relative; + top: -3px; + } + input { + float: left; + } + .button { + float: left; + margin-left: 20px; + } + .alert { + width: 380px; + } + } + .billing-cost-preview { + h3 { + padding: 1em; + } + } + .select-total { + } + #show_more { + a { + float: right; + position: relative; + top: -8px; + cursor: pointer; + text-decoration: underline; + } + } + .payment-memo { + text-align: right; + float: right; + margin-right: 20px; + margin-top: 6px; + font-size: 13px; + } + .billing-stripe-payment { + .alert { + width: 350px; + } + .cc_type { + position: absolute; + top: 0px; + right: 0px; + height: 100%; + width: 360px; + color: #fff; + list-style-type: none; + } + .cc_type ul { + line-height: 47px; + padding: 20px 0px; + } + .cc_type li { + float: left; + margin-right: 5px; + opacity: 0.05; + } + .cc_type li.active { + opacity: 1; + } + } + .billing-next { + margin-top: 1em; + button { + float: right; + } + p { + clear: both; + float: right; + text-align: right; + } + } + .billing-summary { + fieldset { + margin-bottom: 20px; + label { + color: #4c4c4c; + float: left; + line-height: 34px; + } + p { + float: left; + line-height: 34px; + color: #999; + } + span.edit { + float: right; + line-height: 34px; + a { + text-decoration: none; + color: #22A2D9; + } + } + .billing-summary-total { + background-color: #e8e8e8; + p { + color: #4c4c4c; + } + } + } + .next-payment-notification { + margin-bottom: 20px; + } + } +} + +.so-form { + fieldset { + background-color: #fff; + margin-bottom: 10px; + border: 1px solid #ccc; + .border-radius(2px); + & > div { + border-top: 1px solid #ccc; + padding: 20px; + position: relative; + .alert { + position: absolute; + top: 0px; + right: 0px; + height: 100%; + color: #fff; + p { + line-height: 47px; + font-family: @FONTFAMILY_B; + padding: 20px; + } + } + .alert-error { + background-color: #C72027; + border-left: 4px solid #951A1F; + } + .alert-success { + background-color: #8AC721; + border-left: 4px solid #689715; + } + .alert-progress { + color: #333; + background-color: #ccc; + border-left: 4px solid #999; + } + } + & > div:first-child { + border-top: none; + } + label { + font-family: @FONTFAMILY_B; + font-size: 18px; + display: inline-block; + width: 165px; + } + input, select { + font-family: @FONTFAMILY_R; + padding: 10px; + color: #999; + font-size: 18px; + } + input { + width: 310px; + border: 1px solid #ccc; + .border-radius(3px); + } + .radio-form-field input { + width: auto; + } + input.disabled { + border: none; + background-color: transparent; + } + } + .bubbly_strongs { + color: #999; + line-height: 34px; + strong { + margin: 0px 10px; + .border-radius(5px); + padding: 10px; + font-size: 16px; + font-family: @FONTFAMILY_B; + line-height: 34px; + color: #fff; + background-color: #4c4c4c; + } + } +} diff --git a/django/apps/blue_management/blue_mgnt/static/vendor/backbone-min.js b/django/apps/blue_management/blue_mgnt/static/vendor/backbone-min.js new file mode 100644 index 0000000..8ea4b13 --- /dev/null +++ b/django/apps/blue_management/blue_mgnt/static/vendor/backbone-min.js @@ -0,0 +1,2 @@ +(function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('