Skip to content

Commit

Permalink
refactor: radioList component
Browse files Browse the repository at this point in the history
  • Loading branch information
arildm committed May 30, 2024
1 parent 17a72b3 commit a757fcf
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 98 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
### Changed

- Replaced Raphael library with Chart.js, used in the pie chart over corpus distribution in statistics

### Refactoring

- Removed the global `c` alias for `console`
- Removed global `lang`, use `$rootScope["lang"]` instead (outside Angular: `getService("$rootScope")["lang"]`)
- Removed global `loc_data`, use `$rootScope["loc_data"]` instead (outside Angular: `getService("$rootScope")["loc_data"]`)
- Removed globals `CSV` and `moment`, import the libraries instead
- Converted the "radioList" JQuery widget to a component

### Fixed

Expand Down
3 changes: 0 additions & 3 deletions app/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,6 @@ korpApp.run([

// Trigger jQuery Localize
$("body").localize()

// Update language switcher
$("#languages").radioList("select", lang)
})

$(document).keyup(function (event) {
Expand Down
50 changes: 29 additions & 21 deletions app/scripts/components/corpus-distribution-chart.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,46 @@
/** @format */
import angular, { IController, IRootScopeService } from "angular"
import angular, { type IController, type IRootScopeService, type IScope } from "angular"
import { Chart } from "chart.js"
import { html } from "@/util"

const defaultMode: Mode = "relative"
import { loc } from "@/i18n"
import { type Option } from "@/components/radio-list"

angular.module("korpApp").component("corpusDistributionChart", {
template: html`
<div class="flex flex-col gap-2 items-center">
<canvas id="distribution-chart"></canvas>
<div id="statistics_switch">
<a data-mode="relative" href="javascript:"> {{ 'statstable_relfigures' | loc }} </a>
<a data-mode="absolute" href="javascript:"> {{ 'statstable_absfigures' | loc }} </a>
</div>
<radio-list options="$ctrl.modeOptions" ng-model="mode"></radio-list>
</div>
`,
bindings: {
row: "<",
},
controller: [
"$rootScope",
function ($rootScope: IRootScopeService) {
"$scope",
function ($rootScope: IRootScopeService, $scope: CorpusDistributionChartScope) {
const $ctrl = this as CorpusDistributionChartController
$ctrl.modeOptions = [
{
value: "relative",
label: loc("statstable_relfigures", $rootScope["lang"]),
},
{
value: "absolute",
label: loc("statstable_absfigures", $rootScope["lang"]),
},
]
$scope.mode = "relative"
let chart: Chart<"pie">

const getValues = (mode: Mode) => $ctrl.row.map((corpus) => corpus.values[mode == "relative" ? 1 : 0])
const getValues = () => $ctrl.row.map((corpus) => corpus.values[$scope.mode == "relative" ? 1 : 0])

$ctrl.$onInit = () => {
chart = new Chart("distribution-chart", {
type: "pie",
data: {
labels: $ctrl.row.map((corpus) => corpus.title),
datasets: [{ data: getValues(defaultMode) }],
datasets: [{ data: getValues() }],
},
options: {
locale: $rootScope["lang"],
Expand All @@ -42,24 +51,23 @@ angular.module("korpApp").component("corpusDistributionChart", {
},
},
})

setTimeout(() => {
const radioList = ($("#statistics_switch") as any).radioList({
selected: defaultMode,
change: () => {
const mode = radioList.radioList("getSelected").attr("data-mode")
chart.data.datasets[0].data = getValues(mode)
chart.update()
},
})
})
}

$scope.$watch("mode", () => {
chart.data.datasets[0].data = getValues()
chart.update()
})
},
],
})

type CorpusDistributionChartScope = IScope & {
mode: Mode
}

type CorpusDistributionChartController = IController & {
row: { title: string; values: [number, number] }[]
modeOptions: Option<Mode>[]
}

type Mode = "relative" | "absolute"
26 changes: 17 additions & 9 deletions app/scripts/components/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import settings from "@/settings"
import currentMode from "@/mode"
import { collatorSort, html } from "@/util"
import "@/components/corpus_chooser/corpus-chooser"
import "@/components/radio-list"

angular.module("korpApp").component("header", {
template: html`
Expand Down Expand Up @@ -77,14 +78,8 @@ angular.module("korpApp").component("header", {
<div class="flex items-center gap-4">
<login-status></login-status>
<div id="languages">
<a
ng-repeat="langObj in $ctrl.languages"
data-mode="{{langObj.value}}"
ng-click="$root.lang = langObj.value"
>{{langObj.label | locObj:$root.lang}}</a
>
</div>
<radio-list options="$ctrl.languages" ng-model="lang"> </radio-list>
<a class="transiton duration-200 hover_text-blue-600" ng-click="$ctrl.citeClick()"
>{{'about_cite_header' | loc:$root.lang}}</a
Expand Down Expand Up @@ -151,12 +146,16 @@ angular.module("korpApp").component("header", {
`,
bindings: {},
controller: [
"$location",
"$uibModal",
"$rootScope",
"$scope",
"utils",
function ($uibModal, $rootScope, utils) {
function ($location, $uibModal, $rootScope, $scope, utils) {
const $ctrl = this

$scope.lang = $rootScope.lang

$ctrl.logoClick = function () {
const [baseUrl, modeParam, langParam] = $ctrl.getUrlParts(currentMode)
window.location = baseUrl + modeParam + langParam
Expand All @@ -167,6 +166,14 @@ angular.module("korpApp").component("header", {

$ctrl.languages = settings["languages"]

$scope.$watch("lang", (newVal, oldVal) => {
// Watcher gets called with `undefined` on init.
if (!$scope.lang) return
$rootScope["lang"] = $scope.lang
// Set url param if different from default.
$location.search("lang", $scope.lang !== settings["default_language"] ? $scope.lang : null)
})

$ctrl.citeClick = () => {
$rootScope.show_modal = "about"
}
Expand Down Expand Up @@ -221,6 +228,7 @@ angular.module("korpApp").component("header", {
$ctrl.visible = $ctrl.modes.slice(0, N_VISIBLE)

$rootScope.$watch("lang", () => {
$scope.lang = $rootScope.lang
$ctrl.menu = collatorSort($ctrl.modes.slice(N_VISIBLE), "label", $rootScope.lang)

const i = _.map($ctrl.menu, "mode").indexOf(currentMode)
Expand Down
50 changes: 50 additions & 0 deletions app/scripts/components/radio-list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/** @format */
import angular, { IController, type IScope } from "angular"
import { html } from "@/util"

export default angular.module("korpApp").component("radioList", {
template: html`
<span ng-repeat="option in $ctrl.options">
<span ng-if="!$first" class="text-gray-500 mx-1">|</span>
<a ng-click="$ctrl.select(option.value)" ng-class="{radioList_selected: option.value == value}">
{{ option.label | locObj:$root.lang }}
</a>
</span>
`,
bindings: {
options: "<",
},
require: {
ngModelCtrl: "^ngModel",
},
controller: [
"$scope",
function ($scope: RadioListScope) {
const $ctrl: RadioListController = this
$scope.value = undefined

$ctrl.$onInit = () => {
$ctrl.ngModelCtrl.$render = () => {
$scope.value = $ctrl.ngModelCtrl.$viewValue
}
}

$ctrl.select = (value: string) => {
$scope.value = value
$ctrl.ngModelCtrl.$setViewValue(value)
$ctrl.ngModelCtrl.$setTouched()
$ctrl.ngModelCtrl.$setDirty()
}
},
],
})

type RadioListScope = IScope & {
value?: string
}

type RadioListController = IController & {
options: Option[]
}

export type Option<V = string> = { label: string; value: V }
10 changes: 0 additions & 10 deletions app/scripts/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { fetchInitialData } from "@/data_init"
import currentMode from "@/mode"
import * as authenticationProxy from "@/components/auth/auth"
import korpLogo from "../img/korp.svg"
import { locationSearchSet } from "./util"

const createSplashScreen = () => {
const splash = document.getElementById("preload")
Expand Down Expand Up @@ -65,15 +64,6 @@ function initApp() {
}
})

$("#languages").radioList({
change() {
const currentLang = $(this).radioList("getSelected").data("mode")
locationSearchSet("lang", currentLang !== settings["default_language"] ? currentLang : null)
},
// TODO: this does nothing?
selected: settings["default_language"],
})

// this is to hide all ugly markup before Angular is fully loaded
$("#main").css("display", "block")
$("#main").animate({ opacity: 1 }, function () {
Expand Down
46 changes: 0 additions & 46 deletions app/scripts/widgets.js

This file was deleted.

9 changes: 0 additions & 9 deletions app/styles/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,6 @@ label.placeholder {
opacity: 0.6;
}

#languages {
margin-top : -1px;
}

#query_table {
white-space: nowrap;
margin-bottom: 15px;
Expand Down Expand Up @@ -998,11 +994,6 @@ a {
}
}

.radioList_selected {
color: black !important;
cursor: default;
}

.hits_picture_table {
border : 1px solid lightgrey;
width: 100%;
Expand Down

0 comments on commit a757fcf

Please sign in to comment.