Browse Source

First working version, ready for tests

loconox 7 years ago
parent
commit
cf3bbf19a1

+ 2 - 2
Gruntfile.js

@@ -50,8 +50,8 @@ module.exports = function (grunt) {
                     'web/assets/js/main.js': [
                         'app/Resources/lib/jquery/dist/jquery.js',
                         'app/Resources/lib/bootstrap-sass/assets/javascripts/bootstrap.js',
-                        'app/Resources/lib/datatables/media/js/jquery.dataTables.js',
-                        'app/Resources/lib/datatables/media/js/dataTables.boostrap.js'
+                        'app/Resources/lib/datatables.net/js/jquery.dataTables.min.js',
+                        'app/Resources/lib/datatables.net-bs/js/dataTables.bootstrap.js '
                     ]
                 }
             }

+ 1 - 2
app/Resources/assets/sass/main.scss

@@ -1,6 +1,5 @@
 // Variables
 @import "bootstrap_config";
 @import "../../lib/bootstrap-sass/assets/stylesheets/bootstrap"; // bootstrap
-@import "../../lib/datatables/media/css/jquery.dataTables.min";
-@import "../../lib/datatables/media/css/dataTables.bootstrap.min";
+@import "../../lib/datatables.net-bs/css/dataTables.bootstrap.min";
 @import "style";

+ 0 - 0
app/Resources/views/default/edit.html.twig


+ 24 - 0
app/Resources/views/reference/create.html.twig

@@ -0,0 +1,24 @@
+{% extends 'base.html.twig' %}
+
+{% block body %}
+    <div class="row">
+        <div class="col-md-6">
+            {#{{ form(form) }}#}
+            {{ form_start(form) }}
+            {{ form_widget(form) }}
+            <div class="form-group">
+                <div class="col-sm-2"></div>
+                <div class="col-sm-10">
+                    <button type="submit"class="btn-success btn">
+                        Créer
+                    </button>
+                </div>
+            </div>
+            {{ form_end(form) }}
+        </div>
+
+        <div class="col-md-12">
+            <a href="{{ path('list') }}" class="btn btn-default">Retour</a>
+        </div>
+    </div>
+{% endblock body %}

+ 44 - 0
app/Resources/views/reference/edit.html.twig

@@ -0,0 +1,44 @@
+{% extends 'base.html.twig' %}
+
+{% block body %}
+    <div class="row">
+        <div class="col-md-6">
+            {#{{ form(form) }}#}
+            {{ form_start(form) }}
+            {{ form_widget(form) }}
+            <div class="form-group">
+                <div class="col-sm-2"></div>
+                <div class="col-sm-10">
+                    <button type="submit" class="btn-success btn">
+                        Editer
+                    </button>
+                    <button class="btn-danger btn reference-delete" data-id="{{ reference.id }}">
+                        Supprimer
+                    </button>
+                </div>
+            </div>
+            {{ form_end(form) }}
+        </div>
+
+        <div class="col-md-12">
+            <a href="{{ path('list') }}" class="btn btn-default">Retour</a>
+        </div>
+    </div>
+{% endblock body %}
+
+{% block javascripts %}
+    <script type="application/javascript">
+        $('.reference-delete').on('click', function (e) {
+            e.preventDefault();
+
+            var id = $(this).data('id');
+            if (window.confirm("Êtes vous sur de vouloir supprimer référence '"+id+"' ?")) {
+                $.ajax('{{ path('delete', {'id': reference.id}) }}', {
+                    method: 'DELETE'
+                }).done(function (response) {
+                    window.location = response.redirect;
+                });
+            }
+        })
+    </script>
+{% endblock javascripts %}

+ 13 - 8
app/Resources/views/default/index.html.twig

@@ -2,13 +2,8 @@
 
 {% block body %}
     <div class="row">
-        <div class="col-md-6">
-            {{ form(form) }}
-        </div>
-    </div>
-    <div class="row">
         <div class="col-md-12">
-            <table class="table table-striped table-references">
+            <table class="table table-striped table-hover table-references">
                 <thead>
                 <tr>
                     <th>Type</th>
@@ -20,7 +15,7 @@
                 </thead>
                 <tbody>
                 {% for reference in references %}
-                    <tr>
+                    <tr data-url="{{ path('edit', {'id': reference.id|escape('url')}) }}">
                         <td>{{ reference.type }}</td>
                         <td>{{ reference.id }}</td>
                         <td>{{ reference.authority }}</td>
@@ -31,13 +26,23 @@
                 </tbody>
             </table>
         </div>
+        <div class="col-md-12">
+            <a href="{{ path('create') }}" class="btn btn-success">Créer</a>
+            <a href="{{ asset('references.yml') }}" class="btn btn-default">Télécharger references.yml</a>
+        </div>
     </div>
 {% endblock %}
 
 {% block javascripts %}
     <script type="text/javascript">
         $(document).ready( function () {
-            $('.table-references').DataTable();
+            $('.table-references').DataTable({
+                drawCallback: function () {
+                    $('.table-references tbody tr').on('click', function() {
+                        window.location = $(this).data('url');
+                    });
+                }
+            });
         } );
     </script>
 {% endblock %}

+ 1 - 1
app/config/services.yml

@@ -18,4 +18,4 @@ services:
     app.manager.reference:
         class: AppBundle\Entity\ReferenceManger
         arguments:
-            - "%kernel.root_dir%/data/references.yaml"
+            - "%kernel.root_dir%/../web/references.yml"

+ 2 - 1
bower.json

@@ -17,6 +17,7 @@
   ],
   "dependencies": {
     "bootstrap-sass": "^3.3.7",
-    "datatables": "^1.10.15"
+    "datatables.net": "^1.10.15",
+    "datatables.net-bs": "^2.1.1"
   }
 }

+ 6 - 4
src/AppBundle/Command/TestCommand.php

@@ -45,8 +45,9 @@ class TestCommand extends ContainerAwareCommand
             new YamlEncoder(
                 null,
                 null,
-                ['yaml_flags'  => Yaml::PARSE_OBJECT_FOR_MAP,
-                 'yaml_inline' => 2,
+                [
+                    'yaml_flags'  => Yaml::PARSE_OBJECT_FOR_MAP,
+                    'yaml_inline' => 2,
                 ]
             ),
         ];
@@ -54,8 +55,9 @@ class TestCommand extends ContainerAwareCommand
         $serializer = new Serializer($normalizers, $encoders);
         $data       = $serializer->deserialize($in, 'AppBundle\\Entity\\References', 'yaml');
         $out        = $serializer->serialize($data, 'yaml');
-        file_put_contents($root.'/../result.yml', $out);
-        var_dump($out === $in);
+        file_put_contents($root.'/../data.yml', $out);
+        $referenceManager = $container->get('app.manager.reference');
+        $all = $referenceManager->findAll();
 
         return;
         $data = Yaml::parse(file_get_contents($filename), Yaml::PARSE_OBJECT_FOR_MAP);

+ 0 - 39
src/AppBundle/Controller/DefaultController.php

@@ -1,39 +0,0 @@
-<?php
-
-namespace AppBundle\Controller;
-
-use AppBundle\Entity\Reference;
-use AppBundle\Form\ReferenceType;
-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
-use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-use Symfony\Component\HttpFoundation\Request;
-
-class DefaultController extends Controller
-{
-    /**
-     * @Route("/", name="homepage")
-     */
-    public function indexAction(Request $request)
-    {
-        $reference = new Reference();
-        $form = $this->createForm(ReferenceType::class, $reference);
-        $form->handleRequest($request);
-
-        if ($form->isSubmitted() && $form->isValid()) {
-            dump($reference);
-
-            $reference = new Reference();
-            $form = $this->createForm(ReferenceType::class, $reference);
-        }
-        $referenceManager = $this->get('app.manager.reference');
-        $references = $referenceManager->findAll();
-
-        return $this->render(
-            'default/index.html.twig',
-            [
-                'references' => $references,
-                'form' => $form->createView(),
-            ]
-        );
-    }
-}

+ 113 - 0
src/AppBundle/Controller/ReferenceController.php

@@ -0,0 +1,113 @@
+<?php
+
+namespace AppBundle\Controller;
+
+
+use AppBundle\Entity\Reference;
+use AppBundle\Form\ReferenceType;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+
+class ReferenceController extends Controller
+{
+    /**
+     * @Route("/", name="list")
+     */
+    public function listAction()
+    {
+        $referenceManager = $this->get('app.manager.reference');
+        $references       = $referenceManager->findAll();
+
+        return $this->render(
+            ':reference:list.html.twig',
+            [
+                'references' => $references,
+            ]
+        );
+    }
+
+    /**
+     * @Route("/create", name="create", methods={"GET", "PUT"})
+     * @param Request $request
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function createAction(Request $request)
+    {
+        $reference = new Reference();
+        $form      = $this->createForm(ReferenceType::class, $reference, ['method' => 'PUT']);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $referenceManager = $this->get('app.manager.reference');
+            $referenceManager->persist($reference);
+            $referenceManager->flush();
+
+            return new RedirectResponse($this->generateUrl('list'));
+        }
+
+        return $this->render(
+            ':reference:create.html.twig',
+            [
+                'form' => $form->createView(),
+            ]
+        );
+    }
+
+    /**
+     * @Route("/{id}/edit", name="edit", methods={"GET", "PATCH"})
+     * @param Request $request
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function editAction(Request $request, $id)
+    {
+        $id               = rawurldecode($id);
+        $referenceManager = $this->get('app.manager.reference');
+        $reference        = $referenceManager->find($id);
+        $form             = $this->createForm(ReferenceType::class, $reference, ['method' => 'PATCH']);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $referenceManager->persist($reference);
+            $referenceManager->flush();
+
+            return new RedirectResponse($this->generateUrl('list'));
+        }
+
+        return $this->render(
+            ':reference:edit.html.twig',
+            [
+                'reference' => $reference,
+                'form' => $form->createView(),
+            ]
+        );
+    }
+
+    /**
+     * @Route("/{id}", name="delete")
+     * @Method("DELETE")
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function deleteAction($id)
+    {
+        $id               = rawurldecode($id);
+        $referenceManager = $this->get('app.manager.reference');
+        $reference        = $referenceManager->find($id);
+
+        if ( ! $reference) {
+            throw $this->createNotFoundException();
+        }
+        $referenceManager->remove($reference);
+        $referenceManager->flush();
+
+        $response = ['status' => 'ok', 'redirect' => $this->generateUrl('list')];
+
+        return new JsonResponse($response);
+    }
+}

+ 85 - 79
src/AppBundle/Entity/Reference.php

@@ -56,377 +56,377 @@ class Reference
     public $type;
 
     /**
-     * @var mixed
+     * @var string
      * @Assert\NotNull()
      */
     public $id;
 
     /**
-     * @var array
+     * @var array|null
      */
     public $categories;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $language;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $journalAbbreviation;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $shortTitle;
 
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $author;
 
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $collectionEditor;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $composer;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $containerAuthor;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $director;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $editor;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $editorialDirector;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $interviewer;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $illustrator;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $originalAuthor;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $recipient;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $reviewedAuthor;
     /**
-     * @var Name[]
+     * @var Name[]|null
      */
     public $translator;
 
     /**
-     * @var Date
+     * @var Date|null
      */
     public $accessed;
 
     /**
-     * @var Date
+     * @var Date|null
      */
     public $container;
 
     /**
-     * @var Date
+     * @var Date|null
      */
     public $eventDate;
 
     /**
-     * @var Date
+     * @var Date|null
      */
     public $issued;
 
     /**
-     * @var Date
+     * @var Date|null
      */
     public $originalDate;
 
     /**
-     * @var Date
+     * @var Date|null
      */
     public $submitted;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $abstract;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $annote;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $archive;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $archiveLocation;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $archivePlace;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $authority;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $callNumber;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $chapterNumber;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $citationNumber;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $citationLabel;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $collectionNumber;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $collectionTitle;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $containerTitle;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $containerTitlePart;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $dimensions;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $DOI;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $edition;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $event;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $eventPlace;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $firstReferenceNoteNumber;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $genre;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $ISBN;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $ISSN;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $issue;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $jurisdiction;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $keyword;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $locator;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $medium;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $note;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $number;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $numberOfPages;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $numberOfVolumes;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $originalPublisher;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $originalPublisherPlace;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $originalTitle;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $page;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $pageFirst;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $PMCID;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $PMID;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $publisher;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $publisherPlace;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $references;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $reviewedTitle;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $scale;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $section;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $source;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $status;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $title;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $titleShort;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $URL;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $version;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $volume;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $yearSuffix;
 
@@ -435,15 +435,21 @@ class Reference
      */
 
     /**
-     * @var string
+     * @var string|null
      */
     public $ECLI;
 
     /**
-     * @var string
+     * @var string|null
      */
     public $comments;
 
+    public function __construct()
+    {
+        $this->type = 'legal_case';
+        $this->issued = new \DateTime('now');
+    }
+
     public static function getTypeChoices()
     {
         return [

+ 57 - 5
src/AppBundle/Entity/ReferenceManger.php

@@ -10,6 +10,7 @@ namespace AppBundle\Entity;
 
 
 use AppBundle\Serializer\DateDenormalizer;
+use Doctrine\Common\Collections\ArrayCollection;
 use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
 use Symfony\Component\Serializer\Encoder\YamlEncoder;
 use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
@@ -30,7 +31,7 @@ class ReferenceManger
     protected $storageFilename;
 
     /**
-     * @var References
+     * @var Reference[]
      */
     protected $references;
 
@@ -45,8 +46,9 @@ class ReferenceManger
             new YamlEncoder(
                 null,
                 null,
-                ['yaml_flags'  => Yaml::PARSE_OBJECT_FOR_MAP,
-                 'yaml_inline' => 2,
+                [
+                    //'yaml_flags'  => Yaml::PARSE_OBJECT_FOR_MAP,
+                    'yaml_inline' => 2,
                 ]
             ),
         ];
@@ -62,16 +64,66 @@ class ReferenceManger
     {
         $references = $this->getReferences();
 
-        return $references->references;
+        return $references;
     }
 
+    public function find($id)
+    {
+        $references = $this->getReferences();
+
+        foreach ($references as $reference) {
+            if ($reference->id === $id) {
+                return $reference;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @return Reference[]
+     */
     public function getReferences()
     {
         if ($this->references === null) {
             $data = file_get_contents($this->storageFilename);
+            /** @var References $references */
             $this->references = $this->serializer->deserialize($data, 'AppBundle\\Entity\\References', 'yaml');
         }
 
-        return $this->references;
+        return $this->references->getReferences();
+    }
+
+    public function persist(Reference $reference)
+    {
+        /** @var ArrayCollection $references */
+        $references = $this->getReferences();
+        // Has object are always passed by reference
+        if ($references->contains($reference)) {
+            return true;
+        }
+
+        return $references->add($reference);
+    }
+
+    public function remove(Reference $reference)
+    {
+        /** @var ArrayCollection $references */
+        $references = $this->getReferences();
+
+        return $references->removeElement($reference);
+    }
+
+    public function flush()
+    {
+        if ($this->references !== null) {
+            $out = $this->serializer->serialize($this->references, 'yaml');
+            file_put_contents($this->storageFilename, $out);
+        }
+    }
+
+    public function clear()
+    {
+        $this->references = null;
     }
 }

+ 18 - 1
src/AppBundle/Entity/References.php

@@ -9,10 +9,27 @@
 namespace AppBundle\Entity;
 
 
+use Doctrine\Common\Collections\ArrayCollection;
+
 class References
 {
     /**
+     * This is a hack for serialization, because references are stored into elements attribute
      * @var Reference[]
      */
-    public $references;
+    private $references;
+
+    /**
+     * @return ArrayCollection
+     */
+    public function getReferences()
+    {
+        return $this->references;
+    }
+
+
+    public function setReferences($collection)
+    {
+        $this->references = new ArrayCollection($collection);
+    }
 }

+ 1 - 2
src/AppBundle/Form/ReferenceType.php

@@ -27,7 +27,7 @@ class ReferenceType extends AbstractType
     public function buildForm(FormBuilderInterface $builder, array $options)
     {
         $builder
-            ->add('type', ChoiceType::class, ['choices' => $this->getTypeChoices(), 'data' => 'legal_case'])
+            ->add('type', ChoiceType::class, ['choices' => $this->getTypeChoices()])
             ->add('id')
             ->add('authority')
             ->add('section')
@@ -38,7 +38,6 @@ class ReferenceType extends AbstractType
             ->add('ECLI', null, ['label' => 'ECLI'])
             ->add('URL', UrlType::class, ['label' => 'URL', 'required' => false])
             ->add('comments')
-            ->add('Envoyer', SubmitType::class)
         ;
     }
 

+ 4 - 357
web/assets/css/main.css

@@ -5815,359 +5815,6 @@ button.close {
     display: none !important; } }
 
 table.dataTable {
-  width: 100%;
-  margin: 0 auto;
-  clear: both;
-  border-collapse: separate;
-  border-spacing: 0; }
-
-table.dataTable thead th, table.dataTable tfoot th {
-  font-weight: bold; }
-
-table.dataTable thead th, table.dataTable thead td {
-  padding: 10px 18px;
-  border-bottom: 1px solid #111; }
-
-table.dataTable thead th:active, table.dataTable thead td:active {
-  outline: none; }
-
-table.dataTable tfoot th, table.dataTable tfoot td {
-  padding: 10px 18px 6px 18px;
-  border-top: 1px solid #111; }
-
-table.dataTable thead .sorting, table.dataTable thead .sorting_asc, table.dataTable thead .sorting_desc, table.dataTable thead .sorting_asc_disabled, table.dataTable thead .sorting_desc_disabled {
-  cursor: pointer;
-  *cursor: hand; }
-
-table.dataTable thead .sorting, table.dataTable thead .sorting_asc, table.dataTable thead .sorting_desc, table.dataTable thead .sorting_asc_disabled, table.dataTable thead .sorting_desc_disabled {
-  background-repeat: no-repeat;
-  background-position: center right; }
-
-table.dataTable thead .sorting {
-  background-image: url("../images/sort_both.png"); }
-
-table.dataTable thead .sorting_asc {
-  background-image: url("../images/sort_asc.png"); }
-
-table.dataTable thead .sorting_desc {
-  background-image: url("../images/sort_desc.png"); }
-
-table.dataTable thead .sorting_asc_disabled {
-  background-image: url("../images/sort_asc_disabled.png"); }
-
-table.dataTable thead .sorting_desc_disabled {
-  background-image: url("../images/sort_desc_disabled.png"); }
-
-table.dataTable tbody tr {
-  background-color: #ffffff; }
-
-table.dataTable tbody tr.selected {
-  background-color: #B0BED9; }
-
-table.dataTable tbody th, table.dataTable tbody td {
-  padding: 8px 10px; }
-
-table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
-  border-top: 1px solid #ddd; }
-
-table.dataTable.row-border tbody tr:first-child th, table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th, table.dataTable.display tbody tr:first-child td {
-  border-top: none; }
-
-table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
-  border-top: 1px solid #ddd;
-  border-right: 1px solid #ddd; }
-
-table.dataTable.cell-border tbody tr th:first-child, table.dataTable.cell-border tbody tr td:first-child {
-  border-left: 1px solid #ddd; }
-
-table.dataTable.cell-border tbody tr:first-child th, table.dataTable.cell-border tbody tr:first-child td {
-  border-top: none; }
-
-table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
-  background-color: #f9f9f9; }
-
-table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
-  background-color: #acbad4; }
-
-table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {
-  background-color: #f6f6f6; }
-
-table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {
-  background-color: #aab7d1; }
-
-table.dataTable.order-column tbody tr > .sorting_1, table.dataTable.order-column tbody tr > .sorting_2, table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1, table.dataTable.display tbody tr > .sorting_2, table.dataTable.display tbody tr > .sorting_3 {
-  background-color: #fafafa; }
-
-table.dataTable.order-column tbody tr.selected > .sorting_1, table.dataTable.order-column tbody tr.selected > .sorting_2, table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1, table.dataTable.display tbody tr.selected > .sorting_2, table.dataTable.display tbody tr.selected > .sorting_3 {
-  background-color: #acbad5; }
-
-table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
-  background-color: #f1f1f1; }
-
-table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
-  background-color: #f3f3f3; }
-
-table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
-  background-color: whitesmoke; }
-
-table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
-  background-color: #a6b4cd; }
-
-table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
-  background-color: #a8b5cf; }
-
-table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
-  background-color: #a9b7d1; }
-
-table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
-  background-color: #fafafa; }
-
-table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
-  background-color: #fcfcfc; }
-
-table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
-  background-color: #fefefe; }
-
-table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
-  background-color: #acbad5; }
-
-table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
-  background-color: #aebcd6; }
-
-table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
-  background-color: #afbdd8; }
-
-table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {
-  background-color: #eaeaea; }
-
-table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {
-  background-color: #ececec; }
-
-table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {
-  background-color: #efefef; }
-
-table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {
-  background-color: #a2aec7; }
-
-table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {
-  background-color: #a3b0c9; }
-
-table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {
-  background-color: #a5b2cb; }
-
-table.dataTable.no-footer {
-  border-bottom: 1px solid #111; }
-
-table.dataTable.nowrap th, table.dataTable.nowrap td {
-  white-space: nowrap; }
-
-table.dataTable.compact thead th, table.dataTable.compact thead td {
-  padding: 4px 17px 4px 4px; }
-
-table.dataTable.compact tfoot th, table.dataTable.compact tfoot td {
-  padding: 4px; }
-
-table.dataTable.compact tbody th, table.dataTable.compact tbody td {
-  padding: 4px; }
-
-table.dataTable th.dt-left, table.dataTable td.dt-left {
-  text-align: left; }
-
-table.dataTable th.dt-center, table.dataTable td.dt-center, table.dataTable td.dataTables_empty {
-  text-align: center; }
-
-table.dataTable th.dt-right, table.dataTable td.dt-right {
-  text-align: right; }
-
-table.dataTable th.dt-justify, table.dataTable td.dt-justify {
-  text-align: justify; }
-
-table.dataTable th.dt-nowrap, table.dataTable td.dt-nowrap {
-  white-space: nowrap; }
-
-table.dataTable thead th.dt-head-left, table.dataTable thead td.dt-head-left, table.dataTable tfoot th.dt-head-left, table.dataTable tfoot td.dt-head-left {
-  text-align: left; }
-
-table.dataTable thead th.dt-head-center, table.dataTable thead td.dt-head-center, table.dataTable tfoot th.dt-head-center, table.dataTable tfoot td.dt-head-center {
-  text-align: center; }
-
-table.dataTable thead th.dt-head-right, table.dataTable thead td.dt-head-right, table.dataTable tfoot th.dt-head-right, table.dataTable tfoot td.dt-head-right {
-  text-align: right; }
-
-table.dataTable thead th.dt-head-justify, table.dataTable thead td.dt-head-justify, table.dataTable tfoot th.dt-head-justify, table.dataTable tfoot td.dt-head-justify {
-  text-align: justify; }
-
-table.dataTable thead th.dt-head-nowrap, table.dataTable thead td.dt-head-nowrap, table.dataTable tfoot th.dt-head-nowrap, table.dataTable tfoot td.dt-head-nowrap {
-  white-space: nowrap; }
-
-table.dataTable tbody th.dt-body-left, table.dataTable tbody td.dt-body-left {
-  text-align: left; }
-
-table.dataTable tbody th.dt-body-center, table.dataTable tbody td.dt-body-center {
-  text-align: center; }
-
-table.dataTable tbody th.dt-body-right, table.dataTable tbody td.dt-body-right {
-  text-align: right; }
-
-table.dataTable tbody th.dt-body-justify, table.dataTable tbody td.dt-body-justify {
-  text-align: justify; }
-
-table.dataTable tbody th.dt-body-nowrap, table.dataTable tbody td.dt-body-nowrap {
-  white-space: nowrap; }
-
-table.dataTable, table.dataTable th, table.dataTable td {
-  -webkit-box-sizing: content-box;
-  box-sizing: content-box; }
-
-.dataTables_wrapper {
-  position: relative;
-  clear: both;
-  *zoom: 1;
-  zoom: 1; }
-
-.dataTables_wrapper .dataTables_length {
-  float: left; }
-
-.dataTables_wrapper .dataTables_filter {
-  float: right;
-  text-align: right; }
-
-.dataTables_wrapper .dataTables_filter input {
-  margin-left: 0.5em; }
-
-.dataTables_wrapper .dataTables_info {
-  clear: both;
-  float: left;
-  padding-top: 0.755em; }
-
-.dataTables_wrapper .dataTables_paginate {
-  float: right;
-  text-align: right;
-  padding-top: 0.25em; }
-
-.dataTables_wrapper .dataTables_paginate .paginate_button {
-  box-sizing: border-box;
-  display: inline-block;
-  min-width: 1.5em;
-  padding: 0.5em 1em;
-  margin-left: 2px;
-  text-align: center;
-  text-decoration: none !important;
-  cursor: pointer;
-  *cursor: hand;
-  color: #333 !important;
-  border: 1px solid transparent;
-  border-radius: 2px; }
-
-.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
-  color: #333 !important;
-  border: 1px solid #979797;
-  background-color: white;
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));
-  background: -webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);
-  background: -moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);
-  background: -ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);
-  background: -o-linear-gradient(top, #fff 0%, #dcdcdc 100%);
-  background: linear-gradient(to bottom, #fff 0%, #dcdcdc 100%); }
-
-.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
-  cursor: default;
-  color: #666 !important;
-  border: 1px solid transparent;
-  background: transparent;
-  box-shadow: none; }
-
-.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
-  color: white !important;
-  border: 1px solid #111;
-  background-color: #585858;
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));
-  background: -webkit-linear-gradient(top, #585858 0%, #111 100%);
-  background: -moz-linear-gradient(top, #585858 0%, #111 100%);
-  background: -ms-linear-gradient(top, #585858 0%, #111 100%);
-  background: -o-linear-gradient(top, #585858 0%, #111 100%);
-  background: linear-gradient(to bottom, #585858 0%, #111 100%); }
-
-.dataTables_wrapper .dataTables_paginate .paginate_button:active {
-  outline: none;
-  background-color: #2b2b2b;
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));
-  background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
-  background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
-  background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
-  background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
-  background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);
-  box-shadow: inset 0 0 3px #111; }
-
-.dataTables_wrapper .dataTables_paginate .ellipsis {
-  padding: 0 1em; }
-
-.dataTables_wrapper .dataTables_processing {
-  position: absolute;
-  top: 50%;
-  left: 50%;
-  width: 100%;
-  height: 40px;
-  margin-left: -50%;
-  margin-top: -25px;
-  padding-top: 20px;
-  text-align: center;
-  font-size: 1.2em;
-  background-color: white;
-  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
-  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
-  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
-  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
-  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
-  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); }
-
-.dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, .dataTables_wrapper .dataTables_paginate {
-  color: #333; }
-
-.dataTables_wrapper .dataTables_scroll {
-  clear: both; }
-
-.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {
-  *margin-top: -1px;
-  -webkit-overflow-scrolling: touch; }
-
-.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td {
-  vertical-align: middle; }
-
-.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td > div.dataTables_sizing {
-  height: 0;
-  overflow: hidden;
-  margin: 0 !important;
-  padding: 0 !important; }
-
-.dataTables_wrapper.no-footer .dataTables_scrollBody {
-  border-bottom: 1px solid #111; }
-
-.dataTables_wrapper.no-footer div.dataTables_scrollHead > table, .dataTables_wrapper.no-footer div.dataTables_scrollBody > table {
-  border-bottom: none; }
-
-.dataTables_wrapper:after {
-  visibility: hidden;
-  display: block;
-  content: "";
-  clear: both;
-  height: 0; }
-
-@media screen and (max-width: 767px) {
-  .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_paginate {
-    float: none;
-    text-align: center; }
-  .dataTables_wrapper .dataTables_paginate {
-    margin-top: 0.5em; } }
-
-@media screen and (max-width: 640px) {
-  .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter {
-    float: none;
-    text-align: center; }
-  .dataTables_wrapper .dataTables_filter {
-    margin-top: 0.5em; } }
-
-table.dataTable {
   clear: both;
   margin-top: 6px !important;
   margin-bottom: 6px !important;
@@ -6263,18 +5910,18 @@ table.dataTable thead .sorting_asc_disabled:after, table.dataTable thead .sortin
 div.dataTables_scrollHead table.dataTable {
   margin-bottom: 0 !important; }
 
-div.dataTables_scrollBody > table {
+div.dataTables_scrollBody table {
   border-top: none;
   margin-top: 0 !important;
   margin-bottom: 0 !important; }
 
-div.dataTables_scrollBody > table > thead .sorting:after, div.dataTables_scrollBody > table > thead .sorting_asc:after, div.dataTables_scrollBody > table > thead .sorting_desc:after {
+div.dataTables_scrollBody table thead .sorting:after, div.dataTables_scrollBody table thead .sorting_asc:after, div.dataTables_scrollBody table thead .sorting_desc:after {
   display: none; }
 
-div.dataTables_scrollBody > table > tbody > tr:first-child > th, div.dataTables_scrollBody > table > tbody > tr:first-child > td {
+div.dataTables_scrollBody table tbody tr:first-child th, div.dataTables_scrollBody table tbody tr:first-child td {
   border-top: none; }
 
-div.dataTables_scrollFoot > table {
+div.dataTables_scrollFoot table {
   margin-top: 0 !important;
   border-top: none; }
 

File diff suppressed because it is too large
+ 306 - 15301
web/assets/js/main.js