UNPKG

sparnatural

Version:

Visual client-side SPARQL query builder and knowledge graph exploration tool

240 lines (213 loc) 7.62 kB
import { Pattern } from "sparqljs"; import AddUserInputBtn from "../../buttons/AddUserInputBtn"; import InfoBtn from "../../buttons/InfoBtn"; import { AbstractWidget, ValueRepetition, WidgetValue } from "../AbstractWidget"; import "@chenfengyuan/datepicker"; import { DataFactory } from 'rdf-data-factory'; import { SelectedVal } from "../../SelectedVal"; import ISparnaturalSpecification from "../../../spec-providers/ISparnaturalSpecification"; import { I18n } from "../../../settings/I18n"; import HTMLComponent from "../../HtmlComponent"; import { TOOLTIP_CONFIG } from "../../../settings/defaultSettings"; const factory = new DataFactory(); export class DateTimePickerValue implements WidgetValue { value: { label: string; start: Date; stop: Date; }; key():string { return JSON.stringify(this.value.start).replace(/["]+/g,'')+" - "+JSON.stringify(this.value.stop).replace(/["]+/g,''); } constructor(v:DateTimePickerValue["value"]) { this.value = v; } } // converts props of type Date to type string type StringifyDate<T> = T extends Date ? string : T extends object ? { [k in keyof T]: StringifyDate<T[k]>; } : T; // stringified type of DateTimePickerValue // see: https://effectivetypescript.com/2020/04/09/jsonify/ type StringDateTimeValue = StringifyDate<DateTimePickerValue> export class TimeDatePickerWidget extends AbstractWidget { protected widgetValues: DateTimePickerValue[]; datesHandler: any; parentComponent: any; dateFormat: any; inputStart: JQuery<HTMLElement>; inputEnd: JQuery<HTMLElement>; inputValue: JQuery<HTMLElement>; infoBtn: InfoBtn; addValueBtn: AddUserInputBtn; value: DateTimePickerValue; startClassVal: SelectedVal; objectPropVal: SelectedVal; endClassVal: SelectedVal; specProvider: ISparnaturalSpecification; constructor( parentComponent: HTMLComponent, dateFormat: any, startClassCal: SelectedVal, objectPropVal: SelectedVal, endClassVal: SelectedVal, specProvider: ISparnaturalSpecification ) { super( "timedatepicker-widget", parentComponent, null, startClassCal, objectPropVal, endClassVal, ValueRepetition.SINGLE ); this.dateFormat = dateFormat; this.specProvider = specProvider; } render() { super.render(); this.html.append( $(`<span>${I18n.labels.LabelDateFrom}&nbsp;</span>`) ); this.inputStart = $( `<input id="input-start" placeholder="${ I18n.labels.TimeWidgetDateFrom }" autocomplete="off" class="${this.dateFormat}" />` ); this.inputEnd = $( `<input id="input-end" placeholder="${ I18n.labels.TimeWidgetDateTo }" autocomplete="off" class="${this.dateFormat}" />` ); this.inputValue = $(`<input id="input-value" type="hidden"/>`); let span = $(`<span>&nbsp;${I18n.labels.LabelDateTo}&nbsp;</span>`); this.html .append(this.inputStart) .append(span) .append(this.inputEnd) .append(this.inputValue); // Build datatippy info let datatippy = this.dateFormat == "day" ? I18n.labels.TimeWidgetDateHelp : I18n.labels.TimeWidgetYearHelp; // set a tooltip on the info circle var tippySettings = Object.assign({}, TOOLTIP_CONFIG); tippySettings.placement = "left"; tippySettings.trigger = "click"; tippySettings.offset = [this.dateFormat == "day" ? 75 : 50, -20]; tippySettings.delay = [0, 0]; this.infoBtn = new InfoBtn(this, datatippy, tippySettings).render(); //finish datatippy this.addValueBtn = new AddUserInputBtn( this, I18n.labels.ButtonAdd, this.#addValueBtnClicked ).render(); let calendarFormat = (this.dateFormat === "day") ? I18n.labels.TimeWidgetDateFormat : I18n.labels.TimeWidgetYearFormat; var options: { language: any; autoHide: boolean; format: any; date: any; startView: number; } = { language: I18n.labels.LangCodeTimeDate, autoHide: true, format: calendarFormat, date: null, startView: 2, }; this.inputStart.datepicker(options); this.inputEnd.datepicker(options); return this; } #addValueBtnClicked = () => { // fix for negative years // set a minus in front of the date if there was one in the value let startDate:Date; if(this.inputStart.val() != '') { startDate = this.inputStart.datepicker("getDate"); if((this.inputStart.val() as string).startsWith("-") && !startDate.toISOString().startsWith("-")) { startDate.setFullYear(parseInt(this.inputStart.val().toString())); } } let endDate:Date; if(this.inputEnd.val() != '') { endDate = this.inputEnd.datepicker("getDate"); if((this.inputEnd.val() as string).startsWith("-") && !endDate.toISOString().startsWith("-")) { endDate.setFullYear(parseInt(this.inputEnd.val().toString())); } } let stringDateTimeVal:StringDateTimeValue["value"] ={ label: null, start:(startDate)?startDate.toISOString():null, stop:(endDate)?endDate.toISOString():null, } let widgetVal: DateTimePickerValue = this.parseInput( stringDateTimeVal ); if (!widgetVal) return; this.triggerRenderWidgetVal(widgetVal); }; parseInput(input: StringDateTimeValue["value"]): DateTimePickerValue { if(!this.#isValidDate(input.start) && !this.#isValidDate(input.stop)) throw Error('No valid Date received') let startValue = (this.#isValidDate(input.start))?new Date(input.start):null let endValue = (this.#isValidDate(input.stop))?new Date(input.stop):null if (startValue && endValue && (startValue > endValue)) throw Error('StartDate is bigger than Enddate!') let tmpValue: { start: Date; stop: Date; startLabel: string; endLabel: string }; if (this.dateFormat == "day") { tmpValue = { start: (startValue)?new Date(startValue.setHours(0, 0, 0, 0)):null, stop: (endValue)?new Date(endValue.setHours(23, 59, 59, 59)):null, startLabel: startValue?startValue.toLocaleDateString():"", endLabel: endValue?endValue.toLocaleDateString():"" }; } else { tmpValue = { start: this.#getFirstDayYear(startValue), stop: this.#getLastDayOfYear(endValue), startLabel: startValue?startValue.getFullYear().toString():"", endLabel: endValue?endValue.getFullYear().toString():"" }; } let dateTimePickerVal = new DateTimePickerValue({ label: this.#getValueLabel(tmpValue.startLabel, tmpValue.endLabel), start: tmpValue.start, stop: tmpValue.stop, }); return dateTimePickerVal; } #getFirstDayYear(startValue:Date) { return startValue ? new Date(startValue.getFullYear(),0,1,0,0,1,0) :null } #getLastDayOfYear(endValue:Date) { return endValue ? new Date(endValue.getFullYear(),11,31,23,59,59) :null } #getValueLabel = function (startLabel: string, stopLabel: string) { let valueLabel = ""; if ((startLabel != "") && (stopLabel != "")) { valueLabel = I18n.labels.LabelDateFrom+' '+ startLabel +' '+I18n.labels.LabelDateTo+' '+ stopLabel ; } else if (startLabel != "") { valueLabel = I18n.labels.DisplayValueDateFrom+' '+ startLabel ; } else if (stopLabel != "") { valueLabel = I18n.labels.DisplayValueDateTo+' '+ stopLabel ; } return valueLabel; }; #isValidDate(dateString:string){ return (new Date(dateString).toString() !== "Invalid Date") && !isNaN(Date.parse(dateString)); } }