Skip to content

Commit

Permalink
refactor(ts): widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
arildm committed Sep 19, 2024
1 parent cc02b0f commit f7b642d
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -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<AutocExtendedOptions> = (options) => ({
template: html`<autoc
input="input"
is-raw-input="isRawInput"
Expand All @@ -13,7 +24,7 @@ export const autocExtended = (options) => ({
></autoc>`,
controller: [
"$scope",
function ($scope) {
function ($scope: AutocExtendedScope) {
if ($scope.model) {
$scope.input = unregescape($scope.model)
$scope.isRawInput = false
Expand Down
20 changes: 15 additions & 5 deletions app/scripts/components/extended/widgets/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,26 @@ import { StructService, StructServiceOptions } from "@/backend/struct-service"
import { RootScope } from "@/root-scope.types"
import { LocMap } from "@/i18n/types"

type WidgetScope<T = string> = IScope & {
$parent: any
export type WidgetDefinition = Widget | WidgetWithOptions
export type WidgetWithOptions<T extends {} = {}> = (options: T) => Widget
export type Widget = {
template: string | ((vars: Record<string, any>) => string)
controller: IController
}

export type WidgetScope<T = string> = 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
}
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
/** @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<string, string> or string[] on init, and is then reformatted to string[][]
dataset: Record<string, string> | string[] | string[][]
}

/**
* Select-element.
* Use the following settings in the corpus:
* - 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<DatasetSelectOptions> = (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, string> | string[]

$rootScope.$watch("lang", (newVal, oldVal) => {
if (newVal != oldVal) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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`
<div class="date_interval_arg_type">
<h3>{{'simple' | loc:$root.lang}}</h3>
Expand Down Expand Up @@ -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()
Original file line number Diff line number Diff line change
@@ -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`
<input
ng-model="input"
Expand All @@ -27,7 +34,7 @@ export const defaultWidget = {
`,
controller: [
"$scope",
function ($scope) {
function ($scope: DefaultWidgetScope) {
if ($scope.orObj.flags && $scope.orObj.flags.c) {
$scope.case = "insensitive"
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
/** @format */
import merge from "lodash/merge"
import { autocExtended } from "./autoc-extended"
import { WidgetDefinition } from "./common"
import { datasetSelect } from "./dataset-select"
import { dateInterval } from "./date-interval"
import { defaultWidget } from "./default"
import { singleValue } from "./single-value"
import { structServiceAutocomplete } from "./struct-service-autocomplete"
import { structServiceSelect } from "./struct-service-select"

const customWidgets = {}
const customWidgets: Record<string, WidgetDefinition> = {}
try {
Object.assign(customWidgets, require("custom/extended.js").default)
} catch (error) {
console.log("No module for extended components available")
}

const coreWidgets = {
const coreWidgets: Record<string, WidgetDefinition> = {
autocExtended,
datasetSelect,
dateInterval,
Expand All @@ -24,4 +26,4 @@ const coreWidgets = {
structServiceAutocomplete,
}

export default _.merge(coreWidgets, customWidgets)
export default merge(coreWidgets, customWidgets)
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
/** @format */

import { html } from "@/util"
import { Widget, WidgetScope } from "./common"

type SingleValueScope = WidgetScope & {
dataset: Record<string, string>
}

/**
* Puts the first value from a dataset parameter into model
*/
export const singleValue = {
export const singleValue: Widget = {
template: html`<input type="hidden" />`,
controller: [
"$scope",
function ($scope) {
function ($scope: SingleValueScope) {
$scope.model = Object.values($scope.dataset)[0]
},
],
Expand Down
Original file line number Diff line number Diff line change
@@ -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`<div>
<input
type="text"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/** @format */
import { selectController, selectTemplate } from "./common"
import { selectController, selectTemplate, Widget } from "./common"

/**
* Select-element. Gets values from "struct_values"-command.
* Use the following settings in the corpus:
* - escape: boolean, will be used by the escaper-directive
*/
export const structServiceSelect = {
export const structServiceSelect: Widget = {
template: selectTemplate,
controller: selectController(false),
}

0 comments on commit f7b642d

Please sign in to comment.