DataInventory

chore: pre-submission

1/15/2020 3:37:43 PM

Details

diff --git a/app/Controllers/Http/StatusController.js b/app/Controllers/Http/StatusController.js
new file mode 100644
index 0000000..10d52fe
--- /dev/null
+++ b/app/Controllers/Http/StatusController.js
@@ -0,0 +1,119 @@
+'use strict'
+
+/** @typedef {import('@adonisjs/framework/src/Request')} Request */
+/** @typedef {import('@adonisjs/framework/src/Response')} Response */
+/** @typedef {import('@adonisjs/framework/src/View')} View */
+const Status = use('App/Models/Status')
+const { validate } = use('Validator')
+
+/**
+ * Resourceful controller for interacting with statuses
+ */
+class StatusController {
+  /**
+   * Show a list of all statuses.
+   * GET statuses
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   * @param {View} ctx.view
+   */
+  async index ({ request, response, view }) {
+    const statuses = await Status.all()
+  
+    return view.render('status.index', {
+      statuses: statuses.toJSON()
+    })
+  }
+
+  /**
+   * Render a form to be used for creating a new status.
+   * GET statuses/create
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   * @param {View} ctx.view
+   */
+  async create ({ request, response, view }) {
+    return view.render('status.create')
+  }
+
+  /**
+   * Create/save a new status.
+   * POST statuses
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   */
+  async store ({ request, response }) {
+
+    const data = request.only(['status'])
+
+    const validation = await validate(request.all(), {
+      status: 'required',
+    }, {
+      'status.required': `Status is required`,
+    })
+
+    if(validation.fails()) {
+      session.withErrors(validation.messages()).flashAll()
+      return response.redirect('back')
+    }
+
+    await Status.create(data)
+
+    return response.redirect('/status')
+
+  }
+
+  /**
+   * Display a single status.
+   * GET statuses/:id
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   * @param {View} ctx.view
+   */
+  async show ({ params, request, response, view }) {
+  }
+
+  /**
+   * Render a form to update an existing status.
+   * GET statuses/:id/edit
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   * @param {View} ctx.view
+   */
+  async edit ({ params, request, response, view }) {
+  }
+
+  /**
+   * Update status details.
+   * PUT or PATCH statuses/:id
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   */
+  async update ({ params, request, response }) {
+  }
+
+  /**
+   * Delete a status with id.
+   * DELETE statuses/:id
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   */
+  async destroy ({ params, request, response }) {
+  }
+}
+
+module.exports = StatusController
diff --git a/app/Controllers/Http/StewardController.js b/app/Controllers/Http/StewardController.js
new file mode 100644
index 0000000..dcd75ba
--- /dev/null
+++ b/app/Controllers/Http/StewardController.js
@@ -0,0 +1,127 @@
+'use strict'
+
+/** @typedef {import('@adonisjs/framework/src/Request')} Request */
+/** @typedef {import('@adonisjs/framework/src/Response')} Response */
+/** @typedef {import('@adonisjs/framework/src/View')} View */
+const Steward = use('App/Models/Steward')
+const Contact = use('App/Models/Contact')
+const Element = use('App/Models/Element')
+const { validate } = use('Validator')
+
+/**
+ * Resourceful controller for interacting with stewards
+ */
+class StewardController {
+  /**
+   * Show a list of all stewards.
+   * GET stewards
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   * @param {View} ctx.view
+   */
+  async index ({ request, response, view }) {
+    const stewards = await Steward.query().with('contact').with('elements').fetch()
+    return view.render('stewards.index', {
+      stewards: stewards.toJSON()
+    })
+  }
+
+  /**
+   * Render a form to be used for creating a new steward.
+   * GET stewards/create
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   * @param {View} ctx.view
+   */
+  async create ({ request, response, view }) {
+    const contacts = await Contact.all()
+    const elements = await Element.all()
+
+    return view.render('stewards.create', {
+      contacts: contacts.toJSON(),
+      elements: elements.toJSON()
+    })
+  }
+
+  /**
+   * Create/save a new steward.
+   * POST stewards
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   */
+  async store ({ request, response }) {
+
+    // const data = request.only(['contact_id', 'element_id'])
+    var data = {}
+    data['contact_id'] = request.input('contact_id')
+    data['start_date'] = new Date()
+    data['end_date'] = new Date()
+
+    var element = request.input('element_id')
+
+    var steward = await Steward.create(data)
+    await steward.elements().attach([element])
+    
+    return response.redirect('/stewards')
+
+  }
+
+  /**
+   * Display a single steward.
+   * GET stewards/:id
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   * @param {View} ctx.view
+   */
+  async show ({ params, request, response, view }) {
+  }
+
+  /**
+   * Render a form to update an existing steward.
+   * GET stewards/:id/edit
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   * @param {View} ctx.view
+   */
+  async edit ({ params, request, response, view }) {
+  }
+
+  /**
+   * Update steward details.
+   * PUT or PATCH stewards/:id
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   */
+  async update ({ params, request, response }) {
+  }
+
+  /**
+   * Delete a steward with id.
+   * DELETE stewards/:id
+   *
+   * @param {object} ctx
+   * @param {Request} ctx.request
+   * @param {Response} ctx.response
+   */
+  async destroy ({ params, request, response }) {
+    const steward = await Steward.findOrFail(params.id)
+    await steward.elements().detach()
+    await steward.delete()
+
+    return response.redirect('/stewards')
+  }
+}
+
+module.exports = StewardController
diff --git a/app/Models/Element.js b/app/Models/Element.js
index 0729410..b4b0ff5 100644
--- a/app/Models/Element.js
+++ b/app/Models/Element.js
@@ -9,6 +9,10 @@ class Element extends Model {
     return this.belongsTo('App/Models/Theme')
   }
 
+  stewards() {
+    return this.belongsToMany('App/Models/Steward').pivotTable('elements_stewards').withTimestamps()
+  }
+
 }
 
 module.exports = Element
diff --git a/app/Models/Status.js b/app/Models/Status.js
new file mode 100644
index 0000000..097693b
--- /dev/null
+++ b/app/Models/Status.js
@@ -0,0 +1,12 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class Status extends Model {
+  static get table () {
+    return 'submission_statuses'
+  }
+}
+
+module.exports = Status
diff --git a/app/Models/Steward.js b/app/Models/Steward.js
new file mode 100644
index 0000000..0f83237
--- /dev/null
+++ b/app/Models/Steward.js
@@ -0,0 +1,18 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class Steward extends Model {
+
+    contact() {
+      return this.belongsTo('App/Models/Contact')
+    }
+
+    elements() {
+      return this.belongsToMany('App/Models/Element').pivotTable('elements_stewards').withTimestamps()
+    }
+
+}
+
+module.exports = Steward
diff --git a/database/migrations/1575323434337_elements_stewards_schema.js b/database/migrations/1575323434337_elements_stewards_schema.js
index 07638ea..ba435a0 100644
--- a/database/migrations/1575323434337_elements_stewards_schema.js
+++ b/database/migrations/1575323434337_elements_stewards_schema.js
@@ -6,6 +6,7 @@ const Schema = use('Schema')
 class ElementsStewardsSchema extends Schema {
   up () {
     this.create('elements_stewards', (table) => {
+      table.increments('id')
       table.integer('element_id').references('id').inTable('elements')
       table.integer('steward_id').references('id').inTable('stewards')
       table.timestamps()
diff --git a/resources/views/elements/index.edge b/resources/views/elements/index.edge
index a8a48ae..56a5654 100644
--- a/resources/views/elements/index.edge
+++ b/resources/views/elements/index.edge
@@ -3,7 +3,7 @@
 @section('content')
 
 <section class="box is-full-width">
-  <h3 class="is-size-3">Theme Actions</h3>
+  <h3 class="is-size-3">Element Actions</h3>
   <ul>
     <li><a href="{{ route('/elements/create') }}">Add Element</a></li>
   </ul>
diff --git a/resources/views/inc/nav.edge b/resources/views/inc/nav.edge
index 908f96f..b588092 100644
--- a/resources/views/inc/nav.edge
+++ b/resources/views/inc/nav.edge
@@ -1,7 +1,15 @@
 <section class="content box">
-  <h2 class="is-size-5">Main Links</h2>
+  <h2 class="is-size-5">Data Submissions</h2>
   <ul>
-    <li>Main link...</li>
+    <li>Add Submission</li>
+  </ul>
+</section>
+<section class="content box">
+  <h2 class="is-size-5">Dashboard Links</h2>
+  <ul>
+    <li>Submissions</li>
+    <li>Stewards</li>
+    <li>Datasets</li>
   </ul>
 </section>
 
@@ -23,6 +31,12 @@
     <li>
       <a href="{{ route('/organization_types.index') }}">Organization Types</a>
     </li>
+    <li>
+      <a href="{{ route('/stewards.index') }}">Stewards</a>
+    </li>
+    <li>
+      <a href="{{ route('/status.index') }}">Submission Status</a>
+    </li>
   </ul>
 </section>
 
diff --git a/resources/views/status/create.edge b/resources/views/status/create.edge
new file mode 100644
index 0000000..9563200
--- /dev/null
+++ b/resources/views/status/create.edge
@@ -0,0 +1,29 @@
+@layout('layouts.main')
+
+@section('content')
+
+<form method="POST" action="{{ route('/status.store') }}">
+  {{ csrfField() }}
+  <div class="field">
+    <label class="label">Status Title</label>
+    <input class="input" type="text" name="status" placeholder="Admin boundaries" value="{{ old('status', '') }}" />
+    {{ elIf('<span class="has-text-danger">$self</span>', getErrorFor('status'), hasErrorFor('status')) }}
+  </div>
+
+  <div class="field is-grouped">
+      <div class="control">
+        <button class="button is-link ss-submit" type="submit">Submit</button>
+      </div>
+      <div class="control">
+      <button class="button is-text"><a href="{{ route('/status.index') }}">Cancel</a></button>
+      </div>
+    </div>
+    <!--
+    <div class="notification is-warning">
+      <button class="delete"></button>
+      Building Snapshots for some items may take a couple minutes.  Please be patient!
+    </div>
+    -->
+</form>
+
+@endsection 
\ No newline at end of file
diff --git a/resources/views/status/index.edge b/resources/views/status/index.edge
new file mode 100644
index 0000000..5e4e2f6
--- /dev/null
+++ b/resources/views/status/index.edge
@@ -0,0 +1,38 @@
+@layout('layouts.main')
+
+@section('content')
+
+<section class="box is-full-width">
+  <h3 class="is-size-3">Submission Status Actions</h3>
+  <ul>
+    <li><a href="{{ route('/status/create') }}">Add Status</a></li>
+  </ul>
+</section>
+
+<p>There are {{ statuses.length }} total statuses.</p>
+
+<section class="box">
+  <table class="table">
+    <thead class="thead">
+      <tr>
+        <th>Status</th>
+        <th>Action</th>
+      </tr>
+    </thead>
+    <tbody class="tbody">
+      @each(status in statuses)
+      <tr>
+        <td>{{ status.status }}</td>
+        <td>
+          <form action="{{ route('/status.destroy', { id: status.id }) + '?_method=DELETE'}}" method="post">
+            {{ csrfField() }}
+            <button type="submit" name="button" class="is-small button is-danger" onclick="return confirm('Are you sure you want to delete this status?');">Delete</button>
+          </form>
+        </td>
+      </tr>
+      @endeach
+    </tbody>
+  </table>
+</section>
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/stewards/create.edge b/resources/views/stewards/create.edge
new file mode 100644
index 0000000..2611ebc
--- /dev/null
+++ b/resources/views/stewards/create.edge
@@ -0,0 +1,47 @@
+@layout('layouts.main')
+
+@section('content')
+
+<form method="POST" action="{{ route('/stewards.store') }}">
+  {{ csrfField() }}
+  <div class="field">
+    <label class="label">Contact</label>
+    <div class="select">
+      <select name="contact_id">
+        <option>Select dropdown</option>
+        @each(contact in contacts)
+        <option value="{{contact.id}}">{{contact.first_name}} {{contact.last_name}}</option>
+        @endeach
+      </select>
+    </div>
+  </div>
+
+  <div class="field">
+    <label class="label">Element</label>
+    <div class="select">
+      <select name="element_id">
+        <option>Select dropdown</option>
+        @each(element in elements)
+        <option value="{{element.id}}">{{element.name}}</option>
+        @endeach
+      </select>
+    </div>
+  </div>
+
+  <div class="field is-grouped">
+      <div class="control">
+        <button class="button is-link ss-submit" type="submit">Submit</button>
+      </div>
+      <div class="control">
+      <button class="button is-text"><a href="{{ route('/stewards.index') }}">Cancel</a></button>
+      </div>
+    </div>
+    <!--
+    <div class="notification is-warning">
+      <button class="delete"></button>
+      Building Snapshots for some items may take a couple minutes.  Please be patient!
+    </div>
+    -->
+</form>
+
+@endsection 
\ No newline at end of file
diff --git a/resources/views/stewards/index.edge b/resources/views/stewards/index.edge
new file mode 100644
index 0000000..f2c5a2b
--- /dev/null
+++ b/resources/views/stewards/index.edge
@@ -0,0 +1,42 @@
+@layout('layouts.main')
+
+@section('content')
+
+<section class="box is-full-width">
+  <h3 class="is-size-3">Steward Actions</h3>
+  <ul>
+    <li><a href="{{ route('/stewards/create') }}">Add Steward</a></li>
+  </ul>
+</section>
+
+<p>There are {{ stewards.length }} total stewards.</p>
+
+<section class="box">
+  <table class="table">
+    <thead class="thead">
+      <tr>
+        <th>Element</th>
+        <th>Steward Name</th>
+        <th>Steward Email</th>
+        <th>Action</th>
+      </tr>
+    </thead>
+    <tbody class="tbody">
+      @each(steward in stewards)
+      <tr>
+        <td>{{ steward.elements[0].name}}</td>
+        <td>{{ steward.contact.first_name }} {{ steward.contact.last_name }}</td>
+        <td>{{ steward.contact.email }}</td>
+        <td>
+          <form action="{{ route('/stewards.destroy', { id: steward.id }) + '?_method=DELETE'}}" method="post">
+            {{ csrfField() }}
+            <button type="submit" name="button" class="is-small button is-danger" onclick="return confirm('Are you sure you want to delete this theme?');">Delete</button>
+          </form>
+        </td>
+      </tr>
+      @endeach
+    </tbody>
+  </table>
+</section>
+
+@endsection
\ No newline at end of file

start/routes.js 4(+3 -1)

diff --git a/start/routes.js b/start/routes.js
index 16fa4bb..030e441 100644
--- a/start/routes.js
+++ b/start/routes.js
@@ -24,4 +24,6 @@ Route.resource('/themes','ThemeController')
 Route.resource('/elements', 'ElementController')
 Route.resource('/contacts', 'ContactController')
 Route.resource('/organizations', 'OrganizationController')
-Route.resource('/organization_types', 'OrganizationTypeController')
\ No newline at end of file
+Route.resource('/organization_types', 'OrganizationTypeController')
+Route.resource('/stewards', 'StewardController')
+Route.resource('/status', 'StatusController')
\ No newline at end of file