From bebb2395f94f8304edc63f24fb5f1f43059ab015 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Mon, 16 Feb 2015 10:50:26 -0800 Subject: [PATCH] Implemented tags dropdown. --- images/loading-white.png | Bin 0 -> 530 bytes images/loading-white@2x.png | Bin 0 -> 1110 bytes src/ImageCard.react.js | 113 ++++++++++++++++++++++++++++++++++++ src/Main.js | 1 - src/NewContainer.react.js | 89 ++-------------------------- src/NoContainers.react.js | 13 ----- styles/containers.less | 50 +++++++++++++++- 7 files changed, 166 insertions(+), 100 deletions(-) create mode 100644 images/loading-white.png create mode 100644 images/loading-white@2x.png create mode 100644 src/ImageCard.react.js delete mode 100644 src/NoContainers.react.js diff --git a/images/loading-white.png b/images/loading-white.png new file mode 100644 index 0000000000000000000000000000000000000000..17096a362c2c7ea8ba69412b2e14dd3da3861bab GIT binary patch literal 530 zcmV+t0`2{YP)Px$%t=H+R7efAmQODOK^Vrnh$3+j5!G;U5Ck`Fj+M}ZqqBok6I}Qde1KlWg~Z9F z;+r%MJygeRo@Bw}`X$ZgGY3y`z?+bSjoafvb3_}gh;Tp`dMm7oF+%$k!)9OjHkMF~`LrS-2v zBEM_KrKFdf=t9G92<||OSNjR|H^EYY*C9wna~G`yi4;3bSKtj)I5R&9%w71)^-`eI zqJiNu=+UU;Ytw2M9sUhxpY}j|RPYQjgKz-4a+w!`5up|Vx)a@^RD&bP!6c}N3H{f( zV`zY+G0|5Z%AuFuY15ZcSeh-`PlC_fm}-G_6oaBZTNJO=uLY_#bV-@l$3dh%0rw!} U973Sp$^ZZW07*qoM6N<$f;g1%VE_OC literal 0 HcmV?d00001 diff --git a/images/loading-white@2x.png b/images/loading-white@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..75051f37e54f45fb1d258cf7c7bbd1bd4fddce09 GIT binary patch literal 1110 zcmV-c1gZOpP)Px(5J^NqRA>d&nmtSuK^TTTfe48vm zznQtriXvcUW~LH1ZLk$?hg;!VxCYL^NjMH)!6Enr_GL1ePh6J~Q!Y_<-&4Cs8Sj}Y<)Eqeg+u;^yQIH;6Au>(FEimk^|HOU??uBKM zjzS7h?;yMlhu|q#+#!U+4yYku@r%r5*bt)09}@y4-i7XzhJfEdq=t=q=k-%-9QzGK z)M&U&}y?yEfxl`m>{_T^-or z7>Av_PuZuAm}YgL(HN&mYjNT$+?(5^4ruovz(}xy3JjiIwaT+-PzUS_%Pn9F`;eY+ zMAWGR%L%#X|D0-dV9NBM&ZK=z);gl5)B!tbYk9W%yl`=E@R&NFZIA#JB=oDO;z>`;v4u~eWYWbE>cI6bU(Zb ze?u2)GjiAzG%;}$b25-6$-j#;&~)=}#y6ck%&F`{^0A+e&$R+w*2DWE*c2Ezxg z#Q~krBUbN;uwMgnDD(odFQL#v#wg!vk zG?w(w9$JGajPI1MeC;M1&07*qoM6N<$g53xNzW@LL literal 0 HcmV?d00001 diff --git a/src/ImageCard.react.js b/src/ImageCard.react.js new file mode 100644 index 0000000000..2c01f67017 --- /dev/null +++ b/src/ImageCard.react.js @@ -0,0 +1,113 @@ +var $ = require('jquery'); +var React = require('react/addons'); +var RetinaImage = require('react-retina-image'); +var ContainerStore = require('./ContainerStore'); + +var ImageCard = React.createClass({ + getInitialState: function () { + return { + tags: [], + chosenTag: 'latest' + }; + }, + handleTagClick: function (tag) { + this.setState({ + chosenTag: tag + }); + var $tagOverlay = $(this.getDOMNode()).find('.tag-overlay'); + $tagOverlay.fadeOut(300); + }, + handleClick: function (name) { + ContainerStore.create(name, this.state.chosenTag, function (err) { + if (err) { + throw err; + } + $(document.body).find('.new-container-item').parent().fadeOut(); + }.bind(this)); + }, + handleTagOverlayClick: function (name) { + var $tagOverlay = $(this.getDOMNode()).find('.tag-overlay'); + $tagOverlay.fadeIn(300); + $.get('https://registry.hub.docker.com/v1/repositories/' + name + '/tags', function (result) { + console.log(result); + this.setState({ + tags: result + }); + }.bind(this)); + + }, + handleCloseTagOverlay: function () { + var $tagOverlay = $(this.getDOMNode()).find('.tag-overlay'); + $tagOverlay.fadeOut(300); + }, + render: function () { + var self = this; + var name; + if (this.props.image.is_official) { + name = {this.props.image.name}; + } else { + name = {this.props.image.name}; + } + var description; + if (this.props.image.description) { + description = this.props.image.description; + } else { + description = "No description."; + } + var logoStyle = { + backgroundImage: `linear-gradient(-180deg, ${this.props.image.gradient_start} 4%, ${this.props.image.gradient_end} 100%)` + }; + var imgsrc; + if (this.props.image.img) { + imgsrc = `http://kitematic.com/recommended/${this.props.image.img}`; + } else { + imgsrc = 'http://kitematic.com/recommended/kitematic_html.png'; + } + var tags; + if (this.state.tags.length > 0) { + var tagDisplay = this.state.tags.map(function (t) { + return
{t.name}
; + }); + tags = ( +
+ {tagDisplay} +
+ ); + } else { + tags = ; + } + return ( +
+
+ {tags} +
+
+ +
+
+
+ {name} +
+
+ {description} +
+
+
+ + {this.props.image.star_count} +
+
+ + {this.state.chosenTag} +
+
+ Create +
+
+
+
+ ); + } +}); + +module.exports = ImageCard; diff --git a/src/Main.js b/src/Main.js index 69beea6499..63f46262bb 100644 --- a/src/Main.js +++ b/src/Main.js @@ -10,7 +10,6 @@ var boot2docker = require('./boot2docker'); var ContainerStore = require('./ContainerStore'); var SetupStore = require('./SetupStore'); var settingsjson; -var Menu = require('./Menu'); try { settingsjson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'settings.json'), 'utf8')); diff --git a/src/NewContainer.react.js b/src/NewContainer.react.js index 02b3a17a07..ccda251475 100644 --- a/src/NewContainer.react.js +++ b/src/NewContainer.react.js @@ -1,10 +1,9 @@ -var _ = require('underscore'); var $ = require('jquery'); var React = require('react/addons'); var RetinaImage = require('react-retina-image'); var ContainerStore = require('./ContainerStore'); var Radial = require('./Radial.react'); -var assign = require('object-assign'); +var ImageCard = require('./ImageCard.react'); var NewContainer = React.createClass({ _searchRequest: null, @@ -12,10 +11,7 @@ var NewContainer = React.createClass({ return { query: '', results: [], - loading: false, - tags: {}, - active: null, - creating: [] + loading: false }; }, componentDidMount: function () { @@ -79,32 +75,7 @@ var NewContainer = React.createClass({ }, 200); } }, - handleClick: function (name) { - ContainerStore.create(name, 'latest', function (err) { - if (err) { - throw err; - } - $(document.body).find('.new-container-item').parent().fadeOut(); - }.bind(this)); - }, - 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)); - }, render: function () { - var self = this; var title = this.state.query ? 'Results' : 'Recommended'; var data = []; if (this.state.results) { @@ -112,61 +83,9 @@ var NewContainer = React.createClass({ } var results; if (data.length) { - var items = data.map(function (r) { - var name; - if (r.is_official) { - name = {r.name}; - } else { - name = {r.name}; - } - var description; - if (r.description) { - description = r.description; - } else { - description = "No description."; - } - var logoStyle = { - backgroundImage: `linear-gradient(-180deg, ${r.gradient_start} 4%, ${r.gradient_end} 100%)` - }; - var imgsrc; - if (r.img) { - imgsrc = `http://kitematic.com/recommended/${r.img}`; - } else { - imgsrc = 'http://kitematic.com/recommended/kitematic_html.png'; - } - var action; - if (_.find(self.state.creating, r.name)) { - action = ; - } else { - action = Create; - } + var items = data.map(function (image) { return ( -
-
- -
-
-
- {name} -
-
- {description} -
-
-
- - {r.star_count} -
-
- - latest -
-
- {action} -
-
-
-
+ ); }); diff --git a/src/NoContainers.react.js b/src/NoContainers.react.js deleted file mode 100644 index 2be1c9d0eb..0000000000 --- a/src/NoContainers.react.js +++ /dev/null @@ -1,13 +0,0 @@ -var React = require('react/addons'); - -var NoContainers = React.createClass({ - render: function () { - return ( -
-

No Containers

-
- ); - } -}); - -module.exports = NoContainers; diff --git a/styles/containers.less b/styles/containers.less index 750a29aef8..32a2449397 100644 --- a/styles/containers.less +++ b/styles/containers.less @@ -34,6 +34,48 @@ 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: scroll; + .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; @@ -100,13 +142,19 @@ .icon { position: relative; font-size: 11px; - margin-right: 5px; + margin-right: 2px; top: 2px; color: @gray-darkest; } .text { position: relative; top: 0px; + padding: 3px 5px; + &:hover { + background-color: @brand-action; + color: white; + border-radius: 20px; + } } } .action {