mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2026-02-04 02:25:30 +00:00
FIX: back-links in bearbeiten-Formularen
This commit is contained in:
@@ -80,6 +80,7 @@ func (p *AlmanachContentsEditPage) GET(engine *templating.Engine, app core.App)
|
|||||||
data["musenalm_types"] = dbmodels.MUSENALM_TYPE_VALUES
|
data["musenalm_types"] = dbmodels.MUSENALM_TYPE_VALUES
|
||||||
data["pagination_values"] = paginationValuesSorted()
|
data["pagination_values"] = paginationValuesSorted()
|
||||||
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
if msg := popFlashSuccess(e); msg != "" {
|
if msg := popFlashSuccess(e); msg != "" {
|
||||||
data["success"] = msg
|
data["success"] = msg
|
||||||
@@ -160,6 +161,7 @@ func (p *AlmanachContentsEditPage) GETItemEdit(engine *templating.Engine, app co
|
|||||||
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
||||||
data["agents"] = agentsMap
|
data["agents"] = agentsMap
|
||||||
data["content_agents"] = contentAgentsMap[content.Id]
|
data["content_agents"] = contentAgentsMap[content.Id]
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
data["prev_content"] = prevContent
|
data["prev_content"] = prevContent
|
||||||
data["next_content"] = nextContent
|
data["next_content"] = nextContent
|
||||||
data["content_index"] = contentIndex
|
data["content_index"] = contentIndex
|
||||||
@@ -205,6 +207,7 @@ func (p *AlmanachContentsEditPage) GETNew(engine *templating.Engine, app core.Ap
|
|||||||
data["agents"] = map[string]*dbmodels.Agent{}
|
data["agents"] = map[string]*dbmodels.Agent{}
|
||||||
data["content_agents"] = []*dbmodels.RContentsAgents{}
|
data["content_agents"] = []*dbmodels.RContentsAgents{}
|
||||||
data["is_new"] = true
|
data["is_new"] = true
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
return engine.Response200(e, TEMPLATE_ALMANACH_CONTENTS_ITEM_EDIT, data, p.Layout)
|
return engine.Response200(e, TEMPLATE_ALMANACH_CONTENTS_ITEM_EDIT, data, p.Layout)
|
||||||
}
|
}
|
||||||
@@ -225,6 +228,7 @@ func (p *AlmanachContentsEditPage) renderError(engine *templating.Engine, app co
|
|||||||
data["pagination_values"] = paginationValuesSorted()
|
data["pagination_values"] = paginationValuesSorted()
|
||||||
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
||||||
data["error"] = message
|
data["error"] = message
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
data["edit_content_id"] = strings.TrimSpace(e.Request.URL.Query().Get("edit_content"))
|
data["edit_content_id"] = strings.TrimSpace(e.Request.URL.Query().Get("edit_content"))
|
||||||
data["new_content"] = strings.TrimSpace(e.Request.URL.Query().Get("new_content"))
|
data["new_content"] = strings.TrimSpace(e.Request.URL.Query().Get("new_content"))
|
||||||
return engine.Response200(e, p.Template, data, p.Layout)
|
return engine.Response200(e, p.Template, data, p.Layout)
|
||||||
@@ -299,6 +303,7 @@ func (p *AlmanachContentsEditPage) renderItemError(engine *templating.Engine, ap
|
|||||||
data["content_index"] = contentIndex
|
data["content_index"] = contentIndex
|
||||||
data["content_total"] = contentTotal
|
data["content_total"] = contentTotal
|
||||||
data["error"] = message
|
data["error"] = message
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
return engine.Response200(e, TEMPLATE_ALMANACH_CONTENTS_ITEM_EDIT, data, p.Layout)
|
return engine.Response200(e, TEMPLATE_ALMANACH_CONTENTS_ITEM_EDIT, data, p.Layout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ func (p *AlmanachEditPage) GET(engine *templating.Engine, app core.App) HandleFu
|
|||||||
data["item_types"] = dbmodels.ITEM_TYPE_VALUES
|
data["item_types"] = dbmodels.ITEM_TYPE_VALUES
|
||||||
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
||||||
data["series_relations"] = dbmodels.SERIES_RELATIONS
|
data["series_relations"] = dbmodels.SERIES_RELATIONS
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
if msg := popFlashSuccess(e); msg != "" {
|
if msg := popFlashSuccess(e); msg != "" {
|
||||||
data["success"] = msg
|
data["success"] = msg
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ func (p *AlmanachNewPage) GET(engine *templating.Engine, app core.App) HandleFun
|
|||||||
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
data["agent_relations"] = dbmodels.AGENT_RELATIONS
|
||||||
data["series_relations"] = dbmodels.SERIES_RELATIONS
|
data["series_relations"] = dbmodels.SERIES_RELATIONS
|
||||||
data["is_new"] = true
|
data["is_new"] = true
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
return engine.Response200(e, p.Template, data, p.Layout)
|
return engine.Response200(e, p.Template, data, p.Layout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -362,62 +362,9 @@ func (p *BaendePage) buildResultData(app core.App, ma pagemodels.IApp, e *core.R
|
|||||||
return data, fmt.Errorf("failed to get users from cache")
|
return data, fmt.Errorf("failed to get users from cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine active filter (only one at a time)
|
|
||||||
activeFilterType := ""
|
|
||||||
activeFilterValue := ""
|
|
||||||
switch {
|
|
||||||
case status != "":
|
|
||||||
activeFilterType = "status"
|
|
||||||
activeFilterValue = status
|
|
||||||
person = ""
|
|
||||||
user = ""
|
|
||||||
yearStr = ""
|
|
||||||
place = ""
|
|
||||||
case person != "":
|
|
||||||
activeFilterType = "person"
|
|
||||||
activeFilterValue = person
|
|
||||||
user = ""
|
|
||||||
yearStr = ""
|
|
||||||
place = ""
|
|
||||||
case user != "":
|
|
||||||
activeFilterType = "user"
|
|
||||||
activeFilterValue = user
|
|
||||||
yearStr = ""
|
|
||||||
place = ""
|
|
||||||
case yearStr != "":
|
|
||||||
activeFilterType = "year"
|
|
||||||
activeFilterValue = yearStr
|
|
||||||
place = ""
|
|
||||||
case place != "":
|
|
||||||
activeFilterType = "place"
|
|
||||||
activeFilterValue = place
|
|
||||||
}
|
|
||||||
if activeFilterType != "" {
|
|
||||||
search = ""
|
|
||||||
letter = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply search/letter/filters
|
// Apply search/letter/filters
|
||||||
var filteredEntries []*dbmodels.Entry
|
filteredEntries := allEntries
|
||||||
if activeFilterType != "" {
|
if search != "" {
|
||||||
switch activeFilterType {
|
|
||||||
case "status":
|
|
||||||
filteredEntries = filterEntriesByStatus(allEntries, status)
|
|
||||||
case "person":
|
|
||||||
filteredEntries = filterEntriesByAgent(allEntries, entryAgentsMap, person)
|
|
||||||
case "user":
|
|
||||||
filteredEntries = filterEntriesByEditor(allEntries, user)
|
|
||||||
case "year":
|
|
||||||
yearVal, err := strconv.Atoi(yearStr)
|
|
||||||
if err != nil {
|
|
||||||
filteredEntries = []*dbmodels.Entry{}
|
|
||||||
} else {
|
|
||||||
filteredEntries = filterEntriesByYear(allEntries, yearVal)
|
|
||||||
}
|
|
||||||
case "place":
|
|
||||||
filteredEntries = filterEntriesByPlace(allEntries, place)
|
|
||||||
}
|
|
||||||
} else if search != "" {
|
|
||||||
trimmedSearch := strings.TrimSpace(search)
|
trimmedSearch := strings.TrimSpace(search)
|
||||||
if utf8.RuneCountInString(trimmedSearch) >= 3 {
|
if utf8.RuneCountInString(trimmedSearch) >= 3 {
|
||||||
entries, err := searchBaendeEntries(app, trimmedSearch)
|
entries, err := searchBaendeEntries(app, trimmedSearch)
|
||||||
@@ -429,11 +376,30 @@ func (p *BaendePage) buildResultData(app core.App, ma pagemodels.IApp, e *core.R
|
|||||||
filteredEntries = filterEntriesBySearch(allEntries, itemsMap, trimmedSearch)
|
filteredEntries = filterEntriesBySearch(allEntries, itemsMap, trimmedSearch)
|
||||||
}
|
}
|
||||||
data["search"] = trimmedSearch
|
data["search"] = trimmedSearch
|
||||||
} else if letter != "" {
|
}
|
||||||
// Apply letter filter
|
if letter != "" {
|
||||||
filteredEntries = filterEntriesByLetter(allEntries, letter)
|
filteredEntries = filterEntriesByLetter(filteredEntries, letter)
|
||||||
} else {
|
}
|
||||||
filteredEntries = allEntries
|
|
||||||
|
if status != "" {
|
||||||
|
filteredEntries = filterEntriesByStatus(filteredEntries, status)
|
||||||
|
}
|
||||||
|
if person != "" {
|
||||||
|
filteredEntries = filterEntriesByAgent(filteredEntries, entryAgentsMap, person)
|
||||||
|
}
|
||||||
|
if user != "" {
|
||||||
|
filteredEntries = filterEntriesByEditor(filteredEntries, user)
|
||||||
|
}
|
||||||
|
if yearStr != "" {
|
||||||
|
yearVal, err := strconv.Atoi(yearStr)
|
||||||
|
if err != nil {
|
||||||
|
filteredEntries = []*dbmodels.Entry{}
|
||||||
|
} else {
|
||||||
|
filteredEntries = filterEntriesByYear(filteredEntries, yearVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if place != "" {
|
||||||
|
filteredEntries = filterEntriesByPlace(filteredEntries, place)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply sorting based on sort parameter
|
// Apply sorting based on sort parameter
|
||||||
@@ -513,11 +479,14 @@ func (p *BaendePage) buildResultData(app core.App, ma pagemodels.IApp, e *core.R
|
|||||||
data["has_more"] = hasMore
|
data["has_more"] = hasMore
|
||||||
data["next_offset"] = nextOffset
|
data["next_offset"] = nextOffset
|
||||||
data["letter"] = letter
|
data["letter"] = letter
|
||||||
|
data["status"] = status
|
||||||
|
data["person"] = person
|
||||||
|
data["user"] = user
|
||||||
|
data["year"] = yearStr
|
||||||
|
data["place"] = place
|
||||||
data["sort_field"] = sort
|
data["sort_field"] = sort
|
||||||
data["sort_order"] = order
|
data["sort_order"] = order
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
data["active_filter_type"] = activeFilterType
|
|
||||||
data["active_filter_value"] = activeFilterValue
|
|
||||||
|
|
||||||
// Keep letters array for navigation
|
// Keep letters array for navigation
|
||||||
letters := []string{
|
letters := []string{
|
||||||
|
|||||||
14
controllers/cancel_url.go
Normal file
14
controllers/cancel_url.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cancelURLFromHeader(e *core.RequestEvent) string {
|
||||||
|
if e == nil || e.Request == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(e.Request.Header.Get("HX-Current-URL"))
|
||||||
|
}
|
||||||
@@ -108,6 +108,7 @@ func (p *OrtEditPage) GET(engine *templating.Engine, app core.App) HandleFunc {
|
|||||||
|
|
||||||
req := templating.NewRequest(e)
|
req := templating.NewRequest(e)
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
if msg := popFlashSuccess(e); msg != "" {
|
if msg := popFlashSuccess(e); msg != "" {
|
||||||
data["success"] = msg
|
data["success"] = msg
|
||||||
@@ -134,6 +135,7 @@ func (p *OrtEditPage) renderError(engine *templating.Engine, app core.App, e *co
|
|||||||
|
|
||||||
req := templating.NewRequest(e)
|
req := templating.NewRequest(e)
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
return engine.Response200(e, p.Template, data, p.Layout)
|
return engine.Response200(e, p.Template, data, p.Layout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func (p *OrtNewPage) renderPage(engine *templating.Engine, app core.App, e *core
|
|||||||
|
|
||||||
data["result"] = result
|
data["result"] = result
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
data["is_new"] = true
|
data["is_new"] = true
|
||||||
if message != "" {
|
if message != "" {
|
||||||
data["error"] = message
|
data["error"] = message
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ func (p *PersonEditPage) GET(engine *templating.Engine, app core.App) HandleFunc
|
|||||||
|
|
||||||
req := templating.NewRequest(e)
|
req := templating.NewRequest(e)
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
if msg := popFlashSuccess(e); msg != "" {
|
if msg := popFlashSuccess(e); msg != "" {
|
||||||
data["success"] = msg
|
data["success"] = msg
|
||||||
@@ -150,6 +151,7 @@ func (p *PersonEditPage) renderError(engine *templating.Engine, app core.App, e
|
|||||||
|
|
||||||
req := templating.NewRequest(e)
|
req := templating.NewRequest(e)
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
return engine.Response200(e, p.Template, data, p.Layout)
|
return engine.Response200(e, p.Template, data, p.Layout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ func (p *PersonNewPage) renderPage(engine *templating.Engine, app core.App, e *c
|
|||||||
|
|
||||||
data["result"] = result
|
data["result"] = result
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
data["is_new"] = true
|
data["is_new"] = true
|
||||||
if message != "" {
|
if message != "" {
|
||||||
data["error"] = message
|
data["error"] = message
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ func (p *ReiheEditPage) GET(engine *templating.Engine, app core.App) HandleFunc
|
|||||||
|
|
||||||
req := templating.NewRequest(e)
|
req := templating.NewRequest(e)
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
if msg := popFlashSuccess(e); msg != "" {
|
if msg := popFlashSuccess(e); msg != "" {
|
||||||
data["success"] = msg
|
data["success"] = msg
|
||||||
@@ -156,6 +157,7 @@ func (p *ReiheEditPage) renderError(engine *templating.Engine, app core.App, e *
|
|||||||
|
|
||||||
req := templating.NewRequest(e)
|
req := templating.NewRequest(e)
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
|
|
||||||
return engine.Response200(e, p.Template, data, p.Layout)
|
return engine.Response200(e, p.Template, data, p.Layout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ func (p *ReiheNewPage) renderPage(engine *templating.Engine, app core.App, e *co
|
|||||||
|
|
||||||
data["result"] = result
|
data["result"] = result
|
||||||
data["csrf_token"] = req.Session().Token
|
data["csrf_token"] = req.Session().Token
|
||||||
|
data["cancel_url"] = cancelURLFromHeader(e)
|
||||||
data["is_new"] = true
|
data["is_new"] = true
|
||||||
if message != "" {
|
if message != "" {
|
||||||
data["error"] = message
|
data["error"] = message
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1218,7 +1218,7 @@ type AlmanachResult struct {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-action-bar-actions">
|
<div class="form-action-bar-actions">
|
||||||
<a href="{{ if $model.is_new }}/suche/baende{{ else }}/almanach/{{ $model.result.Entry.MusenalmID }}{{ end }}" class="resetbutton w-40 flex items-center gap-2 justify-center">
|
<a href="{{ if $model.is_new }}/suche/baende{{ else }}/almanach/{{ $model.result.Entry.MusenalmID }}{{ end }}" class="resetbutton w-40 flex items-center gap-2 justify-center" data-role="cancel-link" data-cancel-url="{{ $model.cancel_url }}">
|
||||||
<i class="ri-close-line"></i>
|
<i class="ri-close-line"></i>
|
||||||
<span>Abbrechen</span>
|
<span>Abbrechen</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -7,10 +7,13 @@
|
|||||||
loading: false,
|
loading: false,
|
||||||
alphabetOpen: false,
|
alphabetOpen: false,
|
||||||
selectedLetter: '{{ $model.letter }}',
|
selectedLetter: '{{ $model.letter }}',
|
||||||
|
status: '{{ $model.status }}',
|
||||||
|
person: '{{ $model.person }}',
|
||||||
|
user: '{{ $model.user }}',
|
||||||
|
year: '{{ $model.year }}',
|
||||||
|
place: '{{ $model.place }}',
|
||||||
sortField: '{{ if $model.sort_field }}{{ $model.sort_field }}{{ else }}title{{ end }}',
|
sortField: '{{ if $model.sort_field }}{{ $model.sort_field }}{{ else }}title{{ end }}',
|
||||||
sortOrder: '{{ if $model.sort_order }}{{ $model.sort_order }}{{ else }}asc{{ end }}',
|
sortOrder: '{{ if $model.sort_order }}{{ $model.sort_order }}{{ else }}asc{{ end }}',
|
||||||
activeFilterType: '{{ $model.active_filter_type }}',
|
|
||||||
activeFilterValue: '{{ $model.active_filter_value }}',
|
|
||||||
statusLabels: {
|
statusLabels: {
|
||||||
{{- range $k, $v := $model.filter_status_labels -}}
|
{{- range $k, $v := $model.filter_status_labels -}}
|
||||||
{{ printf "%q" $k }}: {{ printf "%q" $v }},
|
{{ printf "%q" $k }}: {{ printf "%q" $v }},
|
||||||
@@ -36,14 +39,77 @@
|
|||||||
{{ printf "%q" $k }}: {{ printf "%q" $v }},
|
{{ printf "%q" $k }}: {{ printf "%q" $v }},
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
},
|
},
|
||||||
appendActiveFilter(params) {
|
appendFilters(params) {
|
||||||
if (this.activeFilterType && this.activeFilterValue) {
|
if (this.status) params.set('status', this.status);
|
||||||
params.set(this.activeFilterType, this.activeFilterValue);
|
if (this.person) params.set('person', this.person);
|
||||||
}
|
if (this.user) params.set('user', this.user);
|
||||||
|
if (this.year) params.set('year', this.year);
|
||||||
|
if (this.place) params.set('place', this.place);
|
||||||
|
},
|
||||||
|
buildResultsUrl(overrides = {}) {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
const next = {
|
||||||
|
search: this.search,
|
||||||
|
letter: this.selectedLetter,
|
||||||
|
status: this.status,
|
||||||
|
person: this.person,
|
||||||
|
user: this.user,
|
||||||
|
year: this.year,
|
||||||
|
place: this.place,
|
||||||
|
sort: this.sortField,
|
||||||
|
order: this.sortOrder,
|
||||||
|
offset: 0,
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
Object.entries(next).forEach(([key, value]) => {
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
params.set(key, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return `/baende/results/?${params.toString()}`;
|
||||||
|
},
|
||||||
|
buildPageUrl(overrides = {}) {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
const next = {
|
||||||
|
search: this.search,
|
||||||
|
letter: this.selectedLetter,
|
||||||
|
status: this.status,
|
||||||
|
person: this.person,
|
||||||
|
user: this.user,
|
||||||
|
year: this.year,
|
||||||
|
place: this.place,
|
||||||
|
sort: this.sortField,
|
||||||
|
order: this.sortOrder,
|
||||||
|
offset: this.offset,
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
Object.entries(next).forEach(([key, value]) => {
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
params.set(key, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const query = params.toString();
|
||||||
|
return query ? `/baende/?${query}` : '/baende/';
|
||||||
|
},
|
||||||
|
applyFilter(overrides = {}, indicator = 'body') {
|
||||||
|
Object.entries(overrides).forEach(([key, value]) => {
|
||||||
|
this[key] = value;
|
||||||
|
});
|
||||||
|
this.offset = 0;
|
||||||
|
this.hasMore = true;
|
||||||
|
const url = this.buildResultsUrl();
|
||||||
|
htmx.ajax('GET', url, {
|
||||||
|
target: '#baenderesults',
|
||||||
|
swap: 'outerHTML',
|
||||||
|
indicator,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
clearFilters() {
|
clearFilters() {
|
||||||
this.activeFilterType = '';
|
this.status = '';
|
||||||
this.activeFilterValue = '';
|
this.person = '';
|
||||||
|
this.user = '';
|
||||||
|
this.year = '';
|
||||||
|
this.place = '';
|
||||||
},
|
},
|
||||||
closeOtherDropdowns(current) {
|
closeOtherDropdowns(current) {
|
||||||
document.querySelectorAll('details').forEach((d) => {
|
document.querySelectorAll('details').forEach((d) => {
|
||||||
@@ -64,14 +130,12 @@
|
|||||||
params.set('sort', this.sortField);
|
params.set('sort', this.sortField);
|
||||||
params.set('order', this.sortOrder);
|
params.set('order', this.sortOrder);
|
||||||
params.set('offset', 0);
|
params.set('offset', 0);
|
||||||
this.appendActiveFilter(params);
|
this.appendFilters(params);
|
||||||
if (!this.activeFilterType) {
|
if (this.search) {
|
||||||
if (this.search) {
|
params.set('search', this.search);
|
||||||
params.set('search', this.search);
|
}
|
||||||
}
|
if (this.selectedLetter) {
|
||||||
if (this.selectedLetter) {
|
params.set('letter', this.selectedLetter);
|
||||||
params.set('letter', this.selectedLetter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryString = params.toString();
|
const queryString = params.toString();
|
||||||
@@ -86,14 +150,12 @@
|
|||||||
params.set('offset', this.offset);
|
params.set('offset', this.offset);
|
||||||
params.set('sort', this.sortField);
|
params.set('sort', this.sortField);
|
||||||
params.set('order', this.sortOrder);
|
params.set('order', this.sortOrder);
|
||||||
this.appendActiveFilter(params);
|
this.appendFilters(params);
|
||||||
if (!this.activeFilterType) {
|
if (this.search) {
|
||||||
if (this.search) {
|
params.set('search', this.search);
|
||||||
params.set('search', this.search);
|
}
|
||||||
}
|
if (this.selectedLetter) {
|
||||||
if (this.selectedLetter) {
|
params.set('letter', this.selectedLetter);
|
||||||
params.set('letter', this.selectedLetter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const query = params.toString();
|
const query = params.toString();
|
||||||
const newUrl = query ? `/baende/?${query}` : '/baende/';
|
const newUrl = query ? `/baende/?${query}` : '/baende/';
|
||||||
@@ -104,14 +166,12 @@
|
|||||||
params.set('offset', this.offset);
|
params.set('offset', this.offset);
|
||||||
params.set('sort', this.sortField);
|
params.set('sort', this.sortField);
|
||||||
params.set('order', this.sortOrder);
|
params.set('order', this.sortOrder);
|
||||||
this.appendActiveFilter(params);
|
this.appendFilters(params);
|
||||||
if (!this.activeFilterType) {
|
if (this.search) {
|
||||||
if (this.search) {
|
params.set('search', this.search);
|
||||||
params.set('search', this.search);
|
}
|
||||||
}
|
if (this.selectedLetter) {
|
||||||
if (this.selectedLetter) {
|
params.set('letter', this.selectedLetter);
|
||||||
params.set('letter', this.selectedLetter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return `/baende/more/?${params.toString()}`;
|
return `/baende/more/?${params.toString()}`;
|
||||||
}
|
}
|
||||||
@@ -122,25 +182,13 @@
|
|||||||
const params = new URL(responseUrl).searchParams;
|
const params = new URL(responseUrl).searchParams;
|
||||||
sortField = params.get('sort') || sortField;
|
sortField = params.get('sort') || sortField;
|
||||||
sortOrder = params.get('order') || sortOrder;
|
sortOrder = params.get('order') || sortOrder;
|
||||||
const filterKeys = ['status', 'person', 'user', 'year', 'place'];
|
status = params.get('status') || '';
|
||||||
activeFilterType = '';
|
person = params.get('person') || '';
|
||||||
activeFilterValue = '';
|
user = params.get('user') || '';
|
||||||
filterKeys.some((key) => {
|
year = params.get('year') || '';
|
||||||
const val = params.get(key);
|
place = params.get('place') || '';
|
||||||
if (val) {
|
search = params.get('search') || '';
|
||||||
activeFilterType = key;
|
selectedLetter = params.get('letter') || '';
|
||||||
activeFilterValue = val;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
if (activeFilterType) {
|
|
||||||
search = '';
|
|
||||||
selectedLetter = '';
|
|
||||||
} else {
|
|
||||||
search = params.get('search') || '';
|
|
||||||
selectedLetter = params.get('letter') || '';
|
|
||||||
}
|
|
||||||
updateUrl();
|
updateUrl();
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
@@ -165,13 +213,9 @@ class="container-normal font-sans mt-10">
|
|||||||
</summary>
|
</summary>
|
||||||
<div class="absolute left-0 mt-2 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
<div class="absolute left-0 mt-2 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
||||||
<div class="p-2 w-[26rem]">
|
<div class="p-2 w-[26rem]">
|
||||||
<a href="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a :href="buildPageUrl({ letter: '', offset: 0 })"
|
||||||
hx-get="/baende/results/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-alphabet-spinner"
|
hx-indicator="#baende-alphabet-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="alphabetOpen = false; applyFilter({ selectedLetter: '' }, '#baende-alphabet-spinner')"
|
||||||
hx-swap="outerHTML"
|
|
||||||
hx-push-url="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; alphabetOpen = false; selectedLetter = ''; search = ''; clearFilters()"
|
|
||||||
x-show="selectedLetter"
|
x-show="selectedLetter"
|
||||||
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
||||||
<i class="ri-filter-off-line text-base"></i>
|
<i class="ri-filter-off-line text-base"></i>
|
||||||
@@ -179,13 +223,9 @@ class="container-normal font-sans mt-10">
|
|||||||
</a>
|
</a>
|
||||||
<div class="grid grid-cols-13 gap-1 text-sm text-gray-700">
|
<div class="grid grid-cols-13 gap-1 text-sm text-gray-700">
|
||||||
{{- range $_, $ch := $model.letters -}}
|
{{- range $_, $ch := $model.letters -}}
|
||||||
<a href="/baende/?letter={{ $ch }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a :href="buildPageUrl({ letter: '{{ $ch }}', offset: 0 })"
|
||||||
hx-get="/baende/results/?letter={{ $ch }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-alphabet-spinner"
|
hx-indicator="#baende-alphabet-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="alphabetOpen = false; applyFilter({ selectedLetter: '{{ $ch }}' }, '#baende-alphabet-spinner')"
|
||||||
hx-swap="outerHTML"
|
|
||||||
hx-push-url="/baende/?letter={{ $ch }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; alphabetOpen = false; selectedLetter = '{{ $ch }}'; search = ''; clearFilters()"
|
|
||||||
:class="selectedLetter === '{{ $ch }}' ? 'bg-stone-200 font-bold' : ''"
|
:class="selectedLetter === '{{ $ch }}' ? 'bg-stone-200 font-bold' : ''"
|
||||||
class="text-center py-1 px-2 rounded hover:bg-gray-100 no-underline transition-colors">
|
class="text-center py-1 px-2 rounded hover:bg-gray-100 no-underline transition-colors">
|
||||||
{{ $ch }}
|
{{ $ch }}
|
||||||
@@ -201,8 +241,8 @@ class="container-normal font-sans mt-10">
|
|||||||
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
||||||
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
||||||
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
||||||
:class="activeFilterType === 'status' ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
:class="status ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
||||||
<span x-text="activeFilterType === 'status' ? `Status: ${statusLabels[activeFilterValue] || activeFilterValue}` : 'Status'"></span>
|
<span x-text="status ? `Status: ${statusLabels[status] || status}` : 'Status'"></span>
|
||||||
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
||||||
<span id="baende-status-spinner" class="htmx-indicator text-slate-900">
|
<span id="baende-status-spinner" class="htmx-indicator text-slate-900">
|
||||||
<i class="ri-loader-4-line spinning" aria-hidden="true"></i>
|
<i class="ri-loader-4-line spinning" aria-hidden="true"></i>
|
||||||
@@ -211,27 +251,19 @@ class="container-normal font-sans mt-10">
|
|||||||
<div class="absolute left-0 mt-2 w-72 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
<div class="absolute left-0 mt-2 w-72 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<div class="max-h-64 overflow-auto flex flex-col gap-1 text-sm text-gray-700 border border-stone-100 rounded-sm" data-role="filter-list">
|
<div class="max-h-64 overflow-auto flex flex-col gap-1 text-sm text-gray-700 border border-stone-100 rounded-sm" data-role="filter-list">
|
||||||
<a data-role="filter-item" data-label="Alle" href="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="Alle" :href="buildPageUrl({ status: '', offset: 0 })"
|
||||||
hx-get="/baende/results/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-status-spinner"
|
hx-indicator="#baende-status-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ status: '' }, '#baende-status-spinner')"
|
||||||
hx-swap="outerHTML"
|
x-show="status"
|
||||||
hx-push-url="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; clearFilters(); search = ''; selectedLetter = ''"
|
|
||||||
x-show="activeFilterType === 'status'"
|
|
||||||
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
||||||
<i class="ri-filter-off-line text-base"></i>
|
<i class="ri-filter-off-line text-base"></i>
|
||||||
<span>Alle</span>
|
<span>Alle</span>
|
||||||
</a>
|
</a>
|
||||||
{{- range $_, $s := $model.filter_statuses -}}
|
{{- range $_, $s := $model.filter_statuses -}}
|
||||||
<a data-role="filter-item" data-label="{{ $s.label }}" href="/baende/?status={{ $s.value }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="{{ $s.label }}" :href="buildPageUrl({ status: '{{ $s.value }}', offset: 0 })"
|
||||||
hx-get="/baende/results/?status={{ $s.value }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-status-spinner"
|
hx-indicator="#baende-status-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ status: '{{ $s.value }}' }, '#baende-status-spinner')"
|
||||||
hx-swap="outerHTML"
|
:class="status === '{{ $s.value }}' ? 'bg-stone-100 font-semibold' : ''"
|
||||||
hx-push-url="/baende/?status={{ $s.value }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; activeFilterType = 'status'; activeFilterValue = '{{ $s.value }}'; search = ''; selectedLetter = ''"
|
|
||||||
:class="activeFilterType === 'status' && activeFilterValue === '{{ $s.value }}' ? 'bg-stone-100 font-semibold' : ''"
|
|
||||||
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
||||||
{{ $s.label }}
|
{{ $s.label }}
|
||||||
</a>
|
</a>
|
||||||
@@ -246,20 +278,16 @@ class="container-normal font-sans mt-10">
|
|||||||
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
||||||
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
||||||
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
||||||
:class="activeFilterType === 'person' ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
:class="person ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
||||||
<span x-text="activeFilterType === 'person' ? `Person: ${personLabels[activeFilterValue] || activeFilterValue}` : 'Person'"></span>
|
<span x-text="person ? `Person: ${personLabels[person] || person}` : 'Person'"></span>
|
||||||
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
||||||
</summary>
|
</summary>
|
||||||
<div class="absolute left-0 mt-2 w-80 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
<div class="absolute left-0 mt-2 w-80 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<a data-role="filter-item" data-label="Alle" href="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="Alle" :href="buildPageUrl({ person: '', offset: 0 })"
|
||||||
hx-get="/baende/results/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-person-spinner"
|
hx-indicator="#baende-person-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ person: '' }, '#baende-person-spinner')"
|
||||||
hx-swap="outerHTML"
|
x-show="person"
|
||||||
hx-push-url="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; clearFilters(); search = ''; selectedLetter = ''"
|
|
||||||
x-show="activeFilterType === 'person'"
|
|
||||||
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
||||||
<i class="ri-filter-off-line text-base"></i>
|
<i class="ri-filter-off-line text-base"></i>
|
||||||
<span>Alle</span>
|
<span>Alle</span>
|
||||||
@@ -272,14 +300,10 @@ class="container-normal font-sans mt-10">
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-2 max-h-80 overflow-auto flex flex-col gap-0.5 text-sm text-gray-700 border border-stone-100 rounded-sm" data-role="filter-list">
|
<div class="mt-2 max-h-80 overflow-auto flex flex-col gap-0.5 text-sm text-gray-700 border border-stone-100 rounded-sm" data-role="filter-list">
|
||||||
{{- range $_, $a := $model.filter_agents -}}
|
{{- range $_, $a := $model.filter_agents -}}
|
||||||
<a data-role="filter-item" data-label="{{ $a.Name }}" href="/baende/?person={{ $a.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="{{ $a.Name }}" :href="buildPageUrl({ person: '{{ $a.Id }}', offset: 0 })"
|
||||||
hx-get="/baende/results/?person={{ $a.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-person-spinner"
|
hx-indicator="#baende-person-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ person: '{{ $a.Id }}' }, '#baende-person-spinner')"
|
||||||
hx-swap="outerHTML"
|
:class="person === '{{ $a.Id }}' ? 'bg-stone-100 font-semibold' : ''"
|
||||||
hx-push-url="/baende/?person={{ $a.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; activeFilterType = 'person'; activeFilterValue = '{{ $a.Id }}'; search = ''; selectedLetter = ''"
|
|
||||||
:class="activeFilterType === 'person' && activeFilterValue === '{{ $a.Id }}' ? 'bg-stone-100 font-semibold' : ''"
|
|
||||||
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
||||||
<span class="filter-list-searchable mr-1">{{ $a.Name }}</span>
|
<span class="filter-list-searchable mr-1">{{ $a.Name }}</span>
|
||||||
{{- if $a.CorporateBody -}}
|
{{- if $a.CorporateBody -}}
|
||||||
@@ -299,20 +323,16 @@ class="container-normal font-sans mt-10">
|
|||||||
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
||||||
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
||||||
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
||||||
:class="activeFilterType === 'user' ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
:class="user ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
||||||
<span x-text="activeFilterType === 'user' ? `Benutzer: ${userLabels[activeFilterValue] || activeFilterValue}` : 'Benutzer'"></span>
|
<span x-text="user ? `Benutzer: ${userLabels[user] || user}` : 'Benutzer'"></span>
|
||||||
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
||||||
</summary>
|
</summary>
|
||||||
<div class="absolute left-0 mt-2 w-80 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
<div class="absolute left-0 mt-2 w-80 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<a data-role="filter-item" data-label="Alle" href="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="Alle" :href="buildPageUrl({ user: '', offset: 0 })"
|
||||||
hx-get="/baende/results/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-user-spinner"
|
hx-indicator="#baende-user-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ user: '' }, '#baende-user-spinner')"
|
||||||
hx-swap="outerHTML"
|
x-show="user"
|
||||||
hx-push-url="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; clearFilters(); search = ''; selectedLetter = ''"
|
|
||||||
x-show="activeFilterType === 'user'"
|
|
||||||
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
||||||
<i class="ri-filter-off-line text-base"></i>
|
<i class="ri-filter-off-line text-base"></i>
|
||||||
<span>Alle</span>
|
<span>Alle</span>
|
||||||
@@ -325,14 +345,10 @@ class="container-normal font-sans mt-10">
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-2 max-h-80 overflow-auto flex flex-col gap-0.5 text-sm text-gray-700 border border-stone-100 rounded-sm" data-role="filter-list">
|
<div class="mt-2 max-h-80 overflow-auto flex flex-col gap-0.5 text-sm text-gray-700 border border-stone-100 rounded-sm" data-role="filter-list">
|
||||||
{{- range $_, $u := $model.filter_users -}}
|
{{- range $_, $u := $model.filter_users -}}
|
||||||
<a data-role="filter-item" data-label="{{ $u.Name }}" href="/baende/?user={{ $u.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="{{ $u.Name }}" :href="buildPageUrl({ user: '{{ $u.Id }}', offset: 0 })"
|
||||||
hx-get="/baende/results/?user={{ $u.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-user-spinner"
|
hx-indicator="#baende-user-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ user: '{{ $u.Id }}' }, '#baende-user-spinner')"
|
||||||
hx-swap="outerHTML"
|
:class="user === '{{ $u.Id }}' ? 'bg-stone-100 font-semibold' : ''"
|
||||||
hx-push-url="/baende/?user={{ $u.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; activeFilterType = 'user'; activeFilterValue = '{{ $u.Id }}'; search = ''; selectedLetter = ''"
|
|
||||||
:class="activeFilterType === 'user' && activeFilterValue === '{{ $u.Id }}' ? 'bg-stone-100 font-semibold' : ''"
|
|
||||||
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
||||||
<span class="filter-list-searchable mr-1">{{ $u.Name }}</span>
|
<span class="filter-list-searchable mr-1">{{ $u.Name }}</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -347,20 +363,16 @@ class="container-normal font-sans mt-10">
|
|||||||
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
||||||
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
||||||
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
||||||
:class="activeFilterType === 'year' ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
:class="year ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
||||||
<span x-text="activeFilterType === 'year' ? `Jahr: ${yearLabels[activeFilterValue] || activeFilterValue}` : 'Jahr'"></span>
|
<span x-text="year ? `Jahr: ${yearLabels[year] || year}` : 'Jahr'"></span>
|
||||||
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
||||||
</summary>
|
</summary>
|
||||||
<div class="absolute left-0 mt-2 w-72 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
<div class="absolute left-0 mt-2 w-72 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<a data-role="filter-item" data-label="Alle" href="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="Alle" :href="buildPageUrl({ year: '', offset: 0 })"
|
||||||
hx-get="/baende/results/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-year-spinner"
|
hx-indicator="#baende-year-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ year: '' }, '#baende-year-spinner')"
|
||||||
hx-swap="outerHTML"
|
x-show="year"
|
||||||
hx-push-url="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; clearFilters(); search = ''; selectedLetter = ''"
|
|
||||||
x-show="activeFilterType === 'year'"
|
|
||||||
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
||||||
<i class="ri-filter-off-line text-base"></i>
|
<i class="ri-filter-off-line text-base"></i>
|
||||||
<span>Alle</span>
|
<span>Alle</span>
|
||||||
@@ -375,14 +387,10 @@ class="container-normal font-sans mt-10">
|
|||||||
{{- range $_, $y := $model.filter_years -}}
|
{{- range $_, $y := $model.filter_years -}}
|
||||||
{{- $label := $y -}}
|
{{- $label := $y -}}
|
||||||
{{- if eq $y 0 -}}{{- $label = "ohne Jahr" -}}{{- end -}}
|
{{- if eq $y 0 -}}{{- $label = "ohne Jahr" -}}{{- end -}}
|
||||||
<a data-role="filter-item" data-label="{{ $label }}" href="/baende/?year={{ $y }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="{{ $label }}" :href="buildPageUrl({ year: '{{ $y }}', offset: 0 })"
|
||||||
hx-get="/baende/results/?year={{ $y }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-year-spinner"
|
hx-indicator="#baende-year-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ year: '{{ $y }}' }, '#baende-year-spinner')"
|
||||||
hx-swap="outerHTML"
|
:class="year === '{{ $y }}' ? 'bg-stone-100 font-semibold' : ''"
|
||||||
hx-push-url="/baende/?year={{ $y }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; activeFilterType = 'year'; activeFilterValue = '{{ $y }}'; search = ''; selectedLetter = ''"
|
|
||||||
:class="activeFilterType === 'year' && activeFilterValue === '{{ $y }}' ? 'bg-stone-100 font-semibold' : ''"
|
|
||||||
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
||||||
{{ $label }}
|
{{ $label }}
|
||||||
</a>
|
</a>
|
||||||
@@ -397,20 +405,16 @@ class="container-normal font-sans mt-10">
|
|||||||
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
<div class="relative" x-data="{ open: false }" data-role="baende-filter">
|
||||||
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
<details class="font-sans text-base list-none" @toggle="open = $el.open; if ($el.open) { closeOtherDropdowns($el); }">
|
||||||
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
<summary class="cursor-pointer select-none text-gray-700 hover:text-slate-900 bg-gray-100 px-3 py-1.5 rounded-md flex items-center gap-2"
|
||||||
:class="activeFilterType === 'place' ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
:class="place ? 'font-semibold text-slate-900 ring-1 ring-slate-300' : ''">
|
||||||
<span x-text="activeFilterType === 'place' ? `Ort: ${placeLabels[activeFilterValue] || activeFilterValue}` : 'Ort'"></span>
|
<span x-text="place ? `Ort: ${placeLabels[place] || place}` : 'Ort'"></span>
|
||||||
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
<i class="ri-arrow-down-s-line transform origin-center transition-transform" :class="{ 'rotate-180': open }"></i>
|
||||||
</summary>
|
</summary>
|
||||||
<div class="absolute left-0 mt-2 w-80 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
<div class="absolute left-0 mt-2 w-80 z-10 bg-white rounded-md shadow-lg border border-gray-200">
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<a data-role="filter-item" data-label="Alle" href="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="Alle" :href="buildPageUrl({ place: '', offset: 0 })"
|
||||||
hx-get="/baende/results/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-place-spinner"
|
hx-indicator="#baende-place-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ place: '' }, '#baende-place-spinner')"
|
||||||
hx-swap="outerHTML"
|
x-show="place"
|
||||||
hx-push-url="/baende/?sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; clearFilters(); search = ''; selectedLetter = ''"
|
|
||||||
x-show="activeFilterType === 'place'"
|
|
||||||
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
class="mb-2 inline-flex w-full items-center justify-center gap-2 rounded bg-orange-100 px-2 py-1 text-sm font-semibold text-orange-800 hover:bg-orange-200 no-underline transition-colors">
|
||||||
<i class="ri-filter-off-line text-base"></i>
|
<i class="ri-filter-off-line text-base"></i>
|
||||||
<span>Alle</span>
|
<span>Alle</span>
|
||||||
@@ -423,14 +427,10 @@ class="container-normal font-sans mt-10">
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-2 max-h-80 overflow-auto flex flex-col gap-0.5 text-sm text-gray-700 border border-stone-100 rounded-sm" data-role="filter-list">
|
<div class="mt-2 max-h-80 overflow-auto flex flex-col gap-0.5 text-sm text-gray-700 border border-stone-100 rounded-sm" data-role="filter-list">
|
||||||
{{- range $_, $p := $model.filter_places -}}
|
{{- range $_, $p := $model.filter_places -}}
|
||||||
<a data-role="filter-item" data-label="{{ $p.Name }}" href="/baende/?place={{ $p.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
<a data-role="filter-item" data-label="{{ $p.Name }}" :href="buildPageUrl({ place: '{{ $p.Id }}', offset: 0 })"
|
||||||
hx-get="/baende/results/?place={{ $p.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
hx-indicator="#baende-place-spinner"
|
hx-indicator="#baende-place-spinner"
|
||||||
hx-target="#baenderesults"
|
@click.prevent="open = false; applyFilter({ place: '{{ $p.Id }}' }, '#baende-place-spinner')"
|
||||||
hx-swap="outerHTML"
|
:class="place === '{{ $p.Id }}' ? 'bg-stone-100 font-semibold' : ''"
|
||||||
hx-push-url="/baende/?place={{ $p.Id }}&sort={{ $model.sort_field }}&order={{ $model.sort_order }}"
|
|
||||||
@click="offset = 0; hasMore = true; open = false; activeFilterType = 'place'; activeFilterValue = '{{ $p.Id }}'; search = ''; selectedLetter = ''"
|
|
||||||
:class="activeFilterType === 'place' && activeFilterValue === '{{ $p.Id }}' ? 'bg-stone-100 font-semibold' : ''"
|
|
||||||
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
class="filter-list-row px-2 py-1 rounded-sm hover:bg-stone-100 no-underline transition-colors">
|
||||||
{{ $p.Name }}
|
{{ $p.Name }}
|
||||||
</a>
|
</a>
|
||||||
@@ -464,6 +464,12 @@ class="container-normal font-sans mt-10">
|
|||||||
aria-label="Bändesuche">
|
aria-label="Bändesuche">
|
||||||
<input type="hidden" name="sort" :value="sortField" />
|
<input type="hidden" name="sort" :value="sortField" />
|
||||||
<input type="hidden" name="order" :value="sortOrder" />
|
<input type="hidden" name="order" :value="sortOrder" />
|
||||||
|
<input type="hidden" name="status" :value="status" />
|
||||||
|
<input type="hidden" name="person" :value="person" />
|
||||||
|
<input type="hidden" name="user" :value="user" />
|
||||||
|
<input type="hidden" name="year" :value="year" />
|
||||||
|
<input type="hidden" name="place" :value="place" />
|
||||||
|
<input type="hidden" name="letter" :value="selectedLetter" />
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input
|
<input
|
||||||
class="px-2 py-0.5 pr-7 font-sans placeholder:italic w-full text-lg"
|
class="px-2 py-0.5 pr-7 font-sans placeholder:italic w-full text-lg"
|
||||||
@@ -472,8 +478,8 @@ class="container-normal font-sans mt-10">
|
|||||||
value="{{ $model.search }}"
|
value="{{ $model.search }}"
|
||||||
placeholder="Signatur oder Suchbegriff"
|
placeholder="Signatur oder Suchbegriff"
|
||||||
x-model="search"
|
x-model="search"
|
||||||
@input.debounce.500="selectedLetter = ''; clearFilters(); ((search.trim().length >= 3) || /^[0-9]+$/.test(search.trim()) || search === '') && $el.form.requestSubmit()"
|
@input.debounce.500="((search.trim().length >= 3) || /^[0-9]+$/.test(search.trim()) || search === '') && $el.form.requestSubmit()"
|
||||||
@search.debounce.500="selectedLetter = ''; clearFilters(); ((search.trim().length >= 3) || /^[0-9]+$/.test(search.trim()) || search === '') && $el.form.requestSubmit()"
|
@search.debounce.500="((search.trim().length >= 3) || /^[0-9]+$/.test(search.trim()) || search === '') && $el.form.requestSubmit()"
|
||||||
autocomplete="off" />
|
autocomplete="off" />
|
||||||
<span id="baende-search-spinner" class="htmx-indicator absolute right-1 top-1/2 -translate-y-1/2 text-slate-900">
|
<span id="baende-search-spinner" class="htmx-indicator absolute right-1 top-1/2 -translate-y-1/2 text-slate-900">
|
||||||
<i class="ri-loader-4-line spinning" aria-hidden="true"></i>
|
<i class="ri-loader-4-line spinning" aria-hidden="true"></i>
|
||||||
|
|||||||
@@ -7,8 +7,11 @@
|
|||||||
loading: false,
|
loading: false,
|
||||||
search: '{{ $model.search }}',
|
search: '{{ $model.search }}',
|
||||||
letter: '{{ $model.letter }}',
|
letter: '{{ $model.letter }}',
|
||||||
activeFilterType: '{{ $model.active_filter_type }}',
|
status: '{{ $model.status }}',
|
||||||
activeFilterValue: '{{ $model.active_filter_value }}',
|
person: '{{ $model.person }}',
|
||||||
|
user: '{{ $model.user }}',
|
||||||
|
year: '{{ $model.year }}',
|
||||||
|
place: '{{ $model.place }}',
|
||||||
sortField: '{{ if $model.sort_field }}{{ $model.sort_field }}{{ else }}title{{ end }}',
|
sortField: '{{ if $model.sort_field }}{{ $model.sort_field }}{{ else }}title{{ end }}',
|
||||||
sortOrder: '{{ if $model.sort_order }}{{ $model.sort_order }}{{ else }}asc{{ end }}'
|
sortOrder: '{{ if $model.sort_order }}{{ $model.sort_order }}{{ else }}asc{{ end }}'
|
||||||
}">
|
}">
|
||||||
@@ -26,7 +29,7 @@
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="content-action-button"
|
class="content-action-button"
|
||||||
:hx-get="`/baende/more/?offset=${offset}&${activeFilterType && activeFilterValue ? `${activeFilterType}=${encodeURIComponent(activeFilterValue)}` : `search=${search}&letter=${letter}`}&sort=${sortField}&order=${sortOrder}`"
|
:hx-get="(() => { const params = new URLSearchParams(); params.set('offset', offset); if (search) params.set('search', search); if (letter) params.set('letter', letter); if (status) params.set('status', status); if (person) params.set('person', person); if (user) params.set('user', user); if (year) params.set('year', year); if (place) params.set('place', place); params.set('sort', sortField); params.set('order', sortOrder); return `/baende/more/?${params.toString()}`; })()"
|
||||||
hx-replace-url="true"
|
hx-replace-url="true"
|
||||||
hx-target="#baende-tbody"
|
hx-target="#baende-tbody"
|
||||||
hx-swap="beforeend"
|
hx-swap="beforeend"
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<div class="form-action-bar">
|
<div class="form-action-bar">
|
||||||
<div class="form-action-bar-inner">
|
<div class="form-action-bar-inner">
|
||||||
<div class="form-action-bar-actions">
|
<div class="form-action-bar-actions">
|
||||||
<a href="/almanach/{{ $entry.MusenalmID }}/contents/edit" class="resetbutton w-40 flex items-center gap-2 justify-center">
|
<a href="/almanach/{{ $entry.MusenalmID }}/contents/edit" class="resetbutton w-40 flex items-center gap-2 justify-center" data-role="cancel-link" data-cancel-url="{{ index . "cancel_url" }}">
|
||||||
<i class="ri-close-line"></i>
|
<i class="ri-close-line"></i>
|
||||||
<span>Zurueck</span>
|
<span>Zurueck</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"content_id" $content.Id
|
"content_id" $content.Id
|
||||||
"entry" $entry
|
"entry" $entry
|
||||||
"csrf_token" $csrf
|
"csrf_token" $csrf
|
||||||
|
"cancel_url" (index . "cancel_url")
|
||||||
"content_types" $contentTypes
|
"content_types" $contentTypes
|
||||||
"musenalm_types" $musenalmTypes
|
"musenalm_types" $musenalmTypes
|
||||||
"pagination_values" $paginationValues
|
"pagination_values" $paginationValues
|
||||||
|
|||||||
@@ -266,7 +266,7 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
</p>
|
</p>
|
||||||
<div class="form-action-bar-actions">
|
<div class="form-action-bar-actions">
|
||||||
<a href="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/edit" class="resetbutton w-40 flex items-center gap-2 justify-center">
|
<a href="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/edit" class="resetbutton w-40 flex items-center gap-2 justify-center" data-role="cancel-link" data-cancel-url="{{ $model.cancel_url }}">
|
||||||
<i class="ri-arrow-left-line"></i>
|
<i class="ri-arrow-left-line"></i>
|
||||||
<span>Liste</span>
|
<span>Liste</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -205,7 +205,7 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
</p>
|
</p>
|
||||||
<div class="form-action-bar-actions">
|
<div class="form-action-bar-actions">
|
||||||
<a href="/orte/" class="resetbutton w-40 flex items-center gap-2 justify-center">
|
<a href="/orte/" class="resetbutton w-40 flex items-center gap-2 justify-center" data-role="cancel-link" data-cancel-url="{{ $model.cancel_url }}">
|
||||||
<i class="ri-close-line"></i>
|
<i class="ri-close-line"></i>
|
||||||
<span>Abbrechen</span>
|
<span>Abbrechen</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -256,7 +256,7 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
</p>
|
</p>
|
||||||
<div class="form-action-bar-actions">
|
<div class="form-action-bar-actions">
|
||||||
<a href="{{ if $model.is_new }}/personen/{{ else }}/person/{{ $agent.Id }}{{ end }}" class="resetbutton w-40 flex items-center gap-2 justify-center">
|
<a href="{{ if $model.is_new }}/personen/{{ else }}/person/{{ $agent.Id }}{{ end }}" class="resetbutton w-40 flex items-center gap-2 justify-center" data-role="cancel-link" data-cancel-url="{{ $model.cancel_url }}">
|
||||||
<i class="ri-close-line"></i>
|
<i class="ri-close-line"></i>
|
||||||
<span>Abbrechen</span>
|
<span>Abbrechen</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -191,7 +191,7 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
</p>
|
</p>
|
||||||
<div class="form-action-bar-actions">
|
<div class="form-action-bar-actions">
|
||||||
<a href="{{ if $model.is_new }}/reihen/{{ else }}/reihe/{{ $series.MusenalmID }}{{ end }}" class="resetbutton w-40 flex items-center gap-2 justify-center">
|
<a href="{{ if $model.is_new }}/reihen/{{ else }}/reihe/{{ $series.MusenalmID }}{{ end }}" class="resetbutton w-40 flex items-center gap-2 justify-center" data-role="cancel-link" data-cancel-url="{{ $model.cancel_url }}">
|
||||||
<i class="ri-close-line"></i>
|
<i class="ri-close-line"></i>
|
||||||
<span>Abbrechen</span>
|
<span>Abbrechen</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -179,6 +179,31 @@ function ShowBoostedErrors() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupCancelLinks(root = document) {
|
||||||
|
const links = root.querySelectorAll("[data-role='cancel-link']");
|
||||||
|
links.forEach((link) => {
|
||||||
|
if (link.dataset.cancelBound === "true") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
link.dataset.cancelBound = "true";
|
||||||
|
const cancelUrl = (link.getAttribute("data-cancel-url") || "").trim();
|
||||||
|
if (cancelUrl) {
|
||||||
|
link.setAttribute("href", cancelUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
link.addEventListener("click", (event) => {
|
||||||
|
const resolved = (link.getAttribute("data-cancel-url") || "").trim();
|
||||||
|
if (resolved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
if (window.history.length > 1) {
|
||||||
|
window.history.back();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// INFO: Hooks up to all the reset button children of the target element.
|
// INFO: Hooks up to all the reset button children of the target element.
|
||||||
// If an element has a changed state, it will trigger the action with `true`.
|
// If an element has a changed state, it will trigger the action with `true`.
|
||||||
// If no elements are changed, it will trigger the action with `false`.
|
// If no elements are changed, it will trigger the action with `false`.
|
||||||
@@ -224,6 +249,15 @@ function supportsFieldSizing() {
|
|||||||
return browserSupportsFieldSizing;
|
return browserSupportsFieldSizing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
setupCancelLinks(document);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("htmx:afterSwap", (event) => {
|
||||||
|
const root = event.detail?.target || document;
|
||||||
|
setupCancelLinks(root);
|
||||||
|
});
|
||||||
|
|
||||||
// Simple textarea auto-resize function
|
// Simple textarea auto-resize function
|
||||||
function TextareaAutoResize(textarea) {
|
function TextareaAutoResize(textarea) {
|
||||||
console.log("TextareaAutoResize called for:", textarea.name || textarea.id);
|
console.log("TextareaAutoResize called for:", textarea.name || textarea.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user