Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
arildm committed Apr 30, 2024
2 parents a77b126 + 7d640dd commit 374efc8
Show file tree
Hide file tree
Showing 36 changed files with 534 additions and 245 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ VITE_LOGOUT_URL=https://sp.spraakbanken.gu.se/Shibboleth.sso/Logout
# VITE_JWT_URL=https://sp.spraakbanken.gu.se/auth/jwt
VITE_KORP_URL=https://spraakbanken.gu.se/korp/
VITE_STRIX_URL=https://spraakbanken.gu.se/strix/
VITE_NEWS_URL=https://raw.githubusercontent.com/spraakbanken/newsdesk/main/data/mink.yaml
VITE_MATOMO_URL=https://spraakbanken.gu.se/stats/
# VITE_MATOMO_ID= # Do not report to the real backend when developing
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

strategy:
matrix:
node-version: [18.x, 20.x]
node-version: [18.x, 20.x, 22.x]

steps:
- uses: actions/checkout@v4
Expand Down
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ As this project is a user-facing application, the places in the semantic version

## [Unreleased]

## [1.6.0] (2024-04-30)

### Added

- News shown in two places on home page: featured on top, others under the intro text

### Changed

- Restructured panels on corpus overview to better match backend concepts:
- New _Analysis_ panel with the run button from _Status_ and the downloads from _Results_
- Renamed _Result_ to _Explore_ [#115](https://github.com/spraakbanken/mink-frontend/issues/115)
- Fetching news from the Newsdesk repo on page load, instead of a static file at build time
- The `on` prop of `PendingContent` now matches by start of string

### Fixed

- Clarify that data installed in tools is outdated after annotation re-run [#154](https://github.com/spraakbanken/mink-frontend/issues/154)

## [1.5.0] (2024-04-23)

### Added
Expand Down Expand Up @@ -183,7 +201,8 @@ The frontend is now open to the general public! This version allows users to:

Code changes up until this point are not documented other than in the git commit log.

[unreleased]: https://github.com/spraakbanken/mink-frontend/compare/v1.5.0...HEAD
[unreleased]: https://github.com/spraakbanken/mink-frontend/compare/v1.6.0...HEAD
[1.6.0]: https://github.com/spraakbanken/mink-frontend/compare/v1.5.0...v1.6.0
[1.5.0]: https://github.com/spraakbanken/mink-frontend/compare/v1.4.0...v1.5.0
[1.4.0]: https://github.com/spraakbanken/mink-frontend/compare/v1.3.0...v1.4.0
[1.3.0]: https://github.com/spraakbanken/mink-frontend/compare/v1.2.0...v1.3.0
Expand Down
1 change: 1 addition & 0 deletions env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface ImportMetaEnv {
readonly VITE_JWT_URL?: string;
readonly VITE_KORP_URL: string;
readonly VITE_STRIX_URL: string;
readonly VITE_NEWS_URL: string;
readonly VITE_MATOMO_URL: string;
readonly VITE_MATOMO_ID?: number;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mink-frontend",
"version": "1.5.0",
"version": "1.6.0",
"license": "MIT",
"scripts": {
"dev": "vite",
Expand Down
35 changes: 22 additions & 13 deletions src/api/backend.composable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ export default function useMinkBackend() {
spin(api.createMetadata(publicId), "create");

const deleteCorpus = (corpusId: string) =>
spin(api.removeCorpus(corpusId), `corpus/${corpusId}`);
spin(api.removeCorpus(corpusId), `corpus/${corpusId}/delete`);

const deleteMetadata = (resourceId: string) =>
spin(api.removeMetadata(resourceId), `resource/${resourceId}`);
spin(api.removeMetadata(resourceId), `resource/${resourceId}/delete`);

const loadConfig = (corpusId: string) =>
spin(api.downloadConfig(corpusId), `corpus/${corpusId}/config`);
Expand All @@ -28,7 +28,7 @@ export default function useMinkBackend() {
const downloadSource = (corpusId: string, filename: string, binary = false) =>
spin(
api.downloadSources(corpusId, filename, binary),
`corpus/${corpusId}/sources/${filename}`,
`corpus/${corpusId}/sources/${filename}/raw`,
);

const downloadPlaintext = (corpusId: string, filename: string) =>
Expand All @@ -44,11 +44,18 @@ export default function useMinkBackend() {
) =>
spin(
api.uploadSources(corpusId, files, onProgress),
`corpus/${corpusId}/sources`,
`corpus/${corpusId}/sources/upload`,
);

const deleteSource = (corpusId: string, filename: string) =>
spin(api.removeSource(corpusId, filename), `corpus/${corpusId}/sources`);
spin(
api.removeSource(corpusId, filename),
`corpus/${corpusId}/sources/list`,
);

// Same as `resourceInfoOne` but with another spin token.
const listSources = (corpusId: string) =>
spin(api.resourceInfoOne(corpusId), `corpus/${corpusId}/sources/list`);

const uploadMetadata = (resourceId: string, yaml: string) =>
spin(
Expand All @@ -64,31 +71,32 @@ export default function useMinkBackend() {

const resourceInfoAll = () => spin(api.resourceInfoAll(), "corpora");

// Same as `listSources` but with another spin token.
const resourceInfoOne = (corpusId: string) =>
spin(api.resourceInfoOne(corpusId), `corpus/${corpusId}/job`);
spin(api.resourceInfoOne(corpusId), `corpus/${corpusId}/info`);

const runJob = (corpusId: string) =>
spin(api.runSparv(corpusId), `corpus/${corpusId}/job`);
spin(api.runSparv(corpusId), `corpus/${corpusId}/job/sparv`);

const installKorp = (corpusId: string) =>
spin(api.installKorp(corpusId), `corpus/${corpusId}/job`);
spin(api.installKorp(corpusId), `corpus/${corpusId}/job/install/korp`);

const installStrix = (corpusId: string) =>
spin(api.installStrix(corpusId), `corpus/${corpusId}/job`);
spin(api.installStrix(corpusId), `corpus/${corpusId}/job/install/strix`);

const abortJob = (corpusId: string) =>
spin(api.abortJob(corpusId), `corpus/${corpusId}/job`);
spin(api.abortJob(corpusId), `corpus/${corpusId}/job/abort`);

const loadExports = (corpusId: string) =>
spin(api.listExports(corpusId), `corpus/${corpusId}/exports`);
spin(api.listExports(corpusId), `corpus/${corpusId}/exports/list`);

const downloadExports = (corpusId: string) =>
spin(api.downloadExports(corpusId), `corpus/${corpusId}/exports`);
spin(api.downloadExports(corpusId), `corpus/${corpusId}/exports/download`);

const downloadExportFiles = (corpusId: string, filename: string) =>
spin(
api.downloadExportFile(corpusId, filename),
`corpus/${corpusId}/exports`,
`corpus/${corpusId}/exports/download`,
);

const checkAdminMode = () => spin(api.adminModeStatus(), "admin-mode");
Expand All @@ -109,6 +117,7 @@ export default function useMinkBackend() {
downloadPlaintext,
uploadSources,
deleteSource,
listSources,
uploadMetadata,
downloadMetadata,
resourceInfoAll,
Expand Down
6 changes: 3 additions & 3 deletions src/api/corpusConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const yaml = import("js-yaml").then((m) => m.default);
const Yaml = import("js-yaml").then((m) => m.default);

import type { ByLang } from "@/util.types";
import type {
Expand Down Expand Up @@ -150,7 +150,7 @@ export async function makeConfig(id: string, options: ConfigOptions) {
);
}

return (await yaml).dump(config as SparvConfig);
return (await Yaml).dump(config as SparvConfig);
}

export function emptyConfig(): ConfigOptions {
Expand All @@ -167,7 +167,7 @@ export function emptyConfig(): ConfigOptions {
* May throw all kinds of errors, the sky is the limit.
*/
export async function parseConfig(configYaml: string): Promise<ConfigOptions> {
const config = (await yaml).load(configYaml) as any;
const config = (await Yaml).load(configYaml) as any;

if (!config)
throw new TypeError(`Parsing config failed, returned "${config}"`);
Expand Down
4 changes: 2 additions & 2 deletions src/auth/auth.composable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const payload = ref<JwtSbPayload>();
export function useAuth() {
const router = useRouter();
const route = useRoute();
const { spin, pending } = useSpin();
const { spin, isPending } = useSpin();
const { alert } = useMessenger();
const { t } = useI18n();

Expand All @@ -43,7 +43,7 @@ export function useAuth() {
);
const canUserWrite = computed(() => isAuthenticated.value);
/** Indicates whether a jwt request is currently loading. */
const isAuthenticating = computed(() => pending.value.includes("jwt"));
const isAuthenticating = computed(() => isPending("jwt"));

/** If not authenticated, redirect to the login page. */
async function requireAuthentication(callback?: () => void) {
Expand Down
3 changes: 2 additions & 1 deletion src/components/LayoutBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ defineProps<{

<template>
<section
class="border rounded p-2 bg-white dark:bg-zinc-900 dark:border-zinc-700"
class="relative border rounded p-2 bg-white dark:bg-zinc-900 dark:border-zinc-700 overflow-hidden"
>
<div class="flex justify-between mb-2">
<h2 v-if="title" class="text-xl font-semibold uppercase">{{ title }}</h2>
<div class="items-baseline justify-end gap-2 text-sm">
<slot name="controls" />
</div>
</div>

<slot />
</section>
</template>
45 changes: 45 additions & 0 deletions src/components/MaxHeight.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script setup lang="ts">
import { ref } from "vue";
import { useElementSize, useToggle } from "@vueuse/core";
import ActionButton from "./ActionButton.vue";
defineProps<{
/** Maximum height (px). */
maxHeight: number;
}>();
const el = ref(null);
const { height } = useElementSize(el);
const [expanded, toggleExpanded] = useToggle();
</script>

<template>
<div>
<!-- Outer wrapper, whose height gets limited -->
<div
:class="{ mask: !expanded && height > maxHeight }"
:style="{
// Set max height to slightly less than requested, to avoid ridiculously small differences between closed and expanded heights.
maxHeight: !expanded ? maxHeight - 50 + 'px' : undefined,
}"
>
<!-- Inner wrapper, of which height is measured (content's intrinsic height) -->
<div ref="el">
<slot />
</div>
</div>

<div v-if="height > maxHeight" class="text-center p-2 text-sm">
<ActionButton class="button-slim" @click="toggleExpanded()">
<icon :icon="expanded ? 'angles-up' : 'angles-down'" />
{{ expanded ? $t("expand.close") : $t("expand.open") }}
</ActionButton>
</div>
</div>
</template>

<style scoped>
.mask {
mask-image: linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 4em);
}
</style>
28 changes: 17 additions & 11 deletions src/corpus/CorpusOverview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { useCorpusState } from "@/corpus/corpusState.composable";
import ConfigPanel from "@/corpus/config/ConfigPanel.vue";
import SourcesPanel from "@/corpus/sources/SourcesPanel.vue";
import JobStatus from "@/corpus/job/JobStatus.vue";
import ExportsPanel from "@/corpus/exports/ExportsPanel.vue";
import AnalysisPanel from "@/corpus/analysis/AnalysisPanel.vue";
import ExplorePanel from "@/corpus/explore/ExplorePanel.vue";
import CorpusStateHelp from "@/corpus/CorpusStateHelp.vue";
import RouteButton from "@/components/RouteButton.vue";
import LayoutBox from "@/components/LayoutBox.vue";
Expand All @@ -14,13 +15,13 @@ const { isNeedingConfig, isNeedingMeta } = useCorpusState(corpusId);
</script>

<template>
<div class="flex flex-wrap">
<div class="flex flex-wrap gap-4">
<div class="w-full">
<CorpusStateHelp />
</div>

<div class="w-full lg:w-1/2 lg:pr-2">
<LayoutBox :title="$t('configuration')" class="mb-4">
<div class="w-96 grow flex flex-col gap-4">
<LayoutBox :title="$t('settings')">
<ConfigPanel />
<template #controls>
<RouteButton
Expand All @@ -32,22 +33,27 @@ const { isNeedingConfig, isNeedingMeta } = useCorpusState(corpusId);
</RouteButton>
</template>
</LayoutBox>

<LayoutBox :title="$t('texts')">
<SourcesPanel />
</LayoutBox>
</div>

<div class="w-full lg:w-1/2 lg:pl-2">
<div class="w-96 grow flex flex-col gap-4">
<LayoutBox
:title="$t('job.status')"
class="mb-4 bg-zinc-700 text-zinc-300 dark:bg-zinc-600"
class="bg-zinc-700 text-zinc-300 dark:bg-zinc-600"
>
<JobStatus />
</LayoutBox>

<LayoutBox :title="$t('result')" class="mb-4">
<ExportsPanel />
<LayoutBox :title="$t('analysis')">
<AnalysisPanel />
</LayoutBox>

<LayoutBox :title="$t('tools')">
<ExplorePanel />
</LayoutBox>
</div>
</div>
<LayoutBox :title="$t('texts')">
<SourcesPanel />
</LayoutBox>
</template>
Loading

0 comments on commit 374efc8

Please sign in to comment.