Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
arildm committed Dec 6, 2023
2 parents c0d6fa6 + 0db13dc commit 6b14024
Show file tree
Hide file tree
Showing 41 changed files with 1,041 additions and 386 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ jobs:
node-version-file: .nvmrc
- run: yarn install
- run: yarn build

docker:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- run: docker build .
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ node_modules
.DS_Store
dist
dist-ssr
*.local
*.local
stats.html
26 changes: 24 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,31 @@ As this project is a user-facing application, the places in the semantic version

- `MAJOR` denotes changes that are expected to significantly disrupt the flow of a returning user with some experience of the application, _or_ that significantly affects the development workflow
- `MINOR` denotes changes that may affect the user experience _or_ the development workflow
- `PATCH` denotes changes that are insignificant to the user experience or the develpment workflow
- `PATCH` denotes changes that are insignificant to the user experience or the development workflow

## [Unreleased]

## [2.3.0] (2023-12-06)

### Added

- Docker support
- Show year tooltip when dragging year filter slider handles
- Add term/work titles ("slugs") to url
- Add structured data as JSON-LD snippets for SEO
- Add "noindex" robots meta for the 404 page
- Set `rel="canonical"` link element

### Change

- Set maximum app width and center on large screens
- Better use of semantic HTML5 elements
- Simplify code for setting document title

### Fixed

- Ellipsis ("...") was sometimes being added to non-truncated summaries

## [2.2.7] (2023-11-29)

### Fixed
Expand Down Expand Up @@ -266,7 +287,8 @@ As this project is a user-facing application, the places in the semantic version

This date marks the public release of the website. It features a search interface for the Queerlit bibliography, as well as a thesaurus browser for the QLIT thesaurus. Change up until this point are not documented other than in the git commit log.

[unreleased]: https://github.com/gu-gridh/queerlit-gui/compare/v2.2.7...HEAD
[unreleased]: https://github.com/gu-gridh/queerlit-gui/compare/v2.3.0...HEAD
[2.3.0]: https://github.com/gu-gridh/queerlit-gui/compare/v2.2.7...v2.3.0
[2.2.7]: https://github.com/gu-gridh/queerlit-gui/compare/v2.2.6...v2.2.7
[2.2.6]: https://github.com/gu-gridh/queerlit-gui/compare/v2.2.5...v2.2.6
[2.2.5]: https://github.com/gu-gridh/queerlit-gui/compare/v2.2.4...v2.2.5
Expand Down
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
# Install before copying the rest, for caching purposes
COPY package.json yarn.lock .yarnrc.yml ./
COPY .yarn/releases .yarn/releases
RUN yarn install
COPY . .
RUN yarn run build

# Production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
# Make Nginx run in foreground
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
CMD nginx
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ To use the test environment of Libris XL, modify `.env.local` or run:

- `VITE_XLAPI_QA=1 yarn dev`

## Docker

1. [Install Docker](https://www.docker.com/get-started/)
2. `docker build -t queerlit-gui .`
3. `docker run -p 8090:80 queerlit-gui`
4. Visit site at http://localhost:8090/

### Visual Studio Code settings

```json
Expand Down
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!doctype html>
<html lang="en">
<html lang="sv">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Queerlit</title>
</head>
<body class="h-full flex flex-col">
<div id="app" class="flex-1 flex flex-col"></div>
<div id="app" class="flex-1 flex"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
9 changes: 9 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
}
36 changes: 20 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "queerlit-gui",
"version": "2.2.7",
"version": "2.3.0",
"license": "MIT",
"scripts": {
"dev": "vite",
Expand All @@ -17,35 +17,39 @@
"@fortawesome/free-solid-svg-icons": "^6.4.2",
"@fortawesome/vue-fontawesome": "latest-3",
"@modyfi/vite-plugin-yaml": "^1.0.4",
"@unhead/vue": "^1.8.8",
"@vueform/slider": "^2.1.7",
"@vueuse/components": "^9.12.0",
"@vueuse/core": "^9.12.0",
"axios": "^1.5.0",
"axios": "^1.6.2",
"lodash": "^4.17.21",
"pinia": "^2.1.6",
"sass": "^1.66.1",
"vue": "^3.3.4",
"pinia": "^2.1.7",
"sass": "^1.69.5",
"slugify": "^1.6.6",
"vue": "^3.3.9",
"vue-dragscroll": "^4.0.5",
"vue-matomo": "^4.2.0",
"vue-router": "^4.2.4",
"vue3-drag-drop": "^1.0.0"
"vue-router": "^4.2.5",
"vue3-drag-drop": "^1.1.2"
},
"devDependencies": {
"@types/lodash": "^4.14.195",
"@types/node": "^20.4.2",
"@unhead/schema-org": "^1.8.8",
"@vitejs/plugin-vue": "^4.2.0",
"@vue/compiler-sfc": "^3.2.6",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/tsconfig": "^0.4.0",
"autoprefixer": "^10.4.15",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-vue": "^9.17.0",
"postcss": "^8.4.28",
"prettier": "^3.0.2",
"tailwindcss": "^3.3.3",
"typescript": "^5.2.2",
"autoprefixer": "^10.4.16",
"eslint": "^8.55.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-vue": "^9.19.2",
"postcss": "^8.4.32",
"prettier": "^3.1.0",
"rollup-plugin-visualizer": "^5.10.0",
"tailwindcss": "^3.3.5",
"typescript": "^5.3.2",
"vite": "^4.4.9",
"vue-tsc": "^1.8.8"
"vue-tsc": "^1.8.24"
}
}
55 changes: 45 additions & 10 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
<template>
<div class="flex-1 flex flex-col lg:flex-row text-text">
<div class="lg:w-1/2 lg:max-w-screen-sm"></div>
<div class="flex-1 bg-smoke-500"></div>

<div class="w-full max-w-screen-high flex flex-col lg:flex-row text-text">
<div class="lg:w-1/2 lg:max-w-screen-sm">
<!--
This empty element has the same width as the sidebar,
and pushes main content out from the left border.
The sidebar won't do that because it is fixed.
This allows scrolling sidebar and main content separately.
-->
</div>

<div
class="bg-smoke-500 lg:w-1/2 lg:max-w-screen-sm lg:fixed lg:h-full overflow-y-auto"
>
<div class="container py-12">
<nav class="container py-12">
<header class="max-w-screen-md pb-8">
<router-link to="/" class="flex-1" @click="reset">
<img
Expand All @@ -14,7 +24,7 @@
</router-link>
</header>

<nav class="text-lg mt-6 mb-4 transition-all duration-500 low:mt-0">
<div class="text-lg mt-6 mb-4 transition-all duration-500 low:mt-0">
<router-link
to="/"
class="main-nav-link"
Expand All @@ -27,29 +37,38 @@
<a href="https://queerlit.dh.gu.se/om/kontakt" class="main-nav-link">
Kontakt
</a>
</nav>
</div>

<aside>
<section>
<router-view name="side" />
</aside>
</div>
</section>
</nav>
</div>

<div class="flex-1 flex flex-col">
<div class="flex-1">
<section class="flex-1">
<router-view v-if="!is404" />
<NotFound v-else class="flex-1" />
</div>
</section>

<ErrorMessage />
<SiteFooter />
</div>
</div>

<div class="flex-1"></div>
</template>

<script setup lang="ts">
import { computed } from "vue";
import { useRoute } from "vue-router";
import { storeToRefs } from "pinia";
import { useHead } from "@unhead/vue";
import {
useSchemaOrg,
defineOrganization,
defineWebSite,
} from "@unhead/schema-org";
import * as libris from "@/services/libris.service";
import * as terms from "@/services/terms.service";
import * as util from "@/util";
Expand All @@ -63,12 +82,28 @@ import ErrorMessage from "./ErrorMessage.vue";
import SiteFooter from "./SiteFooter.vue";
import useSearch from "./search/search.composable";
const siteDescription =
"Queerlit är en databas för svensk skönlitteratur som skildrar samkönat begär och överskridanden av binära könsnormer.";
const { activateHistory } = useHistory();
const { is404 } = use404();
const store = useRootStore();
const queryStore = useQueryStore();
const route = useRoute();
const { doSearch } = useSearch();
useHead({
// Set Schema.org host as in https://unhead.unjs.io/schema-org/getting-started/setup
templateParams: { schemaOrg: { host: "https://queerlit.dh.gu.se" } },
// Setting head values programmatically makes them available
// for `useSchemaOrg` to use as defaults for some properties:
// https://unhead.unjs.io/schema-org/getting-started/how-it-works#site-page-level-config
meta: [{ name: "description", content: siteDescription }],
htmlAttrs: { lang: "sv" },
});
useSchemaOrg([
defineOrganization({ name: "Queerlit" }),
defineWebSite({ name: "Queerlit", description: siteDescription }),
]);
const isTitlesRoute = computed(() =>
/^\/(work|special)\//.test(route.fullPath),
Expand Down
4 changes: 2 additions & 2 deletions src/SiteFooter.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts"></script>

<template>
<div class="container mt-8 py-8 border-t flex gap-4 justify-between text-sm">
<footer class="container mt-8 py-8 flex gap-4 justify-between text-sm">
<div class="flex-1 q-body flex flex-col gap-1">
<div>
Queerlitprojektet bedrivs på
Expand All @@ -23,5 +23,5 @@
</div>
</div>
<a href="https://gu.se" class="w-20"><img src="@/assets/gu.svg" /></a>
</div>
</footer>
</template>
53 changes: 53 additions & 0 deletions src/canonicalPath.composable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useRouter, useRoute } from "vue-router";
import { useHead } from "@unhead/vue";
import { pathUrl, slugify, urlBasename } from "./util";
import type { Term, Work } from "./types/work";

type RouteParams = {
slug?: string;
[k: string]: any;
};

export function useCanonicalPath() {
const route = useRoute();
const router = useRouter();
const head = useHead({});

/** Get the preferred path for a route */
function getCanonicalPath(name: string, params: RouteParams) {
// Magically slugify any param named "slug"
if (params.slug) params.slug = slugify(params.slug);
// Get the route and its path
const matchedRoute = router.resolve({ name, params });
return matchedRoute.path;
}

/** Get the preferred path for a Libris work page */
function getWorkPath(work: Work) {
return getCanonicalPath("Work", { id: work.id, slug: work.title });
}

/** Get the preferred path for a QLIT term page */
function getTermPath(term: Term) {
// A QLIT term from Libris doesn't have the "name" prop, but it can be read from the uri
const name = "name" in term ? term.name : urlBasename(term.id);
return getCanonicalPath("Term", { id: name, slug: term.label });
}

/** Replace current path if needed */
function ensurePath(path: string) {
// Add canonical link
head?.patch({ link: [{ rel: "canonical", href: pathUrl(path) }] });
// Modify current url
if (route.path != path) {
window.history.replaceState(window.history.state, "", path);
}
}

return {
getCanonicalPath,
getWorkPath,
getTermPath,
ensurePath,
};
}
6 changes: 3 additions & 3 deletions src/components/QDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ defineEmits<{
</script>

<template>
<div class="border-2 border-dashed border-gray-300 px-2 rounded-lg">
<section class="border-2 border-dashed border-gray-300 px-2 rounded-lg">
<header class="text-lg my-1 cursor-pointer" @click="$emit('toggle')">
<icon v-if="expanded" icon="minus" size="sm" class="opacity-70" />
<icon v-else icon="plus" size="sm" class="opacity-70" />
{{ heading }}
<h4 class="inline ml-1">{{ heading }}</h4>
</header>

<div v-if="expanded">
<slot />
</div>
</div>
</section>
</template>
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import "./fontawesome";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import VueDragDrop from "vue3-drag-drop";
import matomo from "vue-matomo";
import { createHead } from "@unhead/vue";

const app = createApp(App) //
.use(router)
.use(createPinia())
.use(createHead())
.component("Icon", FontAwesomeIcon)
.use(VueDragDrop);

Expand Down
Loading

0 comments on commit 6b14024

Please sign in to comment.