UNPKG

mongo-express-enhanced

Version:
577 lines (526 loc) 22.6 kB
{% extends 'layout.html' %} {% block title %}{{ collectionName }}{% endblock %} {% block styles %} <link href="{{ baseHref }}public/css/codemirror.css" rel="stylesheet"> {% if editorTheme != "default" %} <link href="{{ baseHref }}public/css/theme/{{ editorTheme }}.css" rel="stylesheet"> {% endif %} <style type="text/css"> .modal-body .CodeMirror .CodeMirror-scroll { height: 100%; } .tab-pane > form { padding-bottom: 5px; } .sorting-button { white-space: nowrap; } @media (min-width: 992px) { /* meduim and up */ #advanced .form-group .btn { height: 150px; } } #indexes td { vertical-align: middle; } </style> {% endblock %} {% block breadcrumb %} <li> <a href="{{ dbUrl }}">Database:</a> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ dbName }}<span class="caret"></span></a> <ul class="dropdown-menu"> {% for db in databases %} <li><a href="{{ baseHref }}db/{{ db }}/">{{ db | url_encode }}</a></li> {% endfor %} </ul> </li> <li> <a href="{{ dbUrl }}"><span class="glyphicon glyphicon-chevron-right"></span></a> </li> <li> <a href="{{ collectionUrl }}">Collection:</a> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ collectionName }}<span class="caret"></span></a> <ul class="dropdown-menu"> {% for collection in collections %} <li><a href="{{ dbUrl }}/{{ collection | url_encode }}">{{ collection }}</a></li> {% endfor %} </ul> </li> {% endblock %} {% block content %} {% if !settings.read_only %} <p> <button type="button" data-toggle="modal" data-target="#addDocument" class="btn btn-success btn-large"> <span class="glyphicon glyphicon-pencil"></span> New Document </button> <button type="button" data-toggle="modal" data-target="#addIndex" class="btn btn-success btn-large"> <span class="glyphicon glyphicon-pencil"></span> New Index </button> </p> {% endif %} <ul id="tabs" class="nav nav-pills nav-justified" data-tabs="tabs"> <li class="active"><a href="#simple" data-toggle="tab"><span class="glyphicon glyphicon-tag"></span> Simple</a></li> <li><a href="#advanced" data-toggle="tab"><span class="glyphicon glyphicon-tags"></span> Advanced</a></li> </ul> <div id="my-tab-content" class="tab-content"> <div class="tab-pane active" id="simple"> <form class="well" method="get" action="{{ collectionUrl }}"> {% for column in columns %} <input type="checkbox" name="sort[{{column}}]" class="hide sort-{{column}}" {% if sort[column] %}value="{{sort[column]}}" checked="checked"{% endif %}/> {% endfor %} <div class="row"> <div class="form-group col-sm-6 col-md-4"> <input style="width:100%;" class="input-medium form-control" type="text" id="key" name="key" placeholder="Key" title="Key" value="{{ key }}"> </div> <div class="form-group col-sm-6 col-md-4"> <input style="width:100%;" class="input-medium form-control" type="text" id="value" name="value" placeholder="Value" title="Value" value="{{ value }}"> </div> <div class="form-group col-sm-6 col-md-2"> <select name="type" class="form-control"> <option value="S" {% if type == 'S' %}selected {% endif %}>String</option> <option value="R" {% if type == 'R' %}selected {% endif %}>Regex</option> <option value="J" {% if type == 'J' %}selected {% endif %}>JSON, bool</option> <option value="N" {% if type == 'N' %}selected {% endif %}>Number</option> <option value="O" {% if type == 'O' %}selected {% endif %}>ObjectID</option> </select> </div> <div class="form-group col-sm-6 col-md-2"> <button type="submit" class="btn btn-primary btn-block"> <span class="glyphicon glyphicon-search"></span> Find </button> </div> </div> </form> </div> <div class="tab-pane" id="advanced"> <form class="well" method="get" action="{{ collectionUrl }}"> {% for column in columns %} <input type="checkbox" name="sort[{{column}}]" class="hide sort-{{column}}" {% if sort[column] %}value="{{sort[column]}}" checked="checked"{% endif %}/> {% endfor %} <div class="row"> <div class="form-group col-sm-6 col-md-5"> <textarea class="input-medium form-control" style="width: 100%; height: 150px" id="query" name="query" placeholder="Query" title="Query">{{ query }}</textarea> </div> <div class="form-group col-sm-6 col-md-5"> <textarea class="input-medium form-control" style="width: 100%; height: 150px" id="projection" name="projection" placeholder="Projection" title="Projection">{{ projection }}</textarea> </div> <div class="form-group col-md-2"> <button style="height:150px;" type="submit" class="btn btn-primary btn-block"> <span class="glyphicon glyphicon-search"></span> Find </button> </div> </div> </form> </div> </div> {% if !settings.read_only && !settings.no_delete && count > 0 %} <p> <form id="deleteListForm" method="POST" style="display:inline;" action="{{ collectionUrl }}?key={{ key }}&value={{ value }}&type={{ type }}&query={{ query|default('{}') }}&projection={{ projection }}"> {# Router is smart enough to transform method=POST + _method=delete into actual HTTP DELETE, which is what we want #} <input type="hidden" name="_method" value="delete"> <button type="button" data-toggle="modal" data-target="#deleteListModal" class="btn btn-danger btn-large btn-block"> <span class="glyphicon glyphicon-trash"></span> Delete all {{count}} documents retrieved </button> </form> </p> {% endif %} <br/> <!-- Add Document Modal --> <div class="modal fade" id="addDocument" role="dialog" tabindex="-1"> <div class="modal-dialog" role="document"> <div class="modal-content"> <form id="addDocumentForm" method="post" action="{{ collectionUrl }}"> <div class="modal-header"> <button class="close" data-dismiss="modal">×</button> <h2>Add Document</h2> </div> <div class="modal-body" id = "document-modal-body"> <textarea id="document" name="document">{ "_id": ObjectID() }</textarea> </div> <div class="modal-footer"> <button class="btn btn-error" data-dismiss="modal">Close</button> <button type="submit" class="btn btn-success" onclick="return checkValidJSON()"> <span class="glyphicon glyphicon-pencil"></span> Save </button> </div> </form> </div> </div> </div> <!-- End Add Document Modal --> <!-- Add Index Modal --> <div class="modal fade" id="addIndex" role="dialog" tabindex="-1"> <div class="modal-dialog" role="document"> <div class="modal-content"> <form id="addIndexForm" method="post" action="{{ dbUrl }}/addIndex/{{ collectionName | url_encode }}"> <div class="modal-header"> <button class="close" data-dismiss="modal">×</button> <h2>Add Indexes</h2> <span> A document that contains the field and value pairs where the field is the index key. 1 for an ascending and -1 for a descending index. </span> </div> <div class="modal-body" id = "index-modal-body"> <textarea id="index" name="index">{ "key": 1 }</textarea> </div> <div class="modal-footer"> <button class="btn btn-error" data-dismiss="modal">Close</button> <button type="submit" class="btn btn-success" onclick="return checkValidIndexJSON()"> <span class="glyphicon glyphicon-pencil"></span> Save </button> </div> </form> </div> </div> </div> <!-- End Add Index Modal --> {% if documents.length == 0 %} <p class="well"> No documents found. </p> {% else %} {% if pagination %} <ul class="pager span7"> <li class="previous{% if prev.skip < 0 %} disabled{% endif %}"> <a{% if prev.skip >= 0 %} href="{{ collectionUrl }}?skip=0&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}"{% endif %}>&larr; First</a> </li> <li{% if prev.skip < 0 %} class="disabled"{% endif %}> <a{% if prev.skip >= 0 %} href="{{ collectionUrl }}?skip={{ prev.skip }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}"{% endif %}>&larr; Prev</a> </li> <li{% if next.skip >= stats.count %} class="disabled"{% endif %}> <a{% if next.skip < stats.count %} href="{{ collectionUrl }}?skip={{ next.skip }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}"{% endif %}>Next &rarr;</a> </li> <li class="next{% if next.skip >= stats.count %} disabled{% endif %}"> <a{% if next.skip < stats.count %} href="{{ collectionUrl }}?skip={{ last }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}"{% endif %}>Last &rarr;</a> </li> </ul> {% endif %} <div class="fadeToWhite" id="fadeToWhiteID"></div> <div class="table-responsive tableWrapper"> <table class="table table-striped tableHeaderFooterBars"> <thead> {% for column in columns %} <th class="sorting-button" data-column="{{column}}" data-direction="{{sort[column]}}" title="Sort by {{column}}"> {{column}} {% if sort[column] == 1 %} <span class="glyphicon glyphicon-triangle-top"></span> {% elseif sort[column] == -1 %} <span class="glyphicon glyphicon-triangle-bottom"></span> {% endif %} </th> {% endfor %} </thead> {% for document in docs %} {% if document._id._bsontype == 'Binary' %} <tr onclick="loadDocument('{{ collectionUrl }}/{{ document._id | json | safe | url_encode }}?subtype={{ document._id.sub_type }}')"> {% else %} <tr onclick="loadDocument('{{ collectionUrl }}/{{ document._id | json | safe | url_encode }}')"> {% endif %} {% for column in columns %} <td><div class="tableContent"> {% if !settings.read_only && !settings.no_delete && column === '_id' && collectionName !== 'system.indexes' %} <form class="deleteButtonDocument" method="POST" style="display:inline;" action="{{ collectionUrl }}/{{ document._id | json | safe | url_encode }}?skip={{ skip }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection= {{ projection }}"> <input type="hidden" name="_method" value="delete"> <button type="submit" class="btn btn-danger"> <span class="glyphicon glyphicon-trash"></span> </button> </form> {% endif %} {{ document[column] | stringDocIDs | to_display | safe }} </div></td> {% endfor %} </tr> {% endfor %} </table> </div> {% if pagination %} <nav> <div class="text-center"> <ul class="pagination"> {%- if prev2.skip >= 0 %} <li><a href="{{ collectionUrl }}?skip={{ prev2.skip }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}">{{ prev2.page }}</a></li> {% else %} <li><a>&nbsp;</a></li> {%- endif %} {%- if prev.skip >= 0 %} <li><a href="{{ collectionUrl }}?skip={{ prev.skip }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}">{{ prev.page }}</a></li> {% else %} <li><a>&nbsp;</a></li> {%- endif %} <li class="active"><a href="{{ collectionUrl }}?skip={{ skip }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}">{{ here }}</a></li> {%- if next.skip < stats.count %} <li><a href="{{ collectionUrl }}?skip={{ next.skip }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}">{{ next.page }}</a></li> {% else %} <li><a>&nbsp;</a></li> {% endif %} {%- if next2.skip < stats.count %} <li><a href="{{ collectionUrl }}?skip={{ next2.skip }}&key={{ key }}&value={{ value }}&type={{ type }}&query={{ query }}&projection={{ projection }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}">{{ next2.page }}</a></li> {% else %} <li><a>&nbsp;</a></li> {% endif %} </ul> </div> </nav> {% endif %} {% endif %} <div class="row"> {% if !settings.read_only %} <div class="col-md-12"> <h2>Rename Collection</h2> <form method="POST" action="{{ collectionUrl }}" class="well form-inline"> <input type="hidden" name="_method" value="put"> <div class="form-group"> <span class="add-on">{{ dbName }} . </span> <input class="form-control" type="text" id="collection" name="collection" placeholder="{{ collectionName }}"> </div> <button type="submit" class="btn btn-primary"> <span class="glyphicon glyphicon-pencil"></span> Rename </button> </form> </div> {% endif %} </div> <h2>Tools</h2> <div class="row"> {% if !settings.me_no_export %} <div class="col-sm-4 {% if !settings.read_only %}col-lg-3{% endif %}"> <div class="well"> <a href="{{ dbUrl }}/export/{{ collectionName | url_encode }}?key={{ key }}&value={{ value }}&type={{ type }}&query={{ query | url_encode }}&projection= {{ projection | url_encode }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}" class="btn btn-warning btn-block"> <span class="glyphicon glyphicon-floppy-save"></span><br>Export Standard </a> </div> </div> <div class="col-sm-4"> <div class="well"> <a href="{{ dbUrl }}/expArr/{{ collectionName | url_encode }}?key={{ key }}&value={{ value }}&type={{ type }}&query={{ query | url_encode }}&projection= {{ projection | url_encode }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}" class="btn btn-warning btn-block"> <span class="glyphicon glyphicon-floppy-save"></span><br>Export --jsonArray </a> </div> </div> <div class="col-sm-4"> <div class="well"> <a href="{{ dbUrl }}/expCsv/{{ collectionName | url_encode }}?key={{ key }}&value={{ value }}&type={{ type }}&query={{ query | url_encode }}&projection= {{ projection | url_encode }}{% for k, v in sort %}&sort[{{ k }}]={{ v }}{% endfor %}" class="btn btn-warning btn-block"> <span class="glyphicon glyphicon-floppy-save"></span><br>Export --csv </a> </div> </div> {% endif %} <div class="col-sm-4"> <div class="well"> <a href="{{ dbUrl }}/reIndex/{{ collectionName | url_encode }}" class="btn btn-warning btn-block"> <span class="glyphicon glyphicon-resize-small"></span><br>Reindex </a> </div> </div> <div class="col-sm-4"> <div class="well"> <a class="btn btn-warning btn-block import-file-link"> <span class="glyphicon glyphicon-cloud-upload"></span><br>Import --mongoexport json </a> <input class="input-hidden import-input-file" type="file" name="import-file" collection-name="{{ collectionName | url_encode }}"/> </div> </div> {% if !settings.read_only %} <div class="col-sm-4"> <div class="well"> <a href="{{ dbUrl }}/compact/{{ collectionName | url_encode }}" class="btn btn-danger btn-block"> <span class="glyphicon glyphicon-resize-small"></span><br>Compact </a> </div> </div> {% if !settings.no_delete %} <div class="col-sm-4"> <form method="POST" action="{{ collectionUrl }}" class="well"> <form method="POST" action="{{ baseHref }}db/{{ dbName }}/{{ collectionName | url_encode }}" id="db-{{ dbName }}-{{ collectionName }}" class="well"> <input type="hidden" name="_method" value="delete"> <input type="submit" class="hidden" /> <button type="button" class="btn btn-danger deleteButtonCollection btn-block" collection-name="{{ collectionName }}"> <span class="glyphicon glyphicon-trash"></span><br>Delete </button> </form> </div> <div id="confirm-deletion-document" class="modal fade" role="dialog" aria-labelledby="confirmDeletionDocumentLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-body"> Are you sure? </div> <div class="modal-footer"> <button type="button" data-dismiss="modal" class="btn btn-danger" id="delete">Delete</button> <button type="button" data-dismiss="modal" class="btn">Cancel</button> </div> </div> </div> </div> <div id="deleteListModal" class="modal fade" role="dialog" aria-labelledby="confirmDeletionListLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-body"> Are you sure you want to delete all {{count}} documents? </div> <div class="modal-footer"> <button type="button" data-dismiss="modal" class="btn btn-danger" id="deleteListConfirmButton">Delete</button> <button type="button" data-dismiss="modal" class="btn">Cancel</button> </div> </div> </div> </div> <div id="confirm-deletion-collection" class="modal fade" role="dialog" aria-labelledby="confirmDeletionCollectionLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title" id="myModalLabel">Delete collection</h4> </div> <div class="modal-body"> <p> Be careful! You are about to delete whole <strong><span id="modal-collection-name"></span></strong> collection. </p> <p> <label for="confirmation-input">Type the collection name to proceed.</label> <input type="text" id="confirmation-input" name="confirmation-input" shouldbe="" value="" /> </p> </div> <div class="modal-footer"> <button type="button" data-dismiss="modal" class="btn btn-danger" id="delete">Delete</button> <button type="button" data-dismiss="modal" class="btn">Cancel</button> </div> </div> </div> </div> {% endif %} {% endif %} <div class="stats col-md-12"> <h2>Collection Stats</h2> <table class="table table-bordered table-striped"> <tr> <td> <strong>Documents</strong> </td> <td> {{ stats.count }} </td> </tr> <tr> <td> <strong>Total doc size</strong> </td> <td> {{ stats.size|convertBytes }} </td> </tr> <tr> <td> <strong>Average doc size</strong> </td> <td> {{ stats.avgObjSize|convertBytes }} </td> </tr> <tr> <td> <strong>Pre-allocated size</strong> </td> <td> {{ stats.storageSize|convertBytes }} </td> </tr> <tr> <td> <strong>Indexes</strong> </td> <td> {{ stats.nindexes }} </td> </tr> <tr> <td> <strong>Total index size</strong> </td> <td> {{ stats.totalIndexSize|convertBytes }} </td> </tr> <tr> <td> <strong>Padding factor</strong> </td> <td> {{ stats.paddingFactor }} </td> </tr> <tr> <td> <strong>Extents</strong> </td> <td> {{ stats.numExtents }} </td> </tr> </table> </div> <div class="col-md-12"> <h2>Indexes</h2> <table id="indexes" class="table table-bordered table-striped"> <tr> <th>Name</th> <th>Columns</th> <th>Size</th> <th>Attributes</th> <th>Actions</th> </tr> {% for index in indexes %} <tr> <td> {{ index.name }} </td> <td> {% for sort in index.key %} <div>{{ loop.key }} &nbsp; {% if sort == 1 %} ASC {% else %} DSC {% endif %}</div> {% endfor %} </td> <td> {{ index.size|convertBytes }} </td> <td> {% for k,v in index %} <div>{% if k != 'key' && k != 'v' && k != 'name' && k != 'ns' && k != 'size'%} {{ k }}: &nbsp;{{ v }} {% endif %}</div> {% endfor %} </td> {% if !settings.read_only && !settings.no_delete %} <td> <a class="btn btn-danger" href="{{ dbUrl }}/dropIndex/{{ collectionName | url_encode }}?name={{ index.name }}"> <span class="glyphicon glyphicon-trash"></span> &nbsp;DEL </a> </td> {% else %} <td> </td> {% endif %} </tr> {% endfor %} </table> </div> {% endblock %} {% block scripts %} <script src="{{ baseHref }}{{assets.codemirror.js}}"></script> <script src="{{ baseHref }}{{assets.collection.js}}"></script> {% endblock %}