Refactored CSS into different files and removed unused fonts and images.

This commit is contained in:
Sean Li 2015-02-19 15:34:47 -08:00
parent cc50c7a446
commit 2e91d7b00b
30 changed files with 1115 additions and 1785 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,248 +0,0 @@
var $ = require('jquery');
var assign = require('object-assign');
var React = require('react/addons');
var Modal = require('react-bootstrap').Modal;
var OverlayTrigger = require('react-bootstrap');
var Popover = require('react-bootstrap/Popover');
var RetinaImage = require('react-retina-image');
var ContainerStore = require('./ContainerStore');
var OverlayTrigger = require('react-bootstrap/OverlayTrigger');
var Popover = require('react-bootstrap/Popover');
var ContainerModal = React.createClass({
_searchRequest: null,
getInitialState: function () {
return {
query: '',
results: ContainerStore.recommended(),
loading: false,
tags: {},
active: null,
};
},
componentDidMount: function () {
this.refs.searchInput.getDOMNode().focus();
ContainerStore.on(ContainerStore.CLIENT_RECOMMENDED_EVENT, this.update);
},
update: function () {
if (!this.state.query.length) {
this.setState({
results: ContainerStore.recommended()
});
}
},
search: function (query) {
if (this._searchRequest) {
this._searchRequest.abort();
this._searchRequest = null;
}
if (!query.length) {
return;
}
this.setState({
loading: true
});
var self = this;
this._searchRequest = $.get('https://registry.hub.docker.com/v1/search?q=' + query, function (result) {
self.setState({
query: query,
loading: false
});
self._searchRequest = null;
if (self.isMounted()) {
self.setState(result);
}
});
},
handleChange: function (e) {
var query = e.target.value;
if (query === this.state.query) {
return;
}
clearTimeout(this.timeout);
if (!query.length) {
this.setState({
query: query,
results: ContainerStore.recommended()
});
} else {
var self = this;
this.timeout = setTimeout(function () {
self.search(query);
}, 200);
}
},
handleClick: function (name) {
this.props.onRequestHide();
ContainerStore.create(name, 'latest', function (err) {
if (err) {
throw err;
}
}.bind(this));
},
handleTagClick: function (tag, name) {
this.props.onRequestHide();
ContainerStore.create(name, tag, function () {});
},
handleDropdownClick: function (name) {
this.setState({
active: name
});
if (this.state.tags[name]) {
return;
}
$.get('https://registry.hub.docker.com/v1/repositories/' + name + '/tags', function (result) {
var res = {};
res[name] = result;
console.log(assign(this.state.tags, res));
this.setState({
tags: assign(this.state.tags, res)
});
}.bind(this));
},
handleModalClick: function (event) {
if (!this.state.active) {
return;
}
if (!$('.popover').is(event.target)) {
this.setState({
active: null
});
}
},
componentDidUpdate: function () {
if (!this.state.active) {
return;
}
var $dropdown = $(this.getDOMNode()).find('[data-name="' + this.state.active + '"]');
var $popover = $(this.getDOMNode()).find('.popover');
$popover.offset({
top: $dropdown.offset().top + 32,
left: $dropdown.offset().left - $popover.width() / 2 + 11
});
},
render: function () {
var self = this;
var data = this.state.results.slice(0, 7);
var results;
if (data.length) {
var items = data.map(function (r) {
var name;
if (r.is_official) {
name = <span><RetinaImage src="official.png"/>{r.name}</span>;
} else {
name = <span>{r.name}</span>;
}
return (
<li key={r.name}>
<div className="info">
<div className="name">
{name}
</div>
<div className="properties">
<div className="icon icon-star-9"></div>
<div className="star-count">{r.star_count}</div>
</div>
</div>
<div className="action">
<div className="btn-group">
<button type="button" className="btn btn-primary" onClick={self.handleClick.bind(self, r.name)}>Create</button>
<button type="button" className="btn btn-primary dropdown-toggle" onClick={self.handleDropdownClick.bind(self, r.name)} data-name={r.name}>
<span className="icon-dropdown icon icon-arrow-37"></span>
</button>
</div>
</div>
</li>
);
});
results = (
<div className="result-list">
<ul>
{items}
</ul>
</div>
);
} else {
results = (
<div className="no-results">
<h3>
No Results
</h3>
</div>
);
}
var title = this.state.query ? 'Results' : 'Recommended';
var loadingClasses = React.addons.classSet({
hidden: !this.state.loading,
loading: true
});
var magnifierClasses = React.addons.classSet({
hidden: this.state.loading,
icon: true,
'icon-magnifier': true,
'search-icon': true
});
var question = (
<div className="question">
<OverlayTrigger trigger="hover" placement="bottom" overlay={<Popover>An image is a template for a container.</Popover>}>
<span>What&#39;s an image?</span>
</OverlayTrigger>
</div>
);
var tagData = self.state.tags[this.state.active];
var tags;
if (tagData) {
var list = tagData.map(function (t) {
return <li key={t.name} onClick={self.handleTagClick.bind(self, t.name, self.state.active)}>{t.name}</li>;
});
tags = (
<ul>
{list}
</ul>
);
} else {
tags = <RetinaImage className="tags-loading" src="loading.png"/>;
}
var popoverClasses = React.addons.classSet({
popover: true,
hidden: !this.state.active
});
return (
<Modal {...this.props} animation={false} className="create-modal">
<div className="modal-body" onClick={this.handleModalClick}>
<section className="search">
<div className="search-bar">
<input type="search" ref="searchInput" className="form-control" placeholder="Find an existing image" onChange={this.handleChange}/>
<div className={magnifierClasses}></div>
<RetinaImage className={loadingClasses} src="loading.png"/>
</div>
{question}
<div className="results">
<div className="title">{title}</div>
{results}
</div>
</section>
<Popover placement="bottom" className={popoverClasses}>
{tags}
</Popover>
</div>
</Modal>
);
}
});
module.exports = ContainerModal;

View File

@ -40,9 +40,9 @@ var Header = React.createClass({
return (
<div className="header no-drag">
<div className="buttons">
<div className="button button-close red disabled"></div>
<div className="button button-minimize yellow disabled"></div>
<div className="button button-fullscreenclose green enabled" onClick={this.handleFullscreen}></div>
<div className="button button-close disabled"></div>
<div className="button button-minimize disabled"></div>
<div className="button button-fullscreenclose enabled" onClick={this.handleFullscreen}></div>
</div>
<RetinaImage className="logo" src="logo.png"/>
</div>
@ -51,9 +51,9 @@ var Header = React.createClass({
return (
<div className="header">
<div className="buttons">
<div className="button button-close red enabled" onClick={this.handleClose}></div>
<div className="button button-minimize yellow enabled" onClick={this.handleMinimize}></div>
<div className="button button-fullscreen green enabled" onClick={this.handleFullscreen}></div>
<div className="button button-close enabled" onClick={this.handleClose}></div>
<div className="button button-minimize enabled" onClick={this.handleMinimize}></div>
<div className="button button-fullscreen enabled" onClick={this.handleFullscreen}></div>
</div>
<RetinaImage className="logo" src="logo.png"/>
</div>

36
styles/animation.less Normal file
View File

@ -0,0 +1,36 @@
@-webkit-keyframes spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
@-webkit-keyframes translatewave {
from {
-webkit-transform: translateX(0px);
}
to {
-webkit-transform: translateX(20px);
}
}
@-webkit-keyframes translatedownload {
0% {
-webkit-transform: translateY(6px);
opacity: 0;
}
25% {
opacity: 1;
-webkit-transform: translateY(6px);
}
50% {
opacity: 1;
-webkit-transform: translateY(20px);
}
100% {
opacity: 1;
-webkit-transform: translateY(20px);
}
}

View File

@ -1,56 +0,0 @@
@font-face {
font-family: 'Clear';
src: url('clearsans-regular-webfont.ttf') format('truetype');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Clear Sans';
src: url('clearsans-medium-webfont.ttf') format('truetype');
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Clear Sans';
src: url('clearsans-light-webfont.ttf') format('truetype');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Clear Sans';
src: url('clearsans-thin-webfont.ttf') format('truetype');
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Clear Sans';
src: url('clearsans-mediumitalic-webfont.ttf') format('truetype');
font-weight: 500;
font-style: italic;
}
@font-face {
font-family: 'Clear Sans';
src: url('clearsans-italic-webfont.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'Clear Sans';
src: url('clearsans-bolditalic-webfont.ttf') format('truetype');
font-weight: 700;
font-style: italic;
}
@font-face {
font-family: 'Clear Sans';
src: url('clearsans-bold-webfont.ttf') format('truetype');
font-weight: 700;
font-style: normal;
}

170
styles/container-home.less Normal file
View File

@ -0,0 +1,170 @@
.details-panel.home {
background-color: #F9F9F9;
overflow: hidden;
.content {
display: flex;
flex: 1 auto;
flex-direction: row;
padding: 10px 27px;
.left {
width: 60%;
flex-direction: column;
margin-right: 30px;
}
.right {
width: 40%;
flex-direction: column;
}
.web-preview {
margin-bottom: 50px;
.subtext {
text-align: right;
color: @gray-lightest;
margin-top: 2px;
transition: all 0.25s;
&:hover {
color: darken(@gray-lightest, 10%);
}
}
.widget {
background-color: white;
width: 100%;
height: 100%;
border-radius: 4px;
border: 1px solid @gray-lightest;
position: relative;
overflow: hidden;
p {
font-size: 13px;
color: @gray-normal;
padding: 10px;
padding-bottom: 0px;
}
.ip-port {
padding: 20px;
padding-top: 5px;
color: @gray-darkest;
font-family: Menlo;
-webkit-user-select: text;
}
.frame {
border: 0;
position: absolute;
left: -100%;
top: -100%;
height: 400%;
width: 401%;
transform: scale(0.5);
}
.frame-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
color: transparent;
transition: all 0.25s;
.icon {
margin-top: 40%;
display: block;
font-size: 60px;
text-align: center;
}
.text {
font-size: 20px;
text-align: center;
}
&:hover {
color: white;
background-color: @gray-darkest;
opacity: 0.75;
}
}
}
}
.mini-logs {
margin-bottom: 50px;
.widget {
position: relative;
border-radius: 4px;
border: 1px solid @gray-lightest;
background-color: @gray-darkest;
color: @gray-lightest;
height: 100%;
padding: 10px;
overflow: hidden;
font-family: Menlo;
font-size: 7px;
white-space: pre;
.logs {
overflow: hidden;
height: 100%;
}
p {
margin-bottom: 0px;
}
.mini-logs-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
color: transparent;
transition: all 0.25s;
.icon {
margin-top: 25%;
display: block;
font-size: 60px;
text-align: center;
}
.text {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-size: 20px;
text-align: center;
}
&:hover {
color: white;
background-color: @gray-darkest;
opacity: 0.75;
}
}
}
}
.folders {
.subtext {
text-align: right;
color: @gray-lightest;
margin-top: 2px;
transition: all 0.25s;
&:hover {
color: darken(@gray-lightest, 10%);
}
}
.widget {
padding: 10px 5px;
background-color: white;
border-radius: 4px;
border: 1px solid @gray-lightest;
display: flex;
.folder {
width: 110px;
padding: 5px;
&:hover {
background-color: #F9F9F9;
border-radius: 10px;
}
img {
display: block;
margin: 0 auto;
}
.text {
margin-top: 4px;
text-align: center;
}
}
}
}
}
}

View File

@ -0,0 +1,12 @@
.details-panel.logs {
background-color: @gray-darkest;
-webkit-user-select: text;
font-family: Menlo;
font-size: 12px;
padding: 20px 18px;
color: @gray-lightest;
white-space: pre-wrap;
p {
margin-bottom: 0px;
}
}

View File

@ -1,207 +0,0 @@
.create-modal {
@modal-padding: 32px;
@search-width: 372px;
@custom-width: 0;
.modal-dialog {
margin-top: 80px;
width: calc(@modal-padding + @search-width + 2 * @modal-padding + @custom-width);
}
.modal-content {
//box-shadow: 0 3px 15px rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.10);
border: none; //1px solid #ccc;
height: 610px;
display: flex;
}
.modal-body {
flex: 1 auto;
display: flex;
flex-direction: row;
padding: 32px 32px;
.popover {
width: 180px;
text-align: center;
.popover-content {
max-height: 160px;
padding: 0;
overflow: auto;
}
ul {
padding: 0;
list-style: none;
margin: 0;
li {
padding: 8px 0;
border-bottom: 1px solid #eee;
&:hover {
color: white;
background: @brand-primary;
}
}
}
.tags-loading {
text-align: center;
margin: 14px auto;
text-align: center;
-webkit-animation-name: spin;
-webkit-animation-duration: 1.8s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
}
section.search {
min-width: 404px;
.question {
text-align: right;
}
.search-bar {
position: relative;
.loading {
position: absolute;
left: 13px;
top: 10px;
width: 20px;
height: 20px;
-webkit-animation-name: spin;
-webkit-animation-duration: 1.8s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
.search-icon {
font-size: 20px;
color: @gray-lighter;
position: absolute;
top: 9px;
left: 14px;
}
input {
border-radius: 20px;
font-size: 13px;
height: 38px;
padding: 8px 16px 8px 40px;
color: @gray-darkest;
margin-bottom: 3px;
border-color: @gray-lightest;
box-shadow: none;
&:focus {
box-shadow: none;
border-color: @gray-lighter;
}
&::-webkit-input-placeholder {
color: #ddd;
font-weight: 300;
}
}
}
.results {
overflow: auto;
padding-bottom: 80px;
.no-results {
text-align: center;
h3 {
color: #ABC0C0;
font-size: 16px;
margin-top: 160px;
}
}
.title {
flex: 0 auto;
margin-top: 16px;
}
ul {
margin-top: 10px;
list-style: none;
padding: 0;
li {
&:hover {
background-color: lighten(@gray-lightest, 17.5%);
}
display: flex;
flex-direction: row;
padding: 8px 14px 5px 14px;
//margin: 12px;
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: 0;
}
.info {
.name {
color: @gray-darkest;
max-width: 278px;
img {
margin-right: 6px;
margin-left: 2px;
}
font-size: 16px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.properties {
color: @gray-lighter;
margin-top: 2px;
.star-count {
font-size: 10px;
display: inline-block;
position: relative;
top: -3px;
left: 1px;
height: 17px;
}
.icon {
overflow: hidden;
display: inline-block;
font-size: 15px;
height: 15px;
}
}
flex: 0 auto;
}
.action {
position: relative;
top: 5px;
text-align: right;
flex: 1 auto;
ul {
text-align: center;
ul {
overflow: auto;
max-height: 300px;
}
}
.icon {
position: relative;
top: 2px;
font-size: 11px;
}
}
}
}
}
}
}
}
.modal-backdrop.in {
background: rgba(227,230,230,0.95);
opacity: 1;
height: 100%;
}

View File

@ -0,0 +1,202 @@
.details-panel .settings {
display: flex;
flex: 1 auto;
flex-direction: row;
.settings-menu {
min-width: 180px;
flex: 0 auto;
ul {
position: fixed;
margin: 0;
padding: 0;
padding-top: 14px;
display: flex;
flex-direction: column;
a {
min-width: 160px;
margin-left: 12px;
color: @gray-normal;
flex-shrink: 0;
cursor: default;
outline: none;
margin-bottom: 10px;
&.active {
li {
color: white;
border-radius: 40px;
background-image: linear-gradient(-180deg, #24B8EB 4%, #24A3EB 100%);
}
}
&:hover {
text-decoration: none;
li {
cursor: default;
border-radius: 40px;
background-color: #F9F9F9;
}
}
&:focus {
text-decoration: none;
}
}
li {
vertical-align: middle;
padding: 5px 12px;
display: flex;
flex-direction: row;
}
}
}
.settings-panel {
padding-left: 20px;
flex: 1 auto;
overflow-x: hidden;
.settings-section {
margin-bottom: 40px;
}
.container-name {
margin-bottom: 20px;
input {
width: 40%;
}
p {
font-weight: 300;
margin-top: 5px;
color: @gray-lighter;
font-size: 12px;
strong {
font-weight: 500;
}
}
}
.env-vars-labels {
width: 100%;
font-size: 12px;
color: @gray-lightest;
margin-left: 5px;
margin-bottom: 5px;
margin-top: 20px;
.label-key {
display: inline-block;
margin-right: 30px;
width: 30%;
}
.label-val {
display: inline-block;
width: 50%;
}
}
.env-vars {
margin-bottom: 20px;
.keyval-row {
margin-bottom: 5px;
}
input {
margin-right: 30px;
&.key {
width: 30%;
}
&.val {
width: 50%;
}
}
}
.table {
margin-bottom: 0;
.icon-arrow-right {
color: #BBB;
font-size: 20px;
margin: 0px 10px;
flex: 0 auto;
min-width: 13px;
}
&.ports {
.table-labels {
margin-top: 20px;
flex: 1 auto;
display: flex;
font-size: 12px;
color: @gray-lightest;
.label-left {
flex: 0 auto;
min-width: 85px;
margin-right: 30px;
text-align: right;
}
.label-right {
flex: 1 auto;
display: inline-block;
margin-left: 10px;
width: 40%;
}
}
.table-values {
flex: 1 auto;
display: flex;
flex-direction: row;
margin: 8px 0;
.value-left {
text-align: right;
min-width: 85px;
flex: 0 auto;
padding: 0px;
}
.value-right {
flex: 1 auto;
-webkit-user-select: text;
max-width: 170px;
padding: 0px;
}
label {
margin-left: 8px;
margin-top: 1px;
font-weight: 400;
font-size: 13px;
}
input[type="checked"] {
}
}
}
&.volumes {
.table-labels {
margin-top: 20px;
flex: 1 auto;
display: flex;
font-size: 12px;
color: @gray-lightest;
.label-left {
flex: 0 auto;
margin-right: 30px;
}
.label-right {
flex: 1 auto;
display: inline-block;
margin-left: 10px;
}
}
.table-values {
flex: 1 auto;
display: flex;
flex-direction: row;
margin: 8px 0;
.value-left {
flex: 0 auto;
padding: 0px;
}
.value-right {
flex: 1 auto;
-webkit-user-select: text;
padding: 0px;
}
.btn {
margin-left: 10px;
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,12 @@
@import "bootstrap/bootstrap.less";
.header {
position: absolute;
min-width: 100%;
flex: 0;
min-height: 40px;
-webkit-app-region: drag;
-webkit-user-select: none;
// border-bottom: 1px solid #efefef;
&.no-drag {
-webkit-app-region: no-drag;
}
.logo {
position: relative;
float: right;
@ -20,13 +14,11 @@
right: 10px;
z-index: 1000;
}
.buttons {
display: inline-block;
position: relative;
top: 10px;
left: 15px;
&:hover {
.button-minimize.enabled {
.at2x('minimize.png', 10px, 10px);
@ -41,42 +33,23 @@
.at2x('fullscreenclose.png', 10px, 10px);
}
}
.button {
box-sizing: border-box;
display: inline-block;
background: white;
margin-right: 9px;
height: 12px;
width: 12px;
border: 1px solid #CCD3D5;
border-radius: 6px;
box-shadow: 0px 1px 1px 0px rgba(234,234,234,0.50);
-webkit-app-region: no-drag;
&.red {
background-color: #FF5F52;
border-color: #E33E32;
.traffic-light();
&.button-close {
background-color: @traffic-light-red;
border-color: @traffic-light-red-border;
}
&.yellow {
background-color: #FFBE05;
border-color: #E2A100;
&.button-minimize {
background-color: @traffic-light-yellow;
border-color: @traffic-light-yellow-border;
}
&.green {
background-color: #15CC35;
border-color: #17B230;
&.button-fullscreen {
background-color: @traffic-light-green;
border-color: @traffic-light-green-border;
}
&.disabled {
background-color: #DDDDDD;
border: 1px solid #D3D3D3;
}
&.enabled:hover {
box-shadow: 0px 1px 1px 0px rgba(195,198,201,0.50);
}
&.enabled:hover:active {
cursor: default;
-webkit-filter: brightness(92%);
background-color: @traffic-light-gray;
border-color: @traffic-light-gray-border;
}
}
}

12
styles/layout.less Normal file
View File

@ -0,0 +1,12 @@
.containers {
box-sizing: border-box;
height: 100%;
display: flex;
flex-direction: column;
.containers-body {
flex: 1;
display: flex;
flex-direction: row;
padding: 0px;
}
}

249
styles/left-panel.less Normal file
View File

@ -0,0 +1,249 @@
/* Sidebar */
.sidebar {
padding-top: 28px;
background-color: white;
margin: 0;
border-right: 1px solid @divider-color;
display: flex;
flex-direction: column;
min-width: 260px;
box-sizing: border-box;
.sidebar-header {
flex: 0 auto;
min-width: 240px;
min-height: 47px;
display: flex;
border-bottom: 1px solid transparent;
transition: border-bottom 0.25s;
&.sep {
border-bottom: 1px solid #EEE;
box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.03);
}
h4 {
align-self: flex-start;
padding-left: 26px;
margin: 14px 0 0;
display: inline-block;
position: relative;
}
.create {
flex: 1 auto;
text-align: right;
margin-right: 20px;
margin-top: 3px;
.btn-new {
font-size: 24px;
color: @brand-action;
transition: all 0.25s;
&:hover {
color: darken(@brand-action, 15%);
}
}
}
}
.sidebar-containers {
position: relative;
flex: 1 auto;
overflow-y: auto;
overflow-x: hidden;
box-sizing: border-box;
max-width: 260px;
ul {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
.new-container-item {
.info {
position: relative;
top: 9px;
}
}
a {
color: inherit;
flex-shrink: 0;
cursor: default;
outline: none;
&:hover {
text-decoration: none;
cursor: default;
}
&:focus {
text-decoration: none;
}
&.active {
background: @brand-action;
li {
height: 57px;
border-bottom: none;
.brand-gradient();
.name {
color: white;
}
.image {
color: white;
opacity: 0.8;
}
.btn-delete {
font-size: 24px;
color: white;
position: relative;
z-index: 9999;
}
.state-new {
.at2x('container-white.png', 20px, 20px);
}
.state-running {
.at2x('running-white.png', 20px, 20px);
.runningwave {
.at2x('runningwave-white.png', 20px, 20px);
}
}
.state-paused {
.at2x('wavy-white.png', 20px, 20px);
}
.state-stopped {
.at2x('stopped-white.png', 20px, 20px);
}
.state-downloading {
.at2x('downloading-white.png', 20px, 20px);
.downloading-arrow {
.at2x('downloading-arrow-white.png', 20px, 20px);
}
}
}
}
}
li {
vertical-align: middle;
padding: 10px 16px 10px 26px;
display: flex;
flex-direction: row;
height: 57px;
.info {
font-size: 13px;
margin-left: 16px;
.name {
text-overflow: ellipsis;
max-width: 140px;
white-space: nowrap;
overflow: hidden;
font-size: 14px;
font-weight: 400;
color: @gray-darkest;
}
.image {
color: @gray-lighter;
font-size: 12px;
font-weight: 400;
text-overflow: ellipsis;
max-width: 140px;
white-space: nowrap;
overflow: hidden;
}
}
.action {
display: none;
flex: 1;
position: relative;
top: 5px;
text-align: right;
margin-right: 4px;
.btn-delete {
font-size: 24px;
color: @gray-lighter;
position: relative;
z-index: 9999;
}
}
.state {
margin-top: 9px;
display: inline-block;
position: relative;
min-width: 20px;
height: 20px;
}
.state-error {
.at2x('error.png', 20px, 20px);
}
.state-stopped {
.at2x('stopped.png', 20px, 20px);
}
.state-paused {
.at2x('paused.png', 20px, 20px);
}
.state-new {
.at2x('container.png', 20px, 20px);
}
.state-downloading {
.at2x('downloading.png', 20px, 20px);
overflow: hidden;
.downloading-arrow {
width: 20px;
height: 20px;
.at2x('downloading-arrow.png', 20px, 20px);
position: absolute;
-webkit-animation-name: translatedownload;
-webkit-animation-duration: 1.8s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
}
.state-running {
.at2x('running.png', 20px, 20px);
overflow: hidden;
.runningwave {
position: absolute;
width: 40px;
height: 20px;
left: -20px;
.at2x('runningwave.png', 20px, 20px);
-webkit-animation-name: translatewave;
-webkit-animation-duration: 8.0s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
}
.state-restarting {
display: inline-block;
width: 20px;
height: 20px;
.at2x('restarting.png', 20px, 20px);
background-repeat: repeat-x;
-webkit-animation-delay: -1s;
-webkit-animation-name: rotate;
-webkit-animation-duration: 3.0s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
}
}
}
}
/* Auto-Update */
.update-notification {
background-color: white;
opacity: 0.9;
position: fixed;
bottom: 0;
width: 259px;
padding: 10px;
color: @gray-normal;
font-size: 12px;
.text {
position: relative;
top: 3px;
}
.btn {
position: relative;
float: right;
}
}
.update-padding {
position: relative;
height: 40px;
}

View File

@ -1,5 +1,6 @@
@import "bootstrap/bootstrap.less";
@import "variables.less";
@import "mixins.less";
@import "clearsans.less";
@import "theme.less";
@import "icons.less";
@ -8,8 +9,14 @@
@import "radial.less";
@import "preferences.less";
@import "header.less";
@import "containers.less";
@import "container-modal.less";
@import "layout.less";
@import "left-panel.less";
@import "right-panel.less";
@import "new-container.less";
@import "container-home.less";
@import "container-logs.less";
@import "container-settings.less";
@import "animation.less";
html, body {
height: 100%;
@ -17,108 +24,8 @@ html, body {
overflow: hidden;
-webkit-user-select: none;
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
cursor: default;
img {
pointer-events: none;
}
}
/*::-webkit-scrollbar {
width: 13px;
}
::-webkit-scrollbar-track {
margin: 3px;
-webkit-border-radius: 5px;
border-radius: 5px;
background: none;
}
::-webkit-scrollbar-thumb {
border: 3px solid rgba(0, 0, 0, 0);
background-clip: padding-box;
width: 7px;
border-radius: 8px;
background-color: rgba(0,0,0,0.2);
&:hover {
background-color: rgba(0,0,0,0.25);
}
}*/
.question {
color: @gray-lightest;
font-size: 10px;
}
.popover {
font-family: 'Clear Sans', sans-serif;
color: @gray-normal;
font-weight: 400;
font-size: 13px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.10);
border: 1px solid #ddd;
}
.update-notification {
background-color: white;
opacity: 0.9;
position: fixed;
bottom: 0;
width: 259px;
padding: 10px;
//border-top: 1px solid darken(#FCF8E3, 5%);
color: @gray-normal;
font-size: 12px;
.text {
position: relative;
top: 3px;
}
.btn {
position: relative;
float: right;
}
}
.update-padding {
position: relative;
height: 40px;
}
@-webkit-keyframes spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
@-webkit-keyframes translatewave {
from {
-webkit-transform: translateX(0px);
}
to {
-webkit-transform: translateX(20px);
}
}
@-webkit-keyframes translatedownload {
0% {
-webkit-transform: translateY(6px);
opacity: 0;
}
25% {
opacity: 1;
-webkit-transform: translateY(6px);
}
50% {
opacity: 1;
-webkit-transform: translateY(20px);
}
100% {
opacity: 1;
-webkit-transform: translateY(20px);
}
}

23
styles/mixins.less Normal file
View File

@ -0,0 +1,23 @@
.traffic-light() {
box-sizing: border-box;
display: inline-block;
background: white;
margin-right: 9px;
height: 12px;
width: 12px;
border: 1px solid @traffic-light-gray-border;
border-radius: 6px;
box-shadow: 0px 1px 1px 0px rgba(234,234,234,0.50);
-webkit-app-region: no-drag;
&.enabled:hover {
box-shadow: 0px 1px 1px 0px rgba(195,198,201,0.50);
}
&.enabled:hover:active {
cursor: default;
-webkit-filter: brightness(92%);
}
}
.brand-gradient() {
background-image: linear-gradient(-180deg, #24B8EB 4%, #24A3EB 100%);
}

247
styles/new-container.less Normal file
View File

@ -0,0 +1,247 @@
.new-container {
display: flex;
flex: 1 auto;
flex-direction: column;
padding: 35px 20px 32px 25px;
.results {
display: flex;
flex-direction: column;
flex: 1 auto;
.no-results {
flex: 1 auto;
display: flex;
align-items: center;
.loader {
margin: 0 auto;
margin-top: -20%;
text-align: center;
width: 300px;
h2 {
margin-bottom: 20px;
}
}
h1 {
color: @gray-lightest;
font-size: 24px;
margin: 0 auto;
margin-top: -20%;
}
}
}
.new-container-header {
margin-bottom: 18px;
display: flex;
flex: 0 auto;
.text {
flex: 1 auto;
width: 50%;
font-size: 14px;
color: @gray-lighter;
}
.search {
flex: 1 auto;
margin-right: 30px;
.search-bar {
top: -7px;
position: relative;
.loading {
position: absolute;
left: 10px;
top: 7px;
width: 16px;
height: 16px;
-webkit-animation-name: spin;
-webkit-animation-duration: 1.8s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
.search-icon {
font-size: 18px;
color: @gray-lighter;
position: absolute;
top: 5px;
left: 10px;
}
input {
border-radius: 20px;
font-size: 12px;
height: 30px;
padding: 4px 8px 4px 35px;
color: @gray-darkest;
margin-bottom: 3px;
border-color: @gray-lightest;
box-shadow: none;
&:focus {
box-shadow: none;
border-color: @gray-lighter;
}
&::-webkit-input-placeholder {
color: #CCC;
font-weight: 400;
}
}
}
}
}
}
.result-grid {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
margin-top: 10px;
overflow: auto;
.image-item {
display: flex;
width: 320px;
height: 166px;
border-radius: 4px;
border: 1px solid @gray-lightest;
background-color: white;
margin-right: 20px;
margin-bottom: 20px;
.tag-overlay {
z-index: 999;
background-color: rgba(0,0,0,0.8);
border-radius: 4px;
width: 320px;
height: 166px;
position: absolute;
color: white;
font-size: 13px;
display: none;
padding: 10px;
.tag-list {
display: flex;
flex-direction: row;
align-items: flex-start;
align-content: flex-start;
flex-flow: row wrap;
height: 140px;
overflow: auto;
.tag {
display: inline-block;
flex: 0 auto;
margin-right: 2px;
padding: 3px 5px;
&:hover {
background-color: rgba(255,255,255,0.2);
border-radius: 20px;
}
}
}
.tags-loading {
position: relative;
left: 42%;
top: 20%;
text-align: center;
margin: 14px auto;
-webkit-animation-name: spin;
-webkit-animation-duration: 1.8s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
}
.logo {
flex: 1 auto;
min-width: 90px;
background-color: @brand-action;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
justify-content: center;
text-align: center;
img {
margin-top: 15px;
}
}
.card {
padding: 10px 20px 10px 20px;
.name {
font-size: 18px;
color: @gray-darkest;
margin-bottom: 5px;
width: 190px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
img {
margin-right: 7px;
position: relative;
top: -1px;
}
}
.description {
font-size: 12px;
color: @gray-normal;
height: 65px;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
display: -webkit-box;
word-wrap: break-word;
}
.actions {
width: 190px;
padding-top: 25px;
.stars {
height: 15px;
font-size: 10px;
color: @gray-darker;
border-right: 1px solid @gray-lightest;
padding-right: 10px;
.icon {
position: relative;
font-size: 16px;
margin-right: 3px;
top: -1px;
color: @gray-darkest;
}
.text {
position: relative;
top: -6px;
}
}
.tags {
height: 15px;
font-size: 10px;
color: @gray-darker;
padding-left: 10px;
.icon {
position: relative;
font-size: 11px;
margin-right: 2px;
top: 2px;
color: @gray-darkest;
}
.text {
position: relative;
top: 0px;
padding: 3px 5px;
text-decoration: underline;
&:hover {
background-color: @brand-action;
color: white;
border-radius: 20px;
}
}
}
.action {
flex: 1 auto;
.btn {
text-align: right;
position: relative;
float: right;
top: -7px;
}
}
display: flex;
flex-direaction: row;
position: relative;
bottom: 0px;
}
}
}
}

125
styles/right-panel.less Normal file
View File

@ -0,0 +1,125 @@
.details {
background-color: #F9F9F9;
margin: 0;
padding: 0;
box-sizing: border-box;
flex: 1;
display: flex;
flex-direction: column;
.details-subheader {
flex: 0 auto;
display: flex;
flex-direction: row;
position: relative;
border-bottom: 1px solid #DCE2E2;
background-color: white;
height: 57px;
padding: 6px 10px 10px 24px;
font-size: 13px;
color: @gray-normal;
.details-header-actions {
flex: 1 auto;
text-align: left;
margin-top: -12px;
.action {
display: inline-block;
&.disabled {
opacity: 0.3;
}
.action-icon {
color: @gray-normal;
font-size: 30px;
margin-right: 20px;
}
.btn-label {
position: relative;
top: 0px;
display: block;
color: @brand-action;
font-size: 10px;
&.run {
left: 8px;
}
&.restart {
left: 1px;
}
&.terminal {
left: -2px;
}
visibility: hidden;
}
}
}
.details-subheader-tabs {
flex: 1 auto;
text-align: right;
margin-right: 3px;
margin-top: 3px;
.tab {
margin-left: 16px;
padding: 6px 10px;
font-weight: 400;
&:hover {
border-radius: 40px;
background-color: #F9F9F9;
}
&.active {
border-radius: 40px;
color: white;
background-image: linear-gradient(-180deg, #24B8EB 4%, #24A3EB 100%);
}
&.disabled {
opacity: 0.5;
}
}
}
}
.details-header {
flex: 0 auto;
display: flex;
flex-direction: row;
padding: 31px 24px 18px 24px;
position: relative;
background-color: white;
height: 75px;
h1 {
margin: 0;
font-size: 20px;
font-weight: 400;
margin: 0;
color: @gray-darkest;
}
.status {
font-size: 10px;
font-weight: 500;
position: relative;
top: 8px;
left: 14px;
&.running {
color: @brand-positive;
}
&.paused {
color: @gray-lighter;
}
&.stopped {
color: @gray-lighter;
}
&.downloading {
color: @brand-action;
}
}
}
.details-progress {
margin: 20% auto 0;
text-align: center;
width: 300px;
h2 {
margin-bottom: 20px;
}
}
.details-panel {
flex: 1;
overflow: auto;
background-color: #FFF;
}
}

View File

@ -22,17 +22,12 @@ h4 {
}
a {
transition: all 0.25s;
transition: color 0.25s;
&:hover {
text-decoration: none;
}
}
.popover-content {
color: @gray-normal;
font-size: 13px;
}
input[type="text"] {
&.line {
border: 0;

View File

@ -3,8 +3,19 @@
@brand-positive: #15CC35;
@brand-negative: #FF5F52;
@traffic-light-green: @brand-positive;
@traffic-light-green-border: #17B230;
@traffic-light-red: @brand-negative;
@traffic-light-red-border: #E33E32;
@traffic-light-yellow: #FFBE05;
@traffic-light-yellow-border: #E2A100;
@traffic-light-gray: #DDDDDD;
@traffic-light-gray-border: #D3D3D3;
@gray-darkest: #253237;
@gray-darker: #394C51;
@gray-normal: #546C70;
@gray-lighter: #7A9999;
@gray-lightest: #C7D7D7;
@divider-color: #DCE2E2;