diff --git a/app/scripts/components/extended/widgets/autoc-extended.js b/app/scripts/components/extended/widgets/autoc-extended.ts similarity index 65% rename from app/scripts/components/extended/widgets/autoc-extended.js rename to app/scripts/components/extended/widgets/autoc-extended.ts index d62af2675..97cf28ad7 100644 --- a/app/scripts/components/extended/widgets/autoc-extended.js +++ b/app/scripts/components/extended/widgets/autoc-extended.ts @@ -1,8 +1,19 @@ /** @format */ import { html, regescape, unregescape } from "@/util" +import { WidgetScope, WidgetWithOptions } from "./common" import "@/components/autoc" -export const autocExtended = (options) => ({ +export type AutocExtendedOptions = { + type?: string + error_on_empty?: boolean +} + +type AutocExtendedScope = WidgetScope & { + isRawInput: boolean + onChange: (output: string, isRawOutput: boolean) => void +} + +export const autocExtended: WidgetWithOptions = (options) => ({ template: html` ({ >`, controller: [ "$scope", - function ($scope) { + function ($scope: AutocExtendedScope) { if ($scope.model) { $scope.input = unregescape($scope.model) $scope.isRawInput = false diff --git a/app/scripts/components/extended/widgets/common.ts b/app/scripts/components/extended/widgets/common.ts index 203550af1..aa2111d8f 100644 --- a/app/scripts/components/extended/widgets/common.ts +++ b/app/scripts/components/extended/widgets/common.ts @@ -10,16 +10,26 @@ import { StructService, StructServiceOptions } from "@/backend/struct-service" import { RootScope } from "@/root-scope.types" import { LocMap } from "@/i18n/types" -type WidgetScope = IScope & { - $parent: any +export type WidgetDefinition = Widget | WidgetWithOptions +export type WidgetWithOptions = (options: T) => Widget +export type Widget = { + template: string | ((vars: Record) => string) + controller: IController +} + +export type WidgetScope = IScope & { orObj: Condition model: T input: string - loading: boolean +} + +export type SelectWidgetScope = WidgetScope & { + $parent: any + dataset: string[][] type: string translation: LocMap - dataset: string[][] inputOnly: boolean + loading: boolean getRows: (input?: string) => string[][] typeaheadInputFormatter: (model: string) => string } @@ -36,7 +46,7 @@ export const selectController = (autocomplete: boolean): IController => [ "$scope", "$rootScope", "structService", - function ($scope: WidgetScope, $rootScope: RootScope, structService: StructService) { + function ($scope: SelectWidgetScope, $rootScope: RootScope, structService: StructService) { $rootScope.$on("corpuschooserchange", function (event, selected: string[]) { if (selected.length > 0) { reloadValues() diff --git a/app/scripts/components/extended/widgets/dataset-select.js b/app/scripts/components/extended/widgets/dataset-select.ts similarity index 62% rename from app/scripts/components/extended/widgets/dataset-select.js rename to app/scripts/components/extended/widgets/dataset-select.ts index b5f454f18..a8a4ff1b0 100644 --- a/app/scripts/components/extended/widgets/dataset-select.js +++ b/app/scripts/components/extended/widgets/dataset-select.ts @@ -1,7 +1,19 @@ /** @format */ import _ from "lodash" import { locAttribute } from "@/i18n" -import { selectTemplate } from "./common" +import { selectTemplate, WidgetScope, WidgetWithOptions } from "./common" +import { RootScope } from "@/root-scope.types" +import { LocMap } from "@/i18n/types" + +type DatasetSelectOptions = { + sort?: boolean +} + +type DatasetSelectScope = WidgetScope & { + translation: LocMap + // It can be Record or string[] on init, and is then reformatted to string[][] + dataset: Record | string[] | string[][] +} /** * Select-element. @@ -9,14 +21,14 @@ import { selectTemplate } from "./common" * - dataset: an object or an array of values * - escape: boolean, will be used by the escaper-directive */ -export const datasetSelect = (options) => ({ +export const datasetSelect: WidgetWithOptions = (options) => ({ template: selectTemplate, controller: [ "$scope", "$rootScope", - function ($scope, $rootScope) { - let dataset - const original = $scope.dataset + function ($scope: DatasetSelectScope, $rootScope: RootScope) { + let dataset: [string, string][] + const original = $scope.dataset as Record | string[] $rootScope.$watch("lang", (newVal, oldVal) => { if (newVal != oldVal) { diff --git a/app/scripts/components/extended/widgets/date-interval.js b/app/scripts/components/extended/widgets/date-interval.ts similarity index 51% rename from app/scripts/components/extended/widgets/date-interval.js rename to app/scripts/components/extended/widgets/date-interval.ts index 0a121218e..2a9d67de2 100644 --- a/app/scripts/components/extended/widgets/date-interval.js +++ b/app/scripts/components/extended/widgets/date-interval.ts @@ -1,11 +1,26 @@ /** @format */ import _ from "lodash" +import moment, { Moment } from "moment" import settings from "@/settings" -import moment from "moment" import { html } from "@/util" +import { Widget, WidgetScope } from "./common" import "@/components/datetime-picker" -export const dateInterval = { +type DateIntervalScope = WidgetScope<(string | number)[]> & { + minDate: Date + maxDate: Date + fromDate: Date + fromDateString: string + fromTime: Date + toDate: Date + toDateString: string + toTime: Date + commitDateInput: () => void + updateFrom: (m: Moment) => void + updateTo: (m: Moment) => void +} + +export const dateInterval: Widget = { template: html`

{{'simple' | loc:$root.lang}}

@@ -61,75 +76,64 @@ export const dateInterval = { `, controller: [ "$scope", - function ($scope) { - let s = $scope - let cl = settings.corpusListing - - let updateIntervals = function () { - let moments = cl.getMomentInterval() + function ($scope: DateIntervalScope) { + function updateIntervals() { + const moments = settings.corpusListing.getMomentInterval() if (moments.length) { - let [fromYear, toYear] = _.invokeMap(moments, "toDate") - s.minDate = fromYear - s.maxDate = toYear + ;[$scope.minDate, $scope.maxDate] = moments.map((m) => m.toDate()) } else { - let [from, to] = cl.getTimeInterval() - s.minDate = moment(from.toString(), "YYYY").toDate() - s.maxDate = moment(to.toString(), "YYYY").toDate() + const [from, to] = settings.corpusListing.getTimeInterval() + $scope.minDate = getYear(from) + $scope.maxDate = getYear(to) } } - s.commitDateInput = () => { - if (s.fromDateString) { - const dateString = s.fromDateString.length == 4 ? `${s.fromDateString}-01-01` : s.fromDateString - s.fromDate = moment(dateString).toDate() - s.fromTime = moment("000000", "HHmmss").toDate() + + $scope.commitDateInput = () => { + if ($scope.fromDateString) { + const dateString = + $scope.fromDateString.length == 4 ? `${$scope.fromDateString}-01-01` : $scope.fromDateString + $scope.fromDate = moment(dateString).toDate() + $scope.fromTime = moment("000000", "HHmmss").toDate() } - if (s.toDateString) { - const dateString = s.toDateString.length == 4 ? `${s.toDateString}-12-31` : s.toDateString - s.toDate = moment(dateString).toDate() - s.toTime = moment("235959", "HHmmss").toDate() + if ($scope.toDateString) { + const dateString = + $scope.toDateString.length == 4 ? `${$scope.toDateString}-12-31` : $scope.toDateString + $scope.toDate = moment(dateString).toDate() + $scope.toTime = moment("235959", "HHmmss").toDate() } } - s.$on("corpuschooserchange", function () { + + $scope.$on("corpuschooserchange", function () { updateIntervals() }) updateIntervals() - let getYear = function (val) { - return moment(val.toString(), "YYYYMMDD").toDate() + if (!$scope.model) { + $scope.fromDate = $scope.minDate + $scope.toDate = $scope.maxDate + ;[$scope.fromTime, $scope.toTime] = settings.corpusListing.getMomentInterval().map((m) => m.toDate()) + } else if ($scope.model.length === 4) { + ;[$scope.fromDate, $scope.toDate] = $scope.model.slice(0, 3).map(getDate) + ;[$scope.fromTime, $scope.toTime] = $scope.model.slice(2).map(getTime) } - let getTime = function (val) { - return moment(val.toString(), "HHmmss").toDate() - } - - if (!s.model) { - s.fromDate = s.minDate - s.toDate = s.maxDate - let [from, to] = _.invokeMap(cl.getMomentInterval(), "toDate") - s.fromTime = from - s.toTime = to - } else if (s.model.length === 4) { - let [fromYear, toYear] = _.map(s.model.slice(0, 3), getYear) - s.fromDate = fromYear - s.toDate = toYear - let [fromTime, toTime] = _.map(s.model.slice(2), getTime) - s.fromTime = fromTime - s.toTime = toTime - } - - s.updateFrom = (m) => { + $scope.updateFrom = (m: Moment) => { // We cannot just patch the list, we need to re-set it to trigger watcher. // [fromdate, todate, fromtime, totime] - s.model = [m.format("YYYYMMDD"), s.model[1], m.format("HHmmss"), s.model[3]] + $scope.model = [m.format("YYYYMMDD"), $scope.model[1], m.format("HHmmss"), $scope.model[3]] } - s.updateTo = (m) => { + $scope.updateTo = (m: Moment) => { // We cannot just patch the list, we need to re-set it to trigger watcher. // [fromdate, todate, fromtime, totime] m.set("second", 59) - s.model = [s.model[0], m.format("YYYYMMDD"), s.model[2], m.format("HHmmss")] + $scope.model = [$scope.model[0], m.format("YYYYMMDD"), $scope.model[2], m.format("HHmmss")] } }, ], } + +const getDate = (date: string | number): Date => moment(date.toString(), "YYYYMMDD").toDate() +const getTime = (date: string | number): Date => moment(date.toString(), "HHmmss").toDate() +const getYear = (date: number): Date => moment(date.toString(), "YYYY").toDate() diff --git a/app/scripts/components/extended/widgets/default.js b/app/scripts/components/extended/widgets/default.ts similarity index 85% rename from app/scripts/components/extended/widgets/default.js rename to app/scripts/components/extended/widgets/default.ts index eb3f7daea..7904eb29f 100644 --- a/app/scripts/components/extended/widgets/default.js +++ b/app/scripts/components/extended/widgets/default.ts @@ -1,7 +1,14 @@ /** @format */ import { html } from "@/util" +import { Widget, WidgetScope } from "./common" -export const defaultWidget = { +type DefaultWidgetScope = WidgetScope & { + case: "sensitive" | "insensitive" + makeSensitive: () => void + makeInsensitive: () => void +} + +export const defaultWidget: Widget = { template: ({ placeholder }) => html` = {} try { Object.assign(customWidgets, require("custom/extended.js").default) } catch (error) { console.log("No module for extended components available") } -const coreWidgets = { +const coreWidgets: Record = { autocExtended, datasetSelect, dateInterval, @@ -24,4 +26,4 @@ const coreWidgets = { structServiceAutocomplete, } -export default _.merge(coreWidgets, customWidgets) +export default merge(coreWidgets, customWidgets) diff --git a/app/scripts/components/extended/widgets/single-value.js b/app/scripts/components/extended/widgets/single-value.ts similarity index 56% rename from app/scripts/components/extended/widgets/single-value.js rename to app/scripts/components/extended/widgets/single-value.ts index 7008f2992..381100c87 100644 --- a/app/scripts/components/extended/widgets/single-value.js +++ b/app/scripts/components/extended/widgets/single-value.ts @@ -1,15 +1,20 @@ /** @format */ import { html } from "@/util" +import { Widget, WidgetScope } from "./common" + +type SingleValueScope = WidgetScope & { + dataset: Record +} /** * Puts the first value from a dataset parameter into model */ -export const singleValue = { +export const singleValue: Widget = { template: html``, controller: [ "$scope", - function ($scope) { + function ($scope: SingleValueScope) { $scope.model = Object.values($scope.dataset)[0] }, ], diff --git a/app/scripts/components/extended/widgets/struct-service-autocomplete.js b/app/scripts/components/extended/widgets/struct-service-autocomplete.ts similarity index 86% rename from app/scripts/components/extended/widgets/struct-service-autocomplete.js rename to app/scripts/components/extended/widgets/struct-service-autocomplete.ts index bad26419d..da5440086 100644 --- a/app/scripts/components/extended/widgets/struct-service-autocomplete.js +++ b/app/scripts/components/extended/widgets/struct-service-autocomplete.ts @@ -1,13 +1,13 @@ /** @format */ import { html } from "@/util" -import { selectController } from "./common" +import { selectController, Widget } from "./common" /** * Autocomplete. Gets values from "struct_values"-command. * Use the following settings in the corpus: * - escape: boolean, will be used by the escaper-directive */ -export const structServiceAutocomplete = { +export const structServiceAutocomplete: Widget = { template: html`