Sharing tables readonly with other users
- Added sharing feature for table owners to share their tables with other registered users. - Fixed a bug where the wrong entries would be deleted or modified when searching or filtering.
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5">New table</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="$('#form_create_table).trigger('reset');"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="form_create_table" method="post" action="/table/create">
|
||||
@@ -77,7 +77,7 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5">Import new table</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="$('#form_import_table').trigger('reset');"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="/table/import" method="post" id="form_import_table">
|
||||
|
||||
@@ -64,5 +64,51 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
{% if sharednms |length > 1 %}
|
||||
<div class="accordion" id="shared_tables">
|
||||
{% for tname in sharednms %}
|
||||
{% set clms = sharedcols[loop.index0] %}
|
||||
{% set rws = sharedrows[loop.index0] %}
|
||||
{% set tid = sharedtblids[loop.index0] %}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#acc_shared_{{ tid }}" aria-expanded="false" aria-controls="acc_shared_{{ tid }}">
|
||||
{{ tname }}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="acc_shared_{{ tid }}" class="accordion-collapse collapse" data-bs-parent="#shared_tables">
|
||||
<div class="accordion-body">
|
||||
<div class="row justify-content-between">
|
||||
<div class="col-auto"><h3>{{ tname }}</h3></div><div class="col-auto"><a class="btn btn-primary" href="/table/{{ tid }}">Open</a></div>
|
||||
</div>
|
||||
<!-- Preview -->
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
{% for clm in clms %}
|
||||
<th>{{ clm }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in rws %}
|
||||
<tr>
|
||||
<td>{{ loop.index }}</td>
|
||||
{% for clm in clms %}
|
||||
<td>{{ row[loop.index0] }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock body %}
|
||||
|
||||
|
||||
@@ -25,25 +25,30 @@
|
||||
|
||||
<!-- Table header and editing -->
|
||||
<div class="row justify-content-between">
|
||||
<div class="col-auto">
|
||||
<div class="col-2 me-0 pe-0 pt-0 mt-0">
|
||||
<h1>
|
||||
<div class='input-group'>
|
||||
<span id="tname">{{ tblname }}</span>
|
||||
<button class="btn" type="button" onclick="toggle_edit_tname();" id="pencil_button_edit_tname">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class='input-group mt-0'>
|
||||
<span id="tname">{{ tblname }}</span>
|
||||
{% block edit_tname %}
|
||||
{% endblock edit_tname %}
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="col-1 align-self-start align-content-start ms-0 ps-0 mt-0 pt-0">
|
||||
{% block share %}
|
||||
{% endblock share %}
|
||||
</div>
|
||||
|
||||
<div class="col-6">
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Search bar -->
|
||||
<div class="col-auto">
|
||||
<div class="btn-toolbar mt-2" role="toolbar">
|
||||
<div class="btn-group me-2">
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#create_entry_modal">
|
||||
<i class="bi bi-plus-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-3 align-self-end align-content-end pt-0 mt-0">
|
||||
<div class="btn-toolbar mt-0 pt-0" role="toolbar">
|
||||
{% block new_entry %}
|
||||
{% endblock new_entry %}
|
||||
<form method="get" action="/table/{{ tblid }}">
|
||||
<div class="input-group">
|
||||
<div class="input-group-text dropdown-toggle" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
@@ -81,7 +86,8 @@
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="btn-toolbar">
|
||||
<button class="btn" data-bs-toggle="modal" data-bs-target="#create_column_modal" type="button"><i class="bi bi-bookmark-plus"></i></button>
|
||||
{% block new_column %}
|
||||
{% endblock new_column %}
|
||||
<form method="get" action="/table/{{ tblid }}">
|
||||
<input value="0" name="sort_field" hidden />
|
||||
<input value="{% if sort_field == 0 %}{{ (sort_dir + 1) % 2}}{% else %}0{% endif %}" name="sort_dir" hidden />
|
||||
@@ -105,7 +111,7 @@
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="btn-toolbar">
|
||||
<button class="btn p-0 me-2" type="button" data-bs-toggle="modal" data-bs-target="#edit_column_modal" onclick="edit_column({{ loop.index0 }});"><i class="bi bi-pencil"></i></button>
|
||||
<button class="btn p-0 me-2 edit_column_btn" type="button" data-bs-toggle="modal" data-bs-target="#edit_column_modal" onclick="edit_column({{ loop.index0 }});" hidden><i class="bi bi-pencil"></i></button>
|
||||
<form method="GET" action="/table/{{ tblid }}">
|
||||
<input value="{{ loop.index }}" name="sort_field" hidden />
|
||||
<input value="{% if sort_field == loop.index %}{{ (sort_dir + 1) % 2}}{% else %}0{% endif %}" name="sort_dir" hidden />
|
||||
@@ -136,20 +142,5 @@
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock body %}
|
||||
{% block modals %}
|
||||
<!-- Table specific modals -->
|
||||
{% include "table_modals" %}
|
||||
{% endblock modals %}
|
||||
|
||||
{% block script %}
|
||||
<!-- table specific values -->
|
||||
<script type="text/javascript">
|
||||
const column_names = [{% for col in column_names %} '{{ col }}', {% endfor %}];
|
||||
const column_types = [{% for col in column_types %} {{ col }}, {% endfor %}];
|
||||
const tblid = {{ tblid }};
|
||||
const tblname = '{{ tblname }}';
|
||||
</script>
|
||||
<!-- Table specific functionality -->
|
||||
<script type="text/javascript" src="/js/table.js"></script>
|
||||
{% endblock script %}
|
||||
|
||||
|
||||
25
templates/table_owned.html.tera
Normal file
25
templates/table_owned.html.tera
Normal file
@@ -0,0 +1,25 @@
|
||||
{% extends "table_write" %}
|
||||
|
||||
{% block edit_tname %}
|
||||
<button class="btn" type="button" onclick="toggle_edit_tname();" id="pencil_button_edit_tname">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
{% endblock edit_tname %}
|
||||
|
||||
{% block share %}
|
||||
<div class="button-group mt-0">
|
||||
<button class="btn btn-outline-dark mt-0" data-bs-toggle="modal" data-bs-target="#share_table_modal"><i class="bi bi-send-arrow-up"></i></button>
|
||||
</div>
|
||||
{% endblock share %}
|
||||
|
||||
{% block more_modals %}
|
||||
{{ super() }}
|
||||
<!-- Table owned specific modals -->
|
||||
{% include "table_owned_modals" %}
|
||||
{% endblock more_modals %}
|
||||
|
||||
{% block script %}
|
||||
<!-- Table owned specific functionality -->
|
||||
<script type="text/javascript" src="/js/table_owned.js"></script>
|
||||
{% endblock script %}
|
||||
|
||||
65
templates/table_owned_modals.html.tera
Normal file
65
templates/table_owned_modals.html.tera
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
{% block modal_share_table %}
|
||||
<!-- Share table -->
|
||||
<div class="modal fade" id="share_table_modal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5">
|
||||
Share table
|
||||
</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="$( '#form_share_table' ).trigger('reset');"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="/table/share" method="post" id="form_share_table" onreset="$('.2benabled').prop('disabled', false);">
|
||||
<input name="tblid" value="{{ tblid }}" hidden>
|
||||
{% for user in shared %}
|
||||
<div class="row py-1">
|
||||
<div class="col-auto">
|
||||
<input value="{{ user.username }}" readonly id="form_share_table_user_{{ user.id }}" class="form-control 2benabled" />
|
||||
<input value="{{ user.id }}" name="sharees" hidden />
|
||||
</div>
|
||||
<div class="col-auto form-check form-check-inline pt-2">
|
||||
<label for="form_share_table_ro_{{ user.id }}" class="form-check-label"> Read only </label>
|
||||
<input id="form_share_table_ro_{{ user.id }}" type="checkbox" class="form-check-input 2benabled" {% if user.readonly %}checked{% endif %} onchange="$('#form_share_table_action_ro_{{ user.id }}').val($(this).is(':checked'));" />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<input id="form_share_table_action_ro_{{ user.id }}" name="readonly" value="{{ user.readonly }}" hidden>
|
||||
<input id="form_share_table_action_del_{{ user.id }}" name="delete" value="false" hidden>
|
||||
<button id="form_share_table_delete_button_{{ user.id }}" class="btn btn-outline-danger 2benabled" type="button" onclick="$('#form_share_table_action_del_{{ user.id }}').val(true); $('#form_share_table_ro_{{ user.id }}').prop('disabled', true); $('#form_share_table_user_{{ user.id }}').prop('disabled', true); $('#form_share_table_delete_button_{{ user.id }}').prop('disabled', true);"><i class="bi bi-trash3"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="row py-1">
|
||||
<div class="col-auto">
|
||||
<input id="form_share_table_new_user_input" placeholder="User" class="form-control" onchange="query_users($(this).val());" autofocus autocomplete="off" />
|
||||
<input id="form_share_table_new_user_id" name="new_user" hidden>
|
||||
<div class="card text-bg-light mt-2">
|
||||
<ul class="list-group list-group-flush" id="form_share_table_select_new_user">
|
||||
<!-- users to select from -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto form-check form-check-inline pt-2">
|
||||
<label for="form_share_table_new_ro">Read-only</label>
|
||||
<input name="readonly" type="checkbox" class="form-check-input" checked />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="row justify-content-betwen">
|
||||
<div class="col-auto">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" onclick="$('#form_share_table').trigger('reset');"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" onclick="$('#form_share_table').trigger('submit').trigger('reset');"><i class="bi bi-check-lg"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock modal_share_table %}
|
||||
1
templates/table_readonly.html.tera
Normal file
1
templates/table_readonly.html.tera
Normal file
@@ -0,0 +1 @@
|
||||
{% extends "table" %}
|
||||
38
templates/table_write.html.tera
Normal file
38
templates/table_write.html.tera
Normal file
@@ -0,0 +1,38 @@
|
||||
{% extends "table" %}
|
||||
|
||||
{% block new_entry %}
|
||||
<div class="btn-group me-2 mt-0">
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#create_entry_modal">
|
||||
<i class="bi bi-plus-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
{% endblock new_entry %}
|
||||
|
||||
{% block new_column %}
|
||||
<button class="btn" data-bs-toggle="modal" data-bs-target="#create_column_modal" type="button"><i class="bi bi-bookmark-plus"></i></button>
|
||||
{% endblock new_column %}
|
||||
|
||||
|
||||
{% block edit_column %}
|
||||
|
||||
{% endblock edit_column %}
|
||||
|
||||
|
||||
{% block modals %}
|
||||
<!-- Table write specific modals -->
|
||||
{% include "table_write_modals" %}
|
||||
{% endblock modals %}
|
||||
|
||||
{% block script %}
|
||||
<!-- table specific values -->
|
||||
<script type="text/javascript">
|
||||
const column_names = [{% for col in column_names %} '{{ col }}', {% endfor %}];
|
||||
const column_types = [{% for col in column_types %} {{ col }}, {% endfor %}];
|
||||
const tblid = {{ tblid }};
|
||||
const tblname = '{{ tblname }}';
|
||||
</script>
|
||||
<!-- Table write specific functionality -->
|
||||
<script type="text/javascript" src="/js/table_write.js"></script>
|
||||
{% endblock script %}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5">Add entry</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.getElementById('form_create_entry').reset();"></button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="$('#form_create_entry').trigger('reset');"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h5>Cell values:</h5>
|
||||
@@ -49,8 +49,8 @@
|
||||
<div class="col-auto">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_create_entry').reset();"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" type="button" onclick="document.getElementById('form_create_entry').submit().reset();"><i class="bi bi-check-lg"></i></button>
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="$('#form_create_entry').trigger('reset');"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" type="button" onclick="$('#form_create_entry').trigger('submit').trigger('reset');"><i class="bi bi-check-lg"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -66,7 +66,7 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5"><div class="row"><div class="col-auto">Row <span id="modal_caller"></span></div><div class="col-auto"><i class="bi bi-pencil-fill"></i></div></div></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.getElementById('form_edit_entry').reset();"></button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="$('#form_edit_entry').trigger('reset');"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="/row/edit" method="post" id="form_edit_entry">
|
||||
@@ -96,8 +96,8 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_edit_entry').reset();"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" type="button" onclick="submit_and_reset('form_edit_entry');" class="bi bi-check-lg"></i></button>
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="$('#form_edit_entry').trigger('reset');"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" type="button" onclick="$('#form_edit_entry').trigger('submit').trigger('reset');"><i class="bi bi-check-lg"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,7 +108,7 @@
|
||||
|
||||
{% block modal_new_column %}
|
||||
<!-- Add column -->
|
||||
<div class="modal fade" id="create_column_modal" tabindex="-1" aria-hidden="true" onclick="document.getElementById('form_create_column').reset();">
|
||||
<div class="modal fade" id="create_column_modal" tabindex="-1" aria-hidden="true" onclick="$('#form_create_column').trigger('reset');">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@@ -137,8 +137,8 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_create_column').reset();"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" type="button" onclick="submit_and_reset('form_create_column');"><i class="bi bi-check-lg"></i></button>
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="$'#form_create_column').trigger('reset');"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" type="button" onclick="$('#form_create_column').trigger('submit').trigger('reset');"><i class="bi bi-check-lg"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,7 +153,7 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5"><div class="row"><div class="col-auto"><span id="modal_caller"></span></div><div class="col-auto"><i class="bi bi-pencil-fill"></i></div></div></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="$('#form_edit_column').trigger('reset');"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="/column/edit" method="post" id="form_edit_column">
|
||||
@@ -186,8 +186,8 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="document.getElementById('form_edit_column').reset();"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" type="button" onclick="submit_and_reset('form_edit_column');"><i class="bi bi-check-lg"></i></button>
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button" onclick="$('#form_edit_column').trigger('reset');"><i class="bi bi-x"></i></button>
|
||||
<button class="btn btn-primary" type="button" onclick="$('#form_edit_column').trigger('submit').trigger('reset');"><i class="bi bi-check-lg"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user