Checkpoint commit
authorJude N <juden@pwan.org>
Tue, 27 Jun 2017 03:52:08 +0000 (23:52 -0400)
committerJude N <juden@pwan.org>
Tue, 27 Jun 2017 03:52:08 +0000 (23:52 -0400)
TODO.md
web/controllers/radar_controller.ex
web/models/radar_data_point.ex
web/static/vendor/base.css
web/templates/radar/index.html.eex
web/templates/radar_data_point/form.html.eex

diff --git a/TODO.md b/TODO.md
index 609db16..0eab2ab 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -1,9 +1,21 @@
-- Create database
-  - quadrant: enum (tool, technique, platform, language)
-  - cycle: enum (adapt, trial, assess, hold)
-  - is_new: boolean
-  - name: string
-  - description: string
+- Bugs:
+  - Top of 'Techniques is cut off'
+  - Right hand side is cut off a lot: only the 'H' of 'HOLD' is shown !
+  - Bottom of the radar is truncated as well
+
+- Big Features
+  - The ability to drag and drop items within the map
+    - Would need to store the location of the items
+  - Ability to move maps into the future:
+    - Copy the radar but switch any 'is_new' items to False
+    - Any new items have 'is_new' set to true by default.
+
+- database
+  - Update README.md with steps for creating the database
+  - Surface the index number used ?
+  - Surface a 'Radar' table with name / index /
+    - Support showing different radars / multiple users / changes over time
+      - Allow saving radars under a different name.
 
 - Include 'ecto_enum' to support enums: https://github.com/gjaldon/ecto_enum#using-postgress-enum-type
 
index 24b2e5a..44126db 100644 (file)
@@ -3,9 +3,27 @@ defmodule TechRadarEditor.RadarController do
 
   alias TechRadarEditor.RadarDataPoint
 
+  def _make_quadrants(radar_data_points) do
+      List.foldl(radar_data_points,
+                 %{1 => [], 2 => [], 3 => [], 4 => []},
+                 fn(p, acc) -> %{acc | p.quadrant => acc[p.quadrant] ++ [p]} end
+                 )
+  end
+
   # http://www.cultivatehq.com/posts/how-to-set-different-layouts-in-phoenix/
   def index(conn, _params) do
-    radar_data_points = Repo.all(RadarDataPoint)
-    render conn, "index.html", radar_data_points: radar_data_points, layout: {TechRadarEditor.LayoutView, "radar.html"}
+    radar_quadrants = _make_quadrants(Repo.all(RadarDataPoint))
+    render conn, "index.html", radar_quadrants: radar_quadrants, layout: {TechRadarEditor.LayoutView, "radar.html"}
+  end
+
+  # UNTESTED
+  def delete(conn, %{"id" => id}) do
+      radar_data_point = Repo.get!(RadarDataPoint, id)
+      Repo.delete!(radar_data_point)
+
+      conn
+      |> put_flash(:info, "Radar data point " + id + " successfully deleted.")
+      |> redirect(to: radar_path(conn, :index), layout: {TechRadarEditor.LayoutView, "radar.html"} )
   end
+
 end
index bb3580a..fb08bb3 100644 (file)
@@ -27,7 +27,7 @@ defmodule TechRadarEditor.RadarDataPoint do
   end
 
   def cycles do
-     ["Adapt", "Trial", "Assess", "Hold"]
+     ["Adopt", "Trial", "Assess", "Hold"]
   end
 
 
index cb1ac4f..7c56d53 100644 (file)
@@ -2,7 +2,8 @@ body {
   font: 11px 'Open Sans'; }
 
 svg {
-  padding: 20px; }
+    padding: 00px;
+   }
   svg circle:nth-child(1) {
     stroke: none;
     fill: #eaeaea; }
@@ -40,7 +41,7 @@ svg {
   svg text.fourth {
     fill: #8d2145; }
   svg text.first, svg text.second, svg text.third, svg text.fourth {
-    font-size: 16px;
+    font-size: 14px;
     font-weight: bold; }
   svg text.blip-text {
     font-size: 9px;
@@ -71,3 +72,19 @@ svg {
     font-size: 20px;
     font-weight: bold;
     background: #fafafa; }
+
+.radar-input-table {
+  width: 1080px;
+  font-size: 16px;
+  line-height: 26px;
+  padding: 20px; }
+  .radar-input-table tr:nth-child(odd) {
+    background: #bababa; }
+  .radar-input-table tr:nth-child(even) {
+    background: #dadada; }
+  .radar-input-table td {
+    padding: 10px 15px; }
+  .radar-input-table tr.radar-input-status-group {
+    font-size: 20px;
+    font-weight: bold;
+    background: #fafafa; }
index 7ef33f0..e2892e4 100644 (file)
@@ -1,7 +1,51 @@
 <body>
   <div id="radar">
   </div>
-  <div id="ref-table"></div>
+  <div id="new-items">
+
+    <form name="newBlip">
+      <table class="radar-input-table" >
+        <thead>
+          <tr class="radar-input-status-group">
+            <td>Quadrant</td>
+            <td>Cycle</td>
+            <td>Name</td>
+            <td>Description</td>
+            <td< /td>
+          </tr>
+        </thead>
+        <tr c>
+          <td>
+            <select name="quadrant">
+              <option value="1">Tool</option>
+              <option value="2">Technique</option>
+              <option value="3">Platform</option>
+              <option value="4">Language</option>
+            </select>
+          </td>
+          <td>
+            <select name="cycle">
+              <option value="1">Adopt</option>
+              <option value="2">Trial</option>
+              <option value="3">Assess</option>
+              <option value="4">Hold</option>
+            </select>
+          </td>
+          <td>
+            <input type="text" name="name" />
+          </td>
+          <td>
+            <input type="text" name="description" />
+          </td>
+          <td>
+            <input name="Add" type="submit" value="Add" />
+          </td>
+        </tr>
+      </table>
+    </form>
+  </div>
+  <div id="ref-table">
+  </div>
 </body>
 <script>
   var adopt = new tr.models.Cycle('Adopt', 0);
   var platformsQuadrant = new tr.models.Quadrant('Platforms');
   var languageFramework = new tr.models.Quadrant('Languages & Frameworks');
 
+  <% fn_blip_line = fn(p) -> "         new tr.models.Blip('" <> p.name <> "', "
+                             <> String.downcase(Enum.at(TechRadarEditor.RadarDataPoint.cycles, p.cycle-1))  <> ", "
+                             <> if(p.is_new, do: "true", else: "false")
+                             <> if(p.description != nil, do: ",'" <> p.description <> "'", else: "")
+                             <> ")"
+                           end 
+  %>
+
   toolsQuadrant.add([
-      new tr.models.Blip('D3', adopt),
-      new tr.models.Blip('Dependency Management for JavaScript', adopt, true),
-      new tr.models.Blip('Ansible', trial, true),
-      new tr.models.Blip('Calabash', trial, true),
-      new tr.models.Blip('Chaos Monkey', trial, true),
-      new tr.models.Blip('Gatling', trial),
-      new tr.models.Blip('Grunt.js', trial, true),
-      new tr.models.Blip('Hystrix', trial),
-      new tr.models.Blip('Icon fonts', trial),
-      new tr.models.Blip('Librarian-puppet and Librarian-Chef', trial),
-      new tr.models.Blip('Logstash & Graylog2', trial),
-      new tr.models.Blip('Moco', trial, true),
-      new tr.models.Blip('PhantomJS', trial),
-      new tr.models.Blip('Prototype On Paper', trial, true),
-      new tr.models.Blip('SnapCI', trial, true),
-      new tr.models.Blip('Snowplow Analytics & Piwik', trial),
-      new tr.models.Blip('Cloud-init', assess, true),
-      new tr.models.Blip('Docker', assess, true),
-      new tr.models.Blip('Octopus', assess),
-      new tr.models.Blip('Sensu', assess, true),
-      new tr.models.Blip('Travis for OSX/iOS', assess, true),
-      new tr.models.Blip('Visual regression testing tools', assess, true),
-      new tr.models.Blip('Xamarin', assess, true),
-      new tr.models.Blip('Ant', hold, true),
-      new tr.models.Blip('Heavyweight test tools', hold),
-      new tr.models.Blip('TFS', hold)
+<%= raw(Enum.join( Enum.map(@radar_quadrants[1], fn(p) -> fn_blip_line.(p) end),",\n")) %>
   ]);
+
   techniquesQuadrant.add([
-      new tr.models.Blip('Capturing client-side JavaScript errors', adopt),
-      new tr.models.Blip('Continuous delivery for mobile devices', adopt),
-      new tr.models.Blip('Mobile testing on mobile networks', adopt),
-      new tr.models.Blip('Segregated DOM plus node for JS Testing', adopt, true),
-      new tr.models.Blip('Windows infrastructure automation', adopt),
-      new tr.models.Blip('Capture domain events explicitily', trial, true),
-      new tr.models.Blip('Client and server rendering with same code', trial, true),
-      new tr.models.Blip('HTML5 storage instead of cookies', trial),
-      new tr.models.Blip('Instrument all the things', trial, true),
-      new tr.models.Blip('Masterless Chef/Puppet', trial, true),
-      new tr.models.Blip('Micro-services', trial),
-      new tr.models.Blip('Perimeterless enterprise', trial),
-      new tr.models.Blip('Provisioning testing', trial, true),
-      new tr.models.Blip('Structured logging', trial, true),
-      new tr.models.Blip('Bridging physical and digital worlds with simple hardware', assess, true),
-      new tr.models.Blip('Collaborative analytics and data science', assess),
-      new tr.models.Blip('Datensparsamkeit', assess, true),
-      new tr.models.Blip('Development environments in the cloud', assess),
-      new tr.models.Blip('Focus on mean time to recovery', assess),
-      new tr.models.Blip('Machine image as a build artifact', assess),
-      new tr.models.Blip('Tangible interaction', assess, true),
-      new tr.models.Blip('Cloud lift and shift', hold, true),
-      new tr.models.Blip('Ignoring OWASP Top 10', hold, true),
-      new tr.models.Blip('Siloed metrics', hold, true),
-      new tr.models.Blip('Velocity as productivity', hold, true)
+<%= raw(Enum.join( Enum.map(@radar_quadrants[2], fn(p) -> fn_blip_line.(p) end),",\n")) %>
   ]);
+
   platformsQuadrant.add([
-      new tr.models.Blip('Elastic Search', adopt),
-      new tr.models.Blip('MongoDB', adopt),
-      new tr.models.Blip('Neo4J', adopt),
-      new tr.models.Blip('Node.js', adopt),
-      new tr.models.Blip('Redis', adopt),
-      new tr.models.Blip('SMS and USSD as UI', adopt),
-      new tr.models.Blip('Hadoop 2.0', trial),
-      new tr.models.Blip('Hadoop as a service', trial, true),
-      new tr.models.Blip('Open Stack', trial),
-      new tr.models.Blip('PostgreSQL for NoSql', trial),
-      new tr.models.Blip('Vumi', trial),
-      new tr.models.Blip('Akka', assess, true),
-      new tr.models.Blip('Backend as a service', assess, true),
-      new tr.models.Blip('Low-cost robotics', assess, true),
-      new tr.models.Blip('PhoneGap/Apache Cordova', assess),
-      new tr.models.Blip('Private Clouds', assess),
-      new tr.models.Blip('SPDY', assess, true),
-      new tr.models.Blip('Storm', assess, true),
-      new tr.models.Blip('Web Components standard', assess, true),
-      new tr.models.Blip('Big enterprise solutions', hold),
-      new tr.models.Blip('CMS as a platform', hold, true),
-      new tr.models.Blip('Enterprise Data Warehouse', hold, true)
+<%= raw(Enum.join( Enum.map(@radar_quadrants[3], fn(p) -> fn_blip_line.(p) end),",\n")) %>
   ]);
+
   languageFramework.add([
-      new tr.models.Blip('Clojure', adopt, true),
-      new tr.models.Blip('Dropwizard', adopt),
-      new tr.models.Blip('Scala, the good parts', adopt),
-      new tr.models.Blip('Sinatra', adopt),
-      new tr.models.Blip('CoffeeScript', trial),
-      new tr.models.Blip('Go language', trial, true),
-      new tr.models.Blip('Hive', trial, true),
-      new tr.models.Blip('Play Framework 2', trial),
-      new tr.models.Blip('Reactive Extensions across languages', trial, true),
-      new tr.models.Blip('Web API', trial, true),
-      new tr.models.Blip('Elixir', assess, true),
-      new tr.models.Blip('Julia', assess, true),
-      new tr.models.Blip('Nancy', assess),
-      new tr.models.Blip('OWIN', assess),
-      new tr.models.Blip('Pester', assess, true),
-      new tr.models.Blip('Pointer Events', assess, true),
-      new tr.models.Blip('Python 3', assess, true),
-      new tr.models.Blip('TypeScript', assess, true),
-      new tr.models.Blip('Yeoman', assess, true),
-      new tr.models.Blip('Handwritten CSS', hold),
-      new tr.models.Blip('JSF', hold, true)
+<%= raw(Enum.join( Enum.map(@radar_quadrants[4], fn(p) -> fn_blip_line.(p) end),",\n")) %>
   ]);
 
   radar.setFirstQuadrant(toolsQuadrant);
   radar.setThirdQuadrant(platformsQuadrant);
   radar.setFourthQuadrant(languageFramework);
 
-  var radarGraph = new tr.graphing.Radar(1080, radar);
+  // var radarGraph = new tr.graphing.Radar(1080, radar);
+  var radarGraph = new tr.graphing.Radar(1100, radar);
   radarGraph.init('#radar').plot();
   var refTable = new tr.graphing.RefTable(radar);
   refTable.init('#ref-table').render();
-</script>
 
+  ref_table = document.getElementsByClassName('radar-ref-table')[0];
+  for (var i = 0, trow; trow = ref_table.rows[i]; i++) {
+      if (trow.cells.length == 3) {
+         var blip_number = trow.cells[0].textContent;
+         var new_cell = trow.insertCell(-1); 
+         new_cell.innerHTML = "<a href='./delete/" + blip_number + "' class='btn btn-danger btn-xs'>Delete</a>" 
+      };
+  };
   
+</script>
 
 <a href="/admin/radar_data_point">Admin Radar Data Point</a>
 
index e1f22ba..211a7fb 100644 (file)
@@ -1,3 +1,4 @@
+
 <%= form_for @changeset, @action, fn f -> %>
   <%= if @changeset.action do %>
     <div class="alert alert-danger">
@@ -14,7 +15,6 @@
   <div class="form-group">
     <%= label f, :cycle, class: "control-label" %>
     <%= select f, :cycle,  Enum.with_index(TechRadarEditor.RadarDataPoint.cycles,1), class: "form-control" %>
-    <!-- <%= select f, :cycle, ["Adapt": 1, "Trial": 2, "Assess": 3, "Hold": 4], class: "form-control" %> -->
     <%= error_tag f, :cycle %>
   </div>