Skip to content

Commit

Permalink
fix: improve json button
Browse files Browse the repository at this point in the history
Fixes #417
  • Loading branch information
arildm committed Jan 9, 2025
1 parent ca144e9 commit b184cae
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 121 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
- `httpConfAddMethodAngular` was removed
- The members of the `ProgressReport` type returned by `calcProgress()` have been renamed from `{struct, stats, total_results}` to `{data, percent, hits}`

### Fixed

- The response JSON download button now handles POST and logged-in requests, and has been moved into each corresponding result tab [#417](https://github.com/spraakbanken/korp-frontend/issues/417)

## [9.7.2] - 2024-12-09

### Added
Expand Down
2 changes: 0 additions & 2 deletions app/scripts/backend/lemgram-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { RelationsParams, RelationsResponse } from "./types/relations"

export class LemgramProxy extends BaseProxy<"relations"> {
prevParams?: RelationsParams
prevUrl?: string

makeRequest(
word: string,
Expand Down Expand Up @@ -41,7 +40,6 @@ export class LemgramProxy extends BaseProxy<"relations"> {

beforeSend(req, settings) {
self.addAuthorizationHeader(req)
self.prevUrl = settings.url
},
} satisfies AjaxSettings

Expand Down
2 changes: 0 additions & 2 deletions app/scripts/backend/stats-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export function normalizeStatsData(data: CountResponse): StatsNormalized {

export class StatsProxy extends BaseProxy<"count"> {
prevParams: CountParams | null
prevUrl?: string

constructor() {
super()
Expand Down Expand Up @@ -128,7 +127,6 @@ export class StatsProxy extends BaseProxy<"count"> {
data,
beforeSend(req, settings) {
self.addAuthorizationHeader(req)
self.prevUrl = settings.url
},

error(jqXHR, textStatus, errorThrown) {
Expand Down
48 changes: 48 additions & 0 deletions app/scripts/components/json_button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/** @format */
import angular, { IController, IScope } from "angular"
import { downloadFile, html } from "@/util"
import { API } from "@/backend/types"
import { korpRequest } from "@/backend/common"

type JsonButtonController = IController & {
endpoint: keyof API
params: API[keyof API]["params"]
}

type JsonButtonScope = IScope & {
loading: boolean
openJson: () => Promise<void>
}

angular.module("korpApp").component("jsonButton", {
template: html`<div class="float-right mx-2">
<tab-preloader ng-if="loading" class="inline-block mr-1"></tab-preloader>
<input
type="image"
src="img/json.png"
alt="{{'download_response' | loc:$root.lang}}"
ng-click="openJson()"
class="border-0"
/>
</div>`,
bindings: {
endpoint: "<",
params: "<",
},
controller: [
"$scope",
function ($scope: JsonButtonScope) {
const $ctrl = this as JsonButtonController
$scope.loading = false

$scope.openJson = async function () {
// $apply needed becase async
$scope.$applyAsync(($scope: JsonButtonScope) => ($scope.loading = true))
const data = await korpRequest($ctrl.endpoint, $ctrl.params)
const json = JSON.stringify(data, null, 2)
downloadFile(json, `korp-${$ctrl.endpoint}.json`, "application/json")
$scope.$applyAsync(($scope: JsonButtonScope) => ($scope.loading = false))
}
},
],
})
32 changes: 14 additions & 18 deletions app/scripts/components/results.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** @format */
import angular, { IController } from "angular"
import { html } from "@/util"
import "@/components/json_button"
import "@/components/korp-error"
import "@/components/kwic"
import "@/components/loglike-meter"
Expand Down Expand Up @@ -63,16 +64,11 @@ angular.module("korpApp").component("results", {
prev-url="proxy.prevUrl"
corpus-order="corpusOrder"
></kwic>
<json-button endpoint="'query'" params="proxy.prevParams"></json-button>
</div>
</uib-tab>
<uib-tab
stats-result-ctrl
ng-if="$root._settings.statistics != false"
select="onentry()"
deselect="onexit()"
index="2"
>
<uib-tab stats-result-ctrl ng-if="$root._settings.statistics != false" select="onentry()" index="2">
<uib-tab-heading class="flex gap-2 items-center" ng-class="{loading: loading}">
{{'statistics' | loc:$root.lang}}
<tab-preloader
Expand All @@ -95,15 +91,14 @@ angular.module("korpApp").component("results", {
search-params="searchParams"
show-statistics="showStatistics"
></statistics>
<json-button
ng-if="showStatistics && hasResult"
endpoint="'count'"
params="proxy.prevParams"
></json-button>
</uib-tab>
<uib-tab
ng-if="$root._settings['word_picture'] != false"
wordpic-ctrl
index="3"
select="onentry()"
deselect="onexit()"
>
<uib-tab ng-if="$root._settings['word_picture'] != false" wordpic-ctrl index="3">
<uib-tab-heading class="flex gap-2 items-center" ng-class="{loading: loading}">
{{'word_picture' | loc:$root.lang}}
<tab-preloader
Expand All @@ -125,6 +120,11 @@ angular.module("korpApp").component("results", {
></word-picture>
</div>
<korp-error ng-if="error"></korp-error>
<json-button
ng-if="wordPic && hasData"
endpoint="'relations'"
params="proxy.prevParams"
></json-button>
</uib-tab>
<uib-tab example-ctrl ng-repeat="kwicTab in $root.kwicTabs" select="onentry()" deselect="onexit()">
Expand Down Expand Up @@ -280,10 +280,6 @@ angular.module("korpApp").component("results", {
</div>
</uib-tab>
</uib-tabset>
<a id="json-link" ng-href="{{$root.jsonUrl}}" ng-show="$root.jsonUrl" target="_blank">
<img src="img/json.png" />
</a>
</div>
<sidebar
Expand Down
7 changes: 0 additions & 7 deletions app/scripts/controllers/example_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const korpApp = angular.module("korpApp")
type ScopeBase = Omit<KwicCtrlScope, "makeRequest"> & IRepeatScope & TabHashScope

type ExampleCtrlScope = ScopeBase & {
$parent: { $parent: TabHashScope }
closeTab: (idx: number, e: Event) => void
hitsPictureData?: any
hitspictureClick?: (page: number) => void
Expand Down Expand Up @@ -54,8 +53,6 @@ class ExampleCtrl extends KwicCtrl {
s.corpusHits = undefined
s.aborted = false

s.tabindex = s.$parent.$parent.tabset.tabs.length - 1 + s.$index

s.newDynamicTab()

s.isReadingMode = () => {
Expand Down Expand Up @@ -156,10 +153,6 @@ class ExampleCtrl extends KwicCtrl {
return def
}

s.isActive = () => {
return s.tabindex == s.activeTab
}

if (s.kwicTab.queryParams) {
s.makeRequest().then(() => {
// s.onentry()
Expand Down
14 changes: 0 additions & 14 deletions app/scripts/controllers/kwic_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export type KwicCtrlScope = TabHashScope & {
hitsPerPage?: `${number}` | number
ignoreAbort?: boolean
initialSearch?: boolean
isActive: () => boolean
isReadingMode: () => boolean
kwic?: ApiKwic[]
loading?: boolean
Expand All @@ -47,7 +46,6 @@ export type KwicCtrlScope = TabHashScope & {
readingChange: () => void
renderCompleteResult: (data: Response<QueryResponse>, isPaging?: boolean) => void
renderResult: (data: Response<QueryResponse>) => void
tabindex?: number
toggleReading: () => void
}

Expand Down Expand Up @@ -105,8 +103,6 @@ export class KwicCtrl implements IController {

s.proxy = kwicProxyFactory.create()

s.tabindex = 0

this.initPage()

s.pageChange = function (page) {
Expand Down Expand Up @@ -275,28 +271,18 @@ export class KwicCtrl implements IController {
data.kwic = []
}

if (s.isActive()) {
$rootScope.jsonUrl = s.proxy.prevUrl
}

s.corpusOrder = data.corpus_order
s.kwic = data.kwic
}

s.onentry = () => {
$rootScope.jsonUrl = s.proxy.prevUrl
s.active = true
}

s.onexit = () => {
$rootScope.jsonUrl = undefined
s.active = false
}

s.isActive = () => {
return s.tabindex == s.activeTab
}

s.countCorpora = () => {
return s.proxy.prevParams?.corpus ? s.proxy.prevParams.corpus.split(",").length : null
}
Expand Down
18 changes: 0 additions & 18 deletions app/scripts/controllers/statistics_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,8 @@ type StatsResultCtrlScope = TabHashScope & {
proxy: StatsProxy
searchParams: SearchParams
showStatistics: boolean
tabindex: number
isActive: () => boolean
makeRequest: (cqp: string) => void
onentry: () => void
onexit: () => void
onProgress: (progressObj: ProgressReport<"count">, isPaging?: boolean) => void
renderResult: (columns: SlickgridColumn[], data: Dataset) => void
resetView: () => void
Expand All @@ -59,8 +56,6 @@ angular.module("korpApp").directive("statsResultCtrl", () => ({
s.error = false
s.progress = 0

s.tabindex = 2

s.proxy = statsProxyFactory.create()

$rootScope.$on("make_request", (event, cqp: string) => {
Expand All @@ -72,21 +67,12 @@ angular.module("korpApp").directive("statsResultCtrl", () => ({
})

s.onentry = () => {
s.$root.jsonUrl = s.proxy.prevUrl
// workaround for bug in slickgrid
// slickgrid should add this automatically, but doesn't
$("#myGrid").css("position", "relative")
$(window).trigger("resize")
}

s.onexit = () => {
s.$root.jsonUrl = undefined
}

s.isActive = () => {
return s.tabindex == s.activeTab
}

s.resetView = () => {
$("myGrid").empty()
$("#exportStatsSection").show()
Expand Down Expand Up @@ -163,10 +149,6 @@ angular.module("korpApp").directive("statsResultCtrl", () => ({
}

s.renderResult = (columns, data) => {
if (s.isActive()) {
s.$root.jsonUrl = s.proxy.prevUrl
}

s.columns = columns

if (data[0].total[0] === 0) {
Expand Down
23 changes: 0 additions & 23 deletions app/scripts/controllers/word_picture_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,9 @@ type WordpicCtrlScope = TabHashScope & {
hasData: boolean
hitSettings: `${number}`[]
ignoreAbort: boolean
isActive: () => boolean
loading: boolean
makeRequest: () => void
noHits: boolean
onentry: () => void
onexit: () => void
onProgress: (progressObj: ProgressReport<"relations">) => void
progress: number
proxy: LemgramProxy
Expand All @@ -38,7 +35,6 @@ type WordpicCtrlScope = TabHashScope & {
settings: {
showNumberOfHits: `${number}`
}
tabindex: number
wordPic: boolean
}

Expand Down Expand Up @@ -70,7 +66,6 @@ angular.module("korpApp").directive("wordpicCtrl", () => ({
"$timeout",
($scope: WordpicCtrlScope, $rootScope: RootScope, $location: LocationService, $timeout: ITimeoutService) => {
const s = $scope
s.tabindex = 3
s.proxy = lemgramProxyFactory.create()

s.error = false
Expand Down Expand Up @@ -150,20 +145,6 @@ angular.module("korpApp").directive("wordpicCtrl", () => ({
})
}

s.onentry = () => {
if (s.hasData) {
s.$root.jsonUrl = s.proxy.prevUrl
}
}

s.onexit = () => {
s.$root.jsonUrl = undefined
}

s.isActive = () => {
return s.tabindex == s.activeTab
}

s.renderResult = (data, query) => {
s.loading = false
s.progress = 100
Expand All @@ -173,10 +154,6 @@ angular.module("korpApp").directive("wordpicCtrl", () => ({
return
}

if (s.isActive()) {
s.$root.jsonUrl = s.proxy.prevUrl
}

s.hasData = true
if (!data.relations) {
s.noHits = true
Expand Down
1 change: 0 additions & 1 deletion app/scripts/root-scope.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export type RootScope = IRootScopeService & {
mapTabs: MapTab[]
textTabs: TextTab[]
waitForLogin: boolean
jsonUrl?: string
lang: string
loc_data: LangLocMap
openErrorModal: (options: {
Expand Down
11 changes: 11 additions & 0 deletions app/scripts/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,17 @@ export function buildUrl(base: string, params: Record<string, any>): string {
return url.toString()
}

/** Trigger a download in the browser. */
export function downloadFile(data: string, filename: string, type: string) {
const blob = new Blob([data], { type })
const url = URL.createObjectURL(blob)
const a = document.createElement("a")
a.href = url
a.download = filename
a.click()
URL.revokeObjectURL(url)
}

/**
* Sort elements alphabetically by a given attribute.
* @param elems A list of objects.
Expand Down
Loading

0 comments on commit b184cae

Please sign in to comment.