mirror of
https://github.com/hrfee/jfa-go.git
synced 2026-01-18 16:47:42 +01:00
list: cleanup, include offset in DateAttempt
included UTC offset in minutes in DateAttempt, will be used shortly. Also moved this stuff (ParsedDate, DateAttempt) to the common d.ts, and the method for parsing from a string (now parseDateString) to common. Also pre-emptively load the user cache when the admin page loads.
This commit is contained in:
@@ -7,8 +7,6 @@ import { SearchConfiguration, QueryType, SearchableItem, SearchableItemDataAttri
|
||||
import { HiddenInputField } from "./ui"
|
||||
import { PaginatedList } from "./list"
|
||||
|
||||
// FIXME: Find and define a threshold after which searches are no longer performed on input (or just in general by the browser).
|
||||
|
||||
declare var window: GlobalWindow;
|
||||
|
||||
const USER_DEFAULT_SORT_FIELD = "name";
|
||||
@@ -976,9 +974,6 @@ export class accountsList extends PaginatedList {
|
||||
});
|
||||
this._populateNumbers();
|
||||
|
||||
// FIXME: Remove!
|
||||
(window as any).acc = this;
|
||||
|
||||
let searchConfig: SearchConfiguration = {
|
||||
filterArea: this._c.filterArea,
|
||||
sortingByButton: this._sortingByButton,
|
||||
|
||||
@@ -533,9 +533,6 @@ export class activityList extends PaginatedList {
|
||||
}
|
||||
});
|
||||
|
||||
// FIXME: Remove!
|
||||
(window as any).act = this;
|
||||
|
||||
this._container = document.getElementById("activity-card-list")
|
||||
document.addEventListener("activity-reload", () => this.reload());
|
||||
|
||||
@@ -583,7 +580,7 @@ export class activityList extends PaginatedList {
|
||||
// Setting default sort makes sense, since this is the only sort ever being done.
|
||||
this._c.defaultSortAscending = this.ascending;
|
||||
this._sortDirection.innerHTML = `${window.lang.strings("sortDirection")} <i class="ri-arrow-${v ? "up" : "down"}-s-line ml-2"></i>`;
|
||||
// FIXME?: We don't actually re-sort the list here, instead just use setOrdering to apply this.ascending before a reload.
|
||||
// NOTE: We don't actually re-sort the list here, instead just use setOrdering to apply this.ascending before a reload.
|
||||
this._search.setOrdering(this._search.ordering, this._c.defaultSortField, this.ascending);
|
||||
if (this._hasLoaded) {
|
||||
if (this._search.inServerSearch) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
declare var window: GlobalWindow;
|
||||
import dateParser from "any-date-parser";
|
||||
|
||||
export function toDateString(date: Date): string {
|
||||
const locale = window.language || (window as any).navigator.userLanguage || window.navigator.language;
|
||||
@@ -21,6 +22,20 @@ export function toDateString(date: Date): string {
|
||||
return date.toLocaleDateString(locale, args1) + " " + date.toLocaleString(locale, args2);
|
||||
}
|
||||
|
||||
export const parseDateString = (value: string): ParsedDate => {
|
||||
let out: ParsedDate = {
|
||||
text: value,
|
||||
// Used just to tell use what fields the user passed.
|
||||
attempt: dateParser.attempt(value),
|
||||
// note Date.fromString is also provided by dateParser.
|
||||
date: (Date as any).fromString(value) as Date
|
||||
};
|
||||
out.attempt.offsetMinutesFromUTC = out.date.getTimezoneOffset();
|
||||
// Month in Date objects is 0-based, so make our parsed date that way too
|
||||
if ("month" in out.attempt) out.attempt.month -= 1;
|
||||
return out;
|
||||
}
|
||||
|
||||
export const _get = (url: string, data: Object, onreadystatechange: (req: XMLHttpRequest) => void, noConnectionError: boolean = false): void => {
|
||||
let req = new XMLHttpRequest();
|
||||
if (window.pages) { url = window.pages.Base + url; }
|
||||
|
||||
@@ -4,6 +4,10 @@ import "@af-utils/scrollend-polyfill";
|
||||
|
||||
declare var window: GlobalWindow;
|
||||
|
||||
export interface ListItem {
|
||||
asElement: () => HTMLElement;
|
||||
};
|
||||
|
||||
export class RecordCounter {
|
||||
private _container: HTMLElement;
|
||||
private _totalRecords: HTMLElement;
|
||||
@@ -342,7 +346,7 @@ export abstract class PaginatedList {
|
||||
this.lastPage = resp.last_page;
|
||||
|
||||
appendFunc(resp);
|
||||
|
||||
|
||||
this._counter.loaded = this._search.ordering.length;
|
||||
|
||||
if (post) post(resp);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const dateParser = require("any-date-parser");
|
||||
import { ListItem } from "./list";
|
||||
import { parseDateString } from "./common";
|
||||
|
||||
declare var window: GlobalWindow;
|
||||
|
||||
@@ -176,20 +177,6 @@ export class StringQuery extends Query {
|
||||
}
|
||||
}
|
||||
|
||||
export interface DateAttempt {
|
||||
year?: number;
|
||||
month?: number;
|
||||
day?: number;
|
||||
hour?: number;
|
||||
minute?: number
|
||||
}
|
||||
|
||||
export interface ParsedDate {
|
||||
attempt: DateAttempt;
|
||||
date: Date;
|
||||
text: string;
|
||||
};
|
||||
|
||||
const dateGetters: Map<string, () => number> = (() => {
|
||||
let m = new Map<string, () => number>();
|
||||
m.set("year", Date.prototype.getFullYear);
|
||||
@@ -222,24 +209,15 @@ export class DateQuery extends Query {
|
||||
<span class="font-bold mr-2">${subject.name}:</span> ${dateText != "" ? dateText+" " : ""}${value.text}
|
||||
`;
|
||||
}
|
||||
|
||||
public static paramsFromString(valueString: string): [ParsedDate, QueryOperator, boolean] {
|
||||
// FIXME: Validate this!
|
||||
let op = QueryOperator.Equal;
|
||||
if ((Object.values(QueryOperator) as string[]).includes(valueString.charAt(0))) {
|
||||
op = valueString.charAt(0) as QueryOperator;
|
||||
// Trim the operator from the string
|
||||
valueString = valueString.substring(1);
|
||||
}
|
||||
|
||||
let out: ParsedDate = {
|
||||
text: valueString,
|
||||
// Used just to tell use what fields the user passed.
|
||||
attempt: dateParser.attempt(valueString),
|
||||
// note Date.fromString is also provided by dateParser.
|
||||
date: (Date as any).fromString(valueString) as Date
|
||||
};
|
||||
// Month in Date objects is 0-based, so make our parsed date that way too
|
||||
if ("month" in out.attempt) out.attempt.month -= 1;
|
||||
let out = parseDateString(valueString);
|
||||
let isValid = true;
|
||||
if ("invalid" in (out.date as any)) { isValid = false; };
|
||||
|
||||
@@ -278,10 +256,8 @@ export class DateQuery extends Query {
|
||||
}
|
||||
}
|
||||
|
||||
export interface SearchableItem {
|
||||
export interface SearchableItem extends ListItem {
|
||||
matchesSearch: (query: string) => boolean;
|
||||
// FIXME: SearchableItem should really be ListItem or something, this isn't for search!
|
||||
asElement: () => HTMLElement;
|
||||
}
|
||||
|
||||
export const SearchableItemDataAttribute = "data-search-item";
|
||||
@@ -598,7 +574,6 @@ export class Search {
|
||||
this._c.search.oninput(null as any);
|
||||
};
|
||||
|
||||
// FIXME: Make XQuery classes less specifically for in-progress searches, and include this code for making info button things.
|
||||
generateFilterList = () => {
|
||||
// Generate filter buttons
|
||||
for (let queryName of Object.keys(this._c.queries)) {
|
||||
|
||||
@@ -161,5 +161,20 @@ interface PaginatedReqDTO {
|
||||
ascending: boolean;
|
||||
};
|
||||
|
||||
interface DateAttempt {
|
||||
year?: number;
|
||||
month?: number;
|
||||
day?: number;
|
||||
hour?: number;
|
||||
minute?: number;
|
||||
offsetMinutesFromUTC?: number;
|
||||
}
|
||||
|
||||
interface ParsedDate {
|
||||
attempt: DateAttempt;
|
||||
date: Date;
|
||||
text: string;
|
||||
};
|
||||
|
||||
declare var config: Object;
|
||||
declare var modifiedConfig: Object;
|
||||
|
||||
11
usercache.go
11
usercache.go
@@ -235,11 +235,12 @@ const (
|
||||
}*/
|
||||
|
||||
type DateAttempt struct {
|
||||
Year *int `json:"year,omitempty"`
|
||||
Month *int `json:"month,omitempty"`
|
||||
Day *int `json:"day,omitempty"`
|
||||
Hour *int `json:"hour,omitempty"`
|
||||
Minute *int `json:"minute,omitempty"`
|
||||
Year *int `json:"year,omitempty"`
|
||||
Month *int `json:"month,omitempty"`
|
||||
Day *int `json:"day,omitempty"`
|
||||
Hour *int `json:"hour,omitempty"`
|
||||
Minute *int `json:"minute,omitempty"`
|
||||
OffsetMinutesFromUTC *int `json:"offsetMinutesFromUTC,omitempty"`
|
||||
}
|
||||
|
||||
// Compare roughly compares a time.Time to a DateAttempt.
|
||||
|
||||
7
views.go
7
views.go
@@ -67,9 +67,10 @@ func (app *appContext) pushResources(gc *gin.Context, page Page) {
|
||||
default:
|
||||
toPush = []string{}
|
||||
}
|
||||
urlBase := app.getURLBase(gc)
|
||||
if pusher := gc.Writer.Pusher(); pusher != nil {
|
||||
for _, f := range toPush {
|
||||
if err := pusher.Push(PAGES.Base+f, nil); err != nil {
|
||||
if err := pusher.Push(urlBase+f, nil); err != nil {
|
||||
app.debug.Printf(lm.FailedServerPush, err)
|
||||
}
|
||||
}
|
||||
@@ -172,6 +173,10 @@ func (app *appContext) getLang(gc *gin.Context, page Page, chosen string) string
|
||||
|
||||
func (app *appContext) AdminPage(gc *gin.Context) {
|
||||
app.pushResources(gc, AdminPage)
|
||||
|
||||
// Pre-emptively (maybe) generate user cache
|
||||
go app.userCache.MaybeSync(app)
|
||||
|
||||
lang := app.getLang(gc, AdminPage, app.storage.lang.chosenAdminLang)
|
||||
jfAdminOnly := app.config.Section("ui").Key("admin_only").MustBool(true)
|
||||
jfAllowAll := app.config.Section("ui").Key("allow_all").MustBool(false)
|
||||
|
||||
Reference in New Issue
Block a user