BTHLABS-55: Inline create save form

Co-authored-by: Tomek Wójcik <labs@tomekwojcik.pl>
Co-committed-by: Tomek Wójcik <labs@tomekwojcik.pl>
This commit is contained in:
Tomek Wójcik 2025-09-13 06:56:44 +00:00 committed by Tomek Wójcik
parent 29c732faa0
commit b15b48f702
3 changed files with 93 additions and 16 deletions

View File

@ -23,7 +23,6 @@ body, html {
}
body > .ui-viewport {
padding-bottom: 3.5rem;
padding-top: 3.5rem;
}
@ -103,3 +102,23 @@ body.ui-mode-standalone #offcanvas-controls .offcanvas-body {
#BrowseSavesView-Search .form-select {
min-width: 10rem;
}
#navbar .ui-inline-create-save-form {
bottom: 0px;
right: 0px;
top: 0px;
width: 500px;
}
@media screen and (max-width: 767px) {
#navbar .ui-inline-create-save-form {
right: 0.5rem;
width: calc(100vw - 0.5rem - 0.5rem);
}
}
@media screen and (min-width: 768px) {
#InlineCreateSaveForm {
position: relative;
}
}

View File

@ -0,0 +1,53 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present BTHLabs <contact@bthlabs.pl> (https://bthlabs.pl/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
((HotPocket, htmx) => {
class InlineCreateSaveForm {
constructor (app) {
this.app = app;
this.element = null;
this.buttonTrigger = null;
this.form = null;
}
onLoad = (event) => {
console.log('UI.InlineCreateSaveForm.onLoad()', event);
this.element = document.getElementById('InlineCreateSaveForm');
this.buttonTrigger = this.element.querySelector('.ui-inline-create-save-form-trigger');
this.buttonClose = this.element.querySelector('.ui-inline-create-save-form-close');
this.form = this.element.querySelector('.ui-inline-create-save-form');
this.buttonTrigger.addEventListener('click', this.onTriggerClick);
this.buttonClose.addEventListener('click', this.onCloseClick);
};
onTriggerClick = (event) => {
event.preventDefault();
this.form.classList.remove('d-none');
this.form.classList.add('d-flex');
};
onCloseClick = (event) => {
event.stopPropagation();
event.preventDefault();
this.form.classList.add('d-none');
this.form.classList.remove('d-flex');
};
}
HotPocket.addPlugin('UI.InlineCreateSaveForm', (app) => {
return new InlineCreateSaveForm(app);
});
})(window.HotPocket, window.htmx);

View File

@ -40,7 +40,25 @@
</a>
</li>
{% endif %}
<li class="nav-item ms-auto d-flex align-items-center">
{% if not request.user.is_anonymous %}
<li id="InlineCreateSaveForm" class="nav-item ms-auto me-1 d-flex align-items-center">
<a class="nav-link px-1 py-0 fs-3 text-primary ui-inline-create-save-form-trigger" href="{% url 'ui.saves.create' %}">
<i class="bi bi-plus-circle-fill"></i>
</a>
<form action="{% url 'ui.saves.create' %}" class="position-absolute d-none align-items-center bg-body-tertiary ui-inline-create-save-form" method="post">
{% csrf_token %}
<label class="visually-hidden" for="input-inline-create-save-form-url">{% translate 'URL' %}</label>
<input class="form-control flex-grow-1 me-1 form-control-sm" id="input-inline-create-save-form-url" name="url" placeholder="{% translate 'URL' %}" type="text">
<button class="btn btn-primary btn-sm flex-grow-0 flex-shrink-0 me-1" role="button">
<i class="bi bi-floppy-fill"></i>
</button>
<button class="btn btn-outline-danger btn-sm flex-grow-0 flex-shrink-0 ui-inline-create-save-form-close">
<i class="bi bi-x-lg"></i>
</button>
</form>
</li>
{% endif %}
<li class="nav-item {% if request.user.is_anonymous %}ms-auto{% endif %} d-flex align-items-center">
<a class="nav-link px-1 py-0 fs-3" data-bs-toggle="offcanvas" href="#offcanvas-controls" aria-controls="offcanvas-controls">
<i class="bi bi-person-circle"></i>
</a>
@ -74,20 +92,6 @@
</template>
</div>
{% if not request.user.is_anonymous %}
<nav id="button-bar" class="navbar navbar-expand-sm bg-body-tertiary fixed-bottom {% block button_bar_class %}{% endblock %}">
<div class="container">
<ul class="navbar-nav my-0 mx-auto">
<li class="nav-item d-flex align-items-center ms-2">
<a class="nav-link py-1 px-1 text-primary ui-button-bar-link" href="{% url 'ui.saves.create' %}">
<i class="bi bi-plus-circle-fill"></i>
</a>
</li>
</ul>
</div>
</nav>
{% endif %}
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvas-controls" aria-labelledby="offcanvas-controls-label">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvas-controls-label">
@ -147,6 +151,7 @@
<script src="{% static 'ui/js/hotpocket-backend.ui.BrowseSavesView.js' %}" type="text/javascript"></script>
<script src="{% static 'ui/js/hotpocket-backend.ui.ViewAssociationView.js' %}" type="text/javascript"></script>
<script src="{% static 'ui/js/hotpocket-backend.ui.BrowseAccountAppsView.js' %}" type="text/javascript"></script>
<script src="{% static 'ui/js/hotpocket-backend.ui.InlineCreateSaveForm.js' %}" type="text/javascript"></script>
{% block page_scripts %}{% endblock %}
<script type="text/javascript">
(() => {