webapp now uses twitter bootstrap

mocked up the main screen, and am actually pretty happy with it!
This commit is contained in:
Joey Hess 2012-07-27 04:48:50 -04:00
parent 1192e305c7
commit 7e3c1e008d
13 changed files with 877 additions and 408 deletions

View file

@ -47,11 +47,16 @@ mkYesod "WebApp" [parseRoutes|
|] |]
instance Yesod WebApp where instance Yesod WebApp where
defaultLayout contents = do defaultLayout widget = do
page <- widgetToPageContent contents
mmsg <- getMessage mmsg <- getMessage
webapp <- getYesod webapp <- getYesod
hamletToRepHtml $(hamletFile $ hamletTemplate "default-layout") page <- widgetToPageContent $ do
addStylesheet $ StaticR css_bootstrap_css
addStylesheet $ StaticR css_bootstrap_responsive_css
addScript $ StaticR jquery_full_js
addScript $ StaticR js_bootstrap_dropdown_js
$(widgetFile "default-layout")
hamletToRepHtml $(hamletFile $ hamletTemplate "bootstrap")
{- Require an auth token be set when accessing any (non-static route) -} {- Require an auth token be set when accessing any (non-static route) -}
isAuthorized _ _ = checkAuthToken secretToken isAuthorized _ _ = checkAuthToken secretToken
@ -68,7 +73,7 @@ instance Yesod WebApp where
{- Add to any widget to make it auto-update. {- Add to any widget to make it auto-update.
- -
- The widget should have a html element with id=poll, which will be - The widget should have a html element with id=updating, which will be
- replaced when it's updated. - replaced when it's updated.
- -
- Updating is done by getting html from the gethtml route. - Updating is done by getting html from the gethtml route.
@ -80,7 +85,7 @@ instance Yesod WebApp where
- state. - state.
-} -}
autoUpdate :: Text -> Route WebApp -> Route WebApp -> Int -> Int -> Widget autoUpdate :: Text -> Route WebApp -> Route WebApp -> Int -> Int -> Widget
autoUpdate poll gethtml home ms_delay ms_startdelay = do autoUpdate updating gethtml home ms_delay ms_startdelay = do
{- Fallback refreshing is provided for non-javascript browsers. -} {- Fallback refreshing is provided for non-javascript browsers. -}
let delayseconds = show $ ms_to_seconds ms_delay let delayseconds = show $ ms_to_seconds ms_delay
toWidgetHead $(hamletFile $ hamletTemplate "metarefresh") toWidgetHead $(hamletFile $ hamletTemplate "metarefresh")
@ -88,7 +93,6 @@ autoUpdate poll gethtml home ms_delay ms_startdelay = do
{- Use long polling to update the status display. -} {- Use long polling to update the status display. -}
let delay = show ms_delay let delay = show ms_delay
let startdelay = show ms_startdelay let startdelay = show ms_startdelay
addScript $ StaticR jquery_full_js
$(widgetFile "longpolling") $(widgetFile "longpolling")
where where
ms_to_seconds :: Int -> Int ms_to_seconds :: Int -> Int
@ -100,15 +104,13 @@ statusDisplay = do
webapp <- lift getYesod webapp <- lift getYesod
time <- show <$> liftIO getCurrentTime time <- show <$> liftIO getCurrentTime
poll <- lift newIdent updating <- lift newIdent
$(widgetFile "status") $(widgetFile "status")
autoUpdate poll StatusR HomeR (3000 :: Int) (40 :: Int) autoUpdate updating StatusR HomeR (3000 :: Int) (40 :: Int)
getHomeR :: Handler RepHtml getHomeR :: Handler RepHtml
getHomeR = defaultLayout $ do getHomeR = defaultLayout statusDisplay
statusDisplay
[whamlet|<p><a href="@{ConfigR}">config|]
{- Called by client to poll for a new webapp status display. {- Called by client to poll for a new webapp status display.
- -

382
debian/copyright vendored
View file

@ -57,7 +57,7 @@ License: MIT or GPL-2
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Files: static/bootstrap.css Files: static/*/bootstrap*
Copyright: 2011-2012 Twitter, Inc. Copyright: 2011-2012 Twitter, Inc.
License: Apache-2.0 License: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -74,383 +74,3 @@ License: Apache-2.0
. .
The complete text of the Apache License is distributed in The complete text of the Apache License is distributed in
/usr/share/common-licenses/Apache-2.0 on Debian systems. /usr/share/common-licenses/Apache-2.0 on Debian systems.
Files: static/glyphicons*
Copyright: 2010-2012 Jan Kovarik <glyphicons@gmail.com>
License: CC-BY-3.0
Creative Commons Attribution 3.0 License
.
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS
OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR
"LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER
APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS
PROHIBITED.
.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU
ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE.
TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A
CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE
IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
CONDITIONS.
.
1. Definitions
.
a) "Adaptation" means a work based upon
the Work, or upon the Work and other pre-existing works,
such as a translation, adaptation, derivative work,
arrangement of music or other alterations of a literary
or artistic work, or phonogram or performance and
includes cinematographic adaptations or any other form in
which the Work may be recast, transformed, or adapted
including in any form recognizably derived from the
original, except that a work that constitutes a
Collection will not be considered an Adaptation for the
purpose of this License. For the avoidance of doubt,
where the Work is a musical work, performance or
phonogram, the synchronization of the Work in
timed-relation with a moving image ("synching") will be
considered an Adaptation for the purpose of this
License.
.
b) "Collection"</strong> means a collection of
literary or artistic works, such as encyclopedias and
anthologies, or performances, phonograms or broadcasts,
or other works or subject matter other than works listed
in Section 1(f) below, which, by reason of the selection
and arrangement of their contents, constitute
intellectual creations, in which the Work is included in
its entirety in unmodified form along with one or more
other contributions, each constituting separate and
independent works in themselves, which together are
assembled into a collective whole. A work that
constitutes a Collection will not be considered an
Adaptation (as defined above) for the purposes of this
License.
.
c) "Distribute" means to make available
to the public the original and copies of the Work or
Adaptation, as appropriate, through sale or other
transfer of ownership.
.
d) "Licensor" means the individual,
individuals, entity or entities that offer(s) the Work
under the terms of this License.
.
e) "Original Author" means, in the case
of a literary or artistic work, the individual,
individuals, entity or entities who created the Work or
if no individual or entity can be identified, the
publisher; and in addition (i) in the case of a
performance the actors, singers, musicians, dancers, and
other persons who act, sing, deliver, declaim, play in,
interpret or otherwise perform literary or artistic works
or expressions of folklore; (ii) in the case of a
phonogram the producer being the person or legal entity
who first fixes the sounds of a performance or other
sounds; and, (iii) in the case of broadcasts, the
organization that transmits the broadcast.
.
f) "Work" means the literary and/or
artistic work offered under the terms of this License
including without limitation any production in the
literary, scientific and artistic domain, whatever may be
the mode or form of its expression including digital
form, such as a book, pamphlet and other writing; a
lecture, address, sermon or other work of the same
nature; a dramatic or dramatico-musical work; a
choreographic work or entertainment in dumb show; a
musical composition with or without words; a
cinematographic work to which are assimilated works
expressed by a process analogous to cinematography; a
work of drawing, painting, architecture, sculpture,
engraving or lithography; a photographic work to which
are assimilated works expressed by a process analogous to
photography; a work of applied art; an illustration, map,
plan, sketch or three-dimensional work relative to
geography, topography, architecture or science; a
performance; a broadcast; a phonogram; a compilation of
data to the extent it is protected as a copyrightable
work; or a work performed by a variety or circus
performer to the extent it is not otherwise considered a
literary or artistic work.
.
g) "You"</strong> means an individual or entity
exercising rights under this License who has not
previously violated the terms of this License with
respect to the Work, or who has received express
permission from the Licensor to exercise rights under
this License despite a previous violation.
.
h) "Publicly Perform" means to perform
public recitations of the Work and to communicate to the
public those public recitations, by any means or process,
including by wire or wireless means or public digital
performances; to make available to the public Works in
such a way that members of the public may access these
Works from a place and at a place individually chosen by
them; to perform the Work to the public by any means or
process and the communication to the public of the
performances of the Work, including by public digital
performance; to broadcast and rebroadcast the Work by any
means including signs, sounds or images.
.
i) "Reproduce" means to make copies of
the Work by any means including without limitation by
sound or visual recordings and the right of fixation and
reproducing fixations of the Work, including storage of a
protected performance or phonogram in digital form or
other electronic medium.
.
2. Fair Dealing Rights. Nothing in this
License is intended to reduce, limit, or restrict any uses
free from copyright or rights arising from limitations or
exceptions that are provided for in connection with the
copyright protection under copyright law or other
applicable laws.
.
3. License Grant. Subject to the terms
and conditions of this License, Licensor hereby grants You
a worldwide, royalty-free, non-exclusive, perpetual (for
the duration of the applicable copyright) license to
exercise the rights in the Work as stated below:</p>
.
a) to Reproduce the Work, to incorporate the Work into
one or more Collections, and to Reproduce the Work as
incorporated in the Collections;
.
b) to create and Reproduce Adaptations provided that any
such Adaptation, including any translation in any medium,
takes reasonable steps to clearly label, demarcate or
otherwise identify that changes were made to the original
Work. For example, a translation could be marked "The
original work was translated from English to Spanish," or
a modification could indicate "The original work has been
modified.";
.
c) to Distribute and Publicly Perform the Work including
as incorporated in Collections; and,
.
d) to Distribute and Publicly Perform Adaptations.
.
e) For the avoidance of doubt:
.
i) Non-waivable Compulsory License
Schemes. In those jurisdictions in which the
right to collect royalties through any statutory or
compulsory licensing scheme cannot be waived, the
Licensor reserves the exclusive right to collect such
royalties for any exercise by You of the rights
granted under this License;
.
ii) Waivable Compulsory License
Schemes. In those jurisdictions in which the
right to collect royalties through any statutory or
compulsory licensing scheme can be waived, the
Licensor waives the exclusive right to collect such
royalties for any exercise by You of the rights
granted under this License; and,
.
iii) Voluntary License Schemes. The
Licensor waives the right to collect royalties,
whether individually or, in the event that the
Licensor is a member of a collecting society that
administers voluntary licensing schemes, via that
society, from any exercise by You of the rights
granted under this License.
.
The above rights may be exercised in all media and
formats whether now known or hereafter devised. The above
rights include the right to make such modifications as are
technically necessary to exercise the rights in other media
and formats. Subject to Section 8(f), all rights not
expressly granted by Licensor are hereby reserved.
.
4. Restrictions. The license granted in
Section 3 above is expressly made subject to and limited by
the following restrictions:
.
a) You may Distribute or Publicly Perform the Work only
under the terms of this License. You must include a copy
of, or the Uniform Resource Identifier (URI) for, this
License with every copy of the Work You Distribute or
Publicly Perform. You may not offer or impose any terms
on the Work that restrict the terms of this License or
the ability of the recipient of the Work to exercise the
rights granted to that recipient under the terms of the
License. You may not sublicense the Work. You must keep
intact all notices that refer to this License and to the
disclaimer of warranties with every copy of the Work You
Distribute or Publicly Perform. When You Distribute or
Publicly Perform the Work, You may not impose any
effective technological measures on the Work that
restrict the ability of a recipient of the Work from You
to exercise the rights granted to that recipient under
the terms of the License. This Section 4(a) applies to
the Work as incorporated in a Collection, but this does
not require the Collection apart from the Work itself to
be made subject to the terms of this License. If You
create a Collection, upon notice from any Licensor You
must, to the extent practicable, remove from the
Collection any credit as required by Section 4(b), as
requested. If You create an Adaptation, upon notice from
any Licensor You must, to the extent practicable, remove
from the Adaptation any credit as required by Section
4(b), as requested.
.
b) If You Distribute, or Publicly Perform the Work or
any Adaptations or Collections, You must, unless a
request has been made pursuant to Section 4(a), keep
intact all copyright notices for the Work and provide,
reasonable to the medium or means You are utilizing: (i)
the name of the Original Author (or pseudonym, if
applicable) if supplied, and/or if the Original Author
and/or Licensor designate another party or parties (e.g.,
a sponsor institute, publishing entity, journal) for
attribution ("Attribution Parties") in Licensor's
copyright notice, terms of service or by other reasonable
means, the name of such party or parties; (ii) the title
of the Work if supplied; (iii) to the extent reasonably
practicable, the URI, if any, that Licensor specifies to
be associated with the Work, unless such URI does not
refer to the copyright notice or licensing information
for the Work; and (iv) , consistent with Section 3(b), in
the case of an Adaptation, a credit identifying the use
of the Work in the Adaptation (e.g., "French translation
of the Work by Original Author," or "Screenplay based on
original Work by Original Author"). The credit required
by this Section 4 (b) may be implemented in any
reasonable manner; provided, however, that in the case of
a Adaptation or Collection, at a minimum such credit will
appear, if a credit for all contributing authors of the
Adaptation or Collection appears, then as part of these
credits and in a manner at least as prominent as the
credits for the other contributing authors. For the
avoidance of doubt, You may only use the credit required
by this Section for the purpose of attribution in the
manner set out above and, by exercising Your rights under
this License, You may not implicitly or explicitly assert
or imply any connection with, sponsorship or endorsement
by the Original Author, Licensor and/or Attribution
Parties, as appropriate, of You or Your use of the Work,
without the separate, express prior written permission of
the Original Author, Licensor and/or Attribution
Parties.
.
c) Except as otherwise agreed in writing by the Licensor
or as may be otherwise permitted by applicable law, if
You Reproduce, Distribute or Publicly Perform the Work
either by itself or as part of any Adaptations or
Collections, You must not distort, mutilate, modify or
take other derogatory action in relation to the Work
which would be prejudicial to the Original Author's honor
or reputation. Licensor agrees that in those
jurisdictions (e.g. Japan), in which any exercise of the
right granted in Section 3(b) of this License (the right
to make Adaptations) would be deemed to be a distortion,
mutilation, modification or other derogatory action
prejudicial to the Original Author's honor and
reputation, the Licensor will waive or not assert, as
appropriate, this Section, to the fullest extent
permitted by the applicable national law, to enable You
to reasonably exercise Your right under Section 3(b) of
this License (right to make Adaptations) but not
otherwise.
.
5. Representations, Warranties and
Disclaimer
.
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN
WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO
REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE
WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING,
WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE
ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE
PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE.
SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED
WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
.
6. Limitation on Liability. EXCEPT TO
THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL
LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY
SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY
DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK,
EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
.
7. Termination
.
a) This License and the rights granted hereunder will
terminate automatically upon any breach by You of the
terms of this License. Individuals or entities who have
received Adaptations or Collections from You under this
License, however, will not have their licenses terminated
provided such individuals or entities remain in full
compliance with those licenses. Sections 1, 2, 5, 6, 7,
and 8 will survive any termination of this License.</li>
.
b) Subject to the above terms and conditions, the
license granted here is perpetual (for the duration of
the applicable copyright in the Work). Notwithstanding
the above, Licensor reserves the right to release the
Work under different license terms or to stop
distributing the Work at any time; provided, however that
any such election will not serve to withdraw this License
(or any other license that has been, or is required to
be, granted under the terms of this License), and this
License will continue in full force and effect unless
terminated as stated above.
.
8. Miscellaneous
.
a) Each time You Distribute or Publicly Perform the Work
or a Collection, the Licensor offers to the recipient a
license to the Work on the same terms and conditions as
the license granted to You under this License.
.
b) Each time You Distribute or Publicly Perform an
Adaptation, Licensor offers to the recipient a license to
the original Work on the same terms and conditions as the
license granted to You under this License.
.
c) If any provision of this License is invalid or
unenforceable under applicable law, it shall not affect
the validity or enforceability of the remainder of the
terms of this License, and without further action by the
parties to this agreement, such provision shall be
reformed to the minimum extent necessary to make such
provision valid and enforceable.
.
d) No term or provision of this License shall be deemed
waived and no breach consented to unless such waiver or
consent shall be in writing and signed by the party to be
charged with such waiver or consent.
.
e) This License constitutes the entire agreement between
the parties with respect to the Work licensed here. There
are no understandings, agreements or representations with
respect to the Work not specified here. Licensor shall
not be bound by any additional provisions that may appear
in any communication from You. This License may not be
modified without the mutual written agreement of the
Licensor and You.
.
f) The rights granted under, and the subject matter
referenced, in this License were drafted utilizing the
terminology of the Berne Convention for the Protection of
Literary and Artistic Works (as amended on September 28,
1979), the Rome Convention of 1961, the WIPO Copyright
Treaty of 1996, the WIPO Performances and Phonograms
Treaty of 1996 and the Universal Copyright Convention (as
revised on July 24, 1971). These rights and subject
matter take effect in the relevant jurisdiction in which
the License terms are sought to be enforced according to
the corresponding provisions of the implementation of
those treaty provisions in the applicable national law.
If the standard suite of rights granted under applicable
copyright law includes additional rights not granted
under this License, such additional rights are deemed to
be included in the License; this License is not intended
to restrict the license of any rights under applicable
law.

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

686
static/css/bootstrap-responsive.css vendored Normal file
View file

@ -0,0 +1,686 @@
/*!
* Bootstrap Responsive v2.0.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
.clearfix {
*zoom: 1;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both;
}
.hide-text {
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
}
.input-block-level {
display: block;
width: 100%;
min-height: 28px;
/* Make inputs at least the height of their button counterpart */
/* Makes inputs behave like true block-level elements */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.hidden {
display: none;
visibility: hidden;
}
.visible-phone {
display: none;
}
.visible-tablet {
display: none;
}
.visible-desktop {
display: block;
}
.hidden-phone {
display: block;
}
.hidden-tablet {
display: block;
}
.hidden-desktop {
display: none;
}
@media (max-width: 767px) {
.visible-phone {
display: block;
}
.hidden-phone {
display: none;
}
.hidden-desktop {
display: block;
}
.visible-desktop {
display: none;
}
}
@media (min-width: 768px) and (max-width: 979px) {
.visible-tablet {
display: block;
}
.hidden-tablet {
display: none;
}
.hidden-desktop {
display: block;
}
.visible-desktop {
display: none;
}
}
@media (max-width: 480px) {
.nav-collapse {
-webkit-transform: translate3d(0, 0, 0);
}
.page-header h1 small {
display: block;
line-height: 18px;
}
input[type="checkbox"],
input[type="radio"] {
border: 1px solid #ccc;
}
.form-horizontal .control-group > label {
float: none;
width: auto;
padding-top: 0;
text-align: left;
}
.form-horizontal .controls {
margin-left: 0;
}
.form-horizontal .control-list {
padding-top: 0;
}
.form-horizontal .form-actions {
padding-left: 10px;
padding-right: 10px;
}
.modal {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
width: auto;
margin: 0;
}
.modal.fade.in {
top: auto;
}
.modal-header .close {
padding: 10px;
margin: -10px;
}
.carousel-caption {
position: static;
}
}
@media (max-width: 767px) {
body {
padding-left: 20px;
padding-right: 20px;
}
.navbar-fixed-top {
margin-left: -20px;
margin-right: -20px;
}
.container {
width: auto;
}
.row-fluid {
width: 100%;
}
.row {
margin-left: 0;
}
.row > [class*="span"],
.row-fluid > [class*="span"] {
float: none;
display: block;
width: auto;
margin: 0;
}
.thumbnails [class*="span"] {
width: auto;
}
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input {
display: block;
width: 100%;
min-height: 28px;
/* Make inputs at least the height of their button counterpart */
/* Makes inputs behave like true block-level elements */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.input-prepend input[class*="span"],
.input-append input[class*="span"] {
width: auto;
}
}
@media (min-width: 768px) and (max-width: 979px) {
.row {
margin-left: -20px;
*zoom: 1;
}
.row:before,
.row:after {
display: table;
content: "";
}
.row:after {
clear: both;
}
[class*="span"] {
float: left;
margin-left: 20px;
}
.container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 724px;
}
.span12 {
width: 724px;
}
.span11 {
width: 662px;
}
.span10 {
width: 600px;
}
.span9 {
width: 538px;
}
.span8 {
width: 476px;
}
.span7 {
width: 414px;
}
.span6 {
width: 352px;
}
.span5 {
width: 290px;
}
.span4 {
width: 228px;
}
.span3 {
width: 166px;
}
.span2 {
width: 104px;
}
.span1 {
width: 42px;
}
.offset12 {
margin-left: 764px;
}
.offset11 {
margin-left: 702px;
}
.offset10 {
margin-left: 640px;
}
.offset9 {
margin-left: 578px;
}
.offset8 {
margin-left: 516px;
}
.offset7 {
margin-left: 454px;
}
.offset6 {
margin-left: 392px;
}
.offset5 {
margin-left: 330px;
}
.offset4 {
margin-left: 268px;
}
.offset3 {
margin-left: 206px;
}
.offset2 {
margin-left: 144px;
}
.offset1 {
margin-left: 82px;
}
.row-fluid {
width: 100%;
*zoom: 1;
}
.row-fluid:before,
.row-fluid:after {
display: table;
content: "";
}
.row-fluid:after {
clear: both;
}
.row-fluid > [class*="span"] {
float: left;
margin-left: 2.762430939%;
}
.row-fluid > [class*="span"]:first-child {
margin-left: 0;
}
.row-fluid > .span12 {
width: 99.999999993%;
}
.row-fluid > .span11 {
width: 91.436464082%;
}
.row-fluid > .span10 {
width: 82.87292817100001%;
}
.row-fluid > .span9 {
width: 74.30939226%;
}
.row-fluid > .span8 {
width: 65.74585634900001%;
}
.row-fluid > .span7 {
width: 57.182320438000005%;
}
.row-fluid > .span6 {
width: 48.618784527%;
}
.row-fluid > .span5 {
width: 40.055248616%;
}
.row-fluid > .span4 {
width: 31.491712705%;
}
.row-fluid > .span3 {
width: 22.928176794%;
}
.row-fluid > .span2 {
width: 14.364640883%;
}
.row-fluid > .span1 {
width: 5.801104972%;
}
input,
textarea,
.uneditable-input {
margin-left: 0;
}
input.span12, textarea.span12, .uneditable-input.span12 {
width: 714px;
}
input.span11, textarea.span11, .uneditable-input.span11 {
width: 652px;
}
input.span10, textarea.span10, .uneditable-input.span10 {
width: 590px;
}
input.span9, textarea.span9, .uneditable-input.span9 {
width: 528px;
}
input.span8, textarea.span8, .uneditable-input.span8 {
width: 466px;
}
input.span7, textarea.span7, .uneditable-input.span7 {
width: 404px;
}
input.span6, textarea.span6, .uneditable-input.span6 {
width: 342px;
}
input.span5, textarea.span5, .uneditable-input.span5 {
width: 280px;
}
input.span4, textarea.span4, .uneditable-input.span4 {
width: 218px;
}
input.span3, textarea.span3, .uneditable-input.span3 {
width: 156px;
}
input.span2, textarea.span2, .uneditable-input.span2 {
width: 94px;
}
input.span1, textarea.span1, .uneditable-input.span1 {
width: 32px;
}
}
@media (max-width: 979px) {
body {
padding-top: 0;
}
.navbar-fixed-top {
position: static;
margin-bottom: 18px;
}
.navbar-fixed-top .navbar-inner {
padding: 5px;
}
.navbar .container {
width: auto;
padding: 0;
}
.navbar .brand {
padding-left: 10px;
padding-right: 10px;
margin: 0 0 0 -5px;
}
.navbar .nav-collapse {
clear: left;
}
.navbar .nav {
float: none;
margin: 0 0 9px;
}
.navbar .nav > li {
float: none;
}
.navbar .nav > li > a {
margin-bottom: 2px;
}
.navbar .nav > .divider-vertical {
display: none;
}
.navbar .nav .nav-header {
color: #999999;
text-shadow: none;
}
.navbar .nav > li > a,
.navbar .dropdown-menu a {
padding: 6px 15px;
font-weight: bold;
color: #999999;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.navbar .dropdown-menu li + li a {
margin-bottom: 2px;
}
.navbar .nav > li > a:hover,
.navbar .dropdown-menu a:hover {
background-color: #222222;
}
.navbar .dropdown-menu {
position: static;
top: auto;
left: auto;
float: none;
display: block;
max-width: none;
margin: 0 15px;
padding: 0;
background-color: transparent;
border: none;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.navbar .dropdown-menu:before,
.navbar .dropdown-menu:after {
display: none;
}
.navbar .dropdown-menu .divider {
display: none;
}
.navbar-form,
.navbar-search {
float: none;
padding: 9px 15px;
margin: 9px 0;
border-top: 1px solid #222222;
border-bottom: 1px solid #222222;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
}
.navbar .nav.pull-right {
float: none;
margin-left: 0;
}
.navbar-static .navbar-inner {
padding-left: 10px;
padding-right: 10px;
}
.btn-navbar {
display: block;
}
.nav-collapse {
overflow: hidden;
height: 0;
}
}
@media (min-width: 980px) {
.nav-collapse.collapse {
height: auto !important;
overflow: visible !important;
}
}
@media (min-width: 1200px) {
.row {
margin-left: -30px;
*zoom: 1;
}
.row:before,
.row:after {
display: table;
content: "";
}
.row:after {
clear: both;
}
[class*="span"] {
float: left;
margin-left: 30px;
}
.container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 1170px;
}
.span12 {
width: 1170px;
}
.span11 {
width: 1070px;
}
.span10 {
width: 970px;
}
.span9 {
width: 870px;
}
.span8 {
width: 770px;
}
.span7 {
width: 670px;
}
.span6 {
width: 570px;
}
.span5 {
width: 470px;
}
.span4 {
width: 370px;
}
.span3 {
width: 270px;
}
.span2 {
width: 170px;
}
.span1 {
width: 70px;
}
.offset12 {
margin-left: 1230px;
}
.offset11 {
margin-left: 1130px;
}
.offset10 {
margin-left: 1030px;
}
.offset9 {
margin-left: 930px;
}
.offset8 {
margin-left: 830px;
}
.offset7 {
margin-left: 730px;
}
.offset6 {
margin-left: 630px;
}
.offset5 {
margin-left: 530px;
}
.offset4 {
margin-left: 430px;
}
.offset3 {
margin-left: 330px;
}
.offset2 {
margin-left: 230px;
}
.offset1 {
margin-left: 130px;
}
.row-fluid {
width: 100%;
*zoom: 1;
}
.row-fluid:before,
.row-fluid:after {
display: table;
content: "";
}
.row-fluid:after {
clear: both;
}
.row-fluid > [class*="span"] {
float: left;
margin-left: 2.564102564%;
}
.row-fluid > [class*="span"]:first-child {
margin-left: 0;
}
.row-fluid > .span12 {
width: 100%;
}
.row-fluid > .span11 {
width: 91.45299145300001%;
}
.row-fluid > .span10 {
width: 82.905982906%;
}
.row-fluid > .span9 {
width: 74.358974359%;
}
.row-fluid > .span8 {
width: 65.81196581200001%;
}
.row-fluid > .span7 {
width: 57.264957265%;
}
.row-fluid > .span6 {
width: 48.717948718%;
}
.row-fluid > .span5 {
width: 40.170940171000005%;
}
.row-fluid > .span4 {
width: 31.623931624%;
}
.row-fluid > .span3 {
width: 23.076923077%;
}
.row-fluid > .span2 {
width: 14.529914530000001%;
}
.row-fluid > .span1 {
width: 5.982905983%;
}
input,
textarea,
.uneditable-input {
margin-left: 0;
}
input.span12, textarea.span12, .uneditable-input.span12 {
width: 1160px;
}
input.span11, textarea.span11, .uneditable-input.span11 {
width: 1060px;
}
input.span10, textarea.span10, .uneditable-input.span10 {
width: 960px;
}
input.span9, textarea.span9, .uneditable-input.span9 {
width: 860px;
}
input.span8, textarea.span8, .uneditable-input.span8 {
width: 760px;
}
input.span7, textarea.span7, .uneditable-input.span7 {
width: 660px;
}
input.span6, textarea.span6, .uneditable-input.span6 {
width: 560px;
}
input.span5, textarea.span5, .uneditable-input.span5 {
width: 460px;
}
input.span4, textarea.span4, .uneditable-input.span4 {
width: 360px;
}
input.span3, textarea.span3, .uneditable-input.span3 {
width: 260px;
}
input.span2, textarea.span2, .uneditable-input.span2 {
width: 160px;
}
input.span1, textarea.span1, .uneditable-input.span1 {
width: 60px;
}
.thumbnails {
margin-left: -30px;
}
.thumbnails > li {
margin-left: 30px;
}
}

View file

@ -1395,7 +1395,7 @@ table .span24 {
height: 14px; height: 14px;
line-height: 14px; line-height: 14px;
vertical-align: text-top; vertical-align: text-top;
background-image: url("../img/glyphicons-halflings.png"); background-image: url("/static/img/glyphicons-halflings.png");
background-position: 14px 14px; background-position: 14px 14px;
background-repeat: no-repeat; background-repeat: no-repeat;
*margin-right: .3em; *margin-right: .3em;
@ -1405,7 +1405,7 @@ table .span24 {
*margin-left: 0; *margin-left: 0;
} }
.icon-white { .icon-white {
background-image: url("../img/glyphicons-halflings-white.png"); background-image: url("/static/img/glyphicons-halflings-white.png");
} }
.icon-glass { .icon-glass {
background-position: 0 0; background-position: 0 0;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

92
static/js/bootstrap-dropdown.js vendored Normal file
View file

@ -0,0 +1,92 @@
/* ============================================================
* bootstrap-dropdown.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#dropdowns
* ============================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
!function( $ ){
"use strict"
/* DROPDOWN CLASS DEFINITION
* ========================= */
var toggle = '[data-toggle="dropdown"]'
, Dropdown = function ( element ) {
var $el = $(element).on('click.dropdown.data-api', this.toggle)
$('html').on('click.dropdown.data-api', function () {
$el.parent().removeClass('open')
})
}
Dropdown.prototype = {
constructor: Dropdown
, toggle: function ( e ) {
var $this = $(this)
, selector = $this.attr('data-target')
, $parent
, isActive
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
$parent = $(selector)
$parent.length || ($parent = $this.parent())
isActive = $parent.hasClass('open')
clearMenus()
!isActive && $parent.toggleClass('open')
return false
}
}
function clearMenus() {
$(toggle).parent().removeClass('open')
}
/* DROPDOWN PLUGIN DEFINITION
* ========================== */
$.fn.dropdown = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('dropdown')
if (!data) $this.data('dropdown', (data = new Dropdown(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.dropdown.Constructor = Dropdown
/* APPLY TO STANDARD DROPDOWN ELEMENTS
* =================================== */
$(function () {
$('html').on('click.dropdown.data-api', clearMenus)
$('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
})
}( window.jQuery );

View file

@ -0,0 +1,52 @@
$doctype 5
<html>
<head>
<title>#{baseTitle webapp} #{pageTitle page}
<link rel="icon" href=@{StaticR favicon_ico} type="image/x-icon">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
^{pageHead page}
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="#">
git-annex
<ul class="nav">
<li class="active">
<a href="#">Dashboard</a>
<li>
<a href="@{ConfigR}">Config</a>
<ul class="nav pull-right">
<li class="dropdown" id="menu1">
<a class="dropdown-toggle" data-toggle="dropdown" href="#menu1">
Current Repository: #{baseTitle webapp}
<b class="caret"></b>
<ul class="dropdown-menu">
<li><a href="#">#{baseTitle webapp}</a></li>
<li class="divider"></li>
<li><a href="#">Add new repository</a></li>
<div class="container-fluid">
<div class="row-fluid">
<div class="span3">
<div class="sidebar-nav">
<div class="alert alert-info">
<b>This is just a demo.</b> If this were not just a demo,
I'd not be filling this sidebar with silly alerts.
<div class="alert alert-success">
<b>Well done!</b>
You successfully read this important alert message.
<div class="alert alert-error">
<b>Whoops!</b>
Unable to connect to blah blah..
<div class="span9">
^{pageBody page}

View file

@ -1,10 +1,3 @@
$doctype 5 $maybe msg <- mmsg
<html> <div #message>#{msg}
<head> ^{widget}
<title>#{baseTitle webapp} #{pageTitle page}
<link rel="icon" href=@{StaticR favicon_ico} type="image/x-icon">
^{pageHead page}
<body>
$maybe msg <- mmsg
<div #message>#{msg}
^{pageBody page}

View file

@ -1,5 +1,5 @@
// Uses long-polling to update a div with id=#{poll} // Uses long-polling to update a div with id=#{updating}
// The gethtml route should return a new div, with the same id. // The gethtml route should return a new div, with the same id.
// //
// Maximum update frequency is controlled by #{startdelay} // Maximum update frequency is controlled by #{startdelay}
@ -16,7 +16,7 @@ $.LongPoll = (function() {
'url': '@{gethtml}', 'url': '@{gethtml}',
'dataType': 'html', 'dataType': 'html',
'success': function(data, status, jqxhr) { 'success': function(data, status, jqxhr) {
$('##{poll}').replaceWith(data); $('##{updating}').replaceWith(data);
setTimeout($.LongPoll.send, #{delay}); setTimeout($.LongPoll.send, #{delay});
numerrs=0; numerrs=0;
}, },

View file

@ -1,2 +1,26 @@
<div id="#{poll}"> <span id="#{updating}">
polled at #{time} <div class="hero-unit">
<div class="row-fluid">
<h3>
foo &larr;
<small>usb drive</small>
<small class="pull-right">40% of 10 mb</small>
<div class="progress progress-striped">
<div class="bar" style="width: 40%;">
<div class="row-fluid">
<h3>
some_filenames_are_long_and_ugly_like_this_one.mp3 &rarr;
<small>Amazon S3</small>
<small class="pull-right">10% of 50 mb</small>
<div class="progress progress-striped">
<div class="bar" style="width: 10%;">
<div class="row-fluid">
<h3>
bigfile &larr;
<small>usb drive</small>
<small class="pull-right">0% of 512 mb</small>
<div class="progress progress-striped">
<div class="bar" style="width: 0%;">
<footer>
<span>
polled at #{time}