Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

81 create feature component #96

Merged
merged 18 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions components/feature-window-content.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<script lang="ts" setup>
interface Props {
params: FeatureWindowItem["params"];
}

const props = defineProps<Props>();
const { params } = toRefs(props);

const { data, isPending, isPlaceholderData } = useFeatureById(params);
const openNewWindowFromAnchor = useAnchorClickHandler();

const isLoading = computed(() => {
return isPending.value || isPlaceholderData.value;
});
</script>

<template>
<div
class="relative isolate grid h-full w-full overflow-auto"
:class="{ 'opacity-50 grayscale': isLoading }"
>
<!-- eslint-disable-next-line vue/no-v-html, vuejs-accessibility/click-events-have-key-events, vuejs-accessibility/no-static-element-interactions -->
<div v-if="data" class="prose max-w-3xl p-8" @click="openNewWindowFromAnchor" v-html="data" />

<Centered v-if="isLoading">
<LoadingIndicator />
</Centered>
</div>
</template>

<style>
/* stylelint-disable selector-class-pattern */

.tbFeatures {
@apply w-11/12 border border-solid border-[#59533c];
}

.tdFeaturesCom {
@apply bg-[#e7e2ca];
}

.tdFeaturesHead {
@apply border border-solid border-primary bg-primary text-on-primary text-lg;
}

.tdFeaturesHeadRight {
@apply align-top pr-[5px] border border-solid border-primary text-on-primary text-lg text-right;
}

.tdFeaturesLeft {
@apply align-top w-[110px] pl-[3px] border border-solid border-primary bg-on-primary text-primary;
}

.iFeaturesTrans {
@apply text-blue-600 text-xs;
}

.tdFeaturesRightSource {
@apply align-top w-4/5 pl-[3px] border border-solid border-primary bg-[#a85d8f] text-[#7f960a];
}

.tdFeaturesRightTarget {
@apply align-top w-4/5 pl-[3px] border border-solid border-primary bg-on-primary text-[#a58103] italic;
}

a.word-search {
@apply text-inherit;
}

.w {
@apply text-inherit not-italic;
}

.w.highlight {
@apply p-0 bg-inherit text-red-600;
}
</style>
105 changes: 105 additions & 0 deletions components/profile-window-content.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<script lang="ts" setup>
interface Props {
params: ProfileWindowItem["params"];
}

const props = defineProps<Props>();
const { params } = toRefs(props);

const { data, isPending, isPlaceholderData } = useProfileById(params);
const openNewWindowFromAnchor = useAnchorClickHandler();

const isLoading = computed(() => {
return isPending.value || isPlaceholderData.value;
});
</script>

<template>
<div
class="relative isolate grid h-full w-full overflow-auto"
:class="{ 'opacity-50 grayscale': isLoading }"
>
<!-- eslint-disable-next-line vue/no-v-html, vuejs-accessibility/click-events-have-key-events, vuejs-accessibility/no-static-element-interactions -->
<div v-if="data" class="prose max-w-3xl p-8" @click="openNewWindowFromAnchor" v-html="data" />

<Centered v-if="isLoading">
<LoadingIndicator />
</Centered>
</div>
</template>

<style>
/* stylelint-disable selector-class-pattern */

.tbProfile {
@apply border border-solid border-[#59533c];
}

.tdHead {
@apply align-top w-[150px] pr-[5px] border-dotted border-primary border-b bg-primary text-on-primary text-right break-words;
}

.tdProfileTableRight {
@apply align-top pl-[5px] border-dotted border-primary border-b bg-[#dedede] text-primary;
}

.aExplBar {
@apply bg-transparent text-[#252771] no-underline cursor-pointer;
}

.aExplBar:hover {
@apply underline cursor-pointer;
}

.aVicText {
@apply bg-transparent text-primary no-underline cursor-pointer;
}

.aVicText:hover {
@apply bg-primary text-on-primary cursor-pointer;
}

.info-block-wrap > .aVicText {
@apply text-[#335175];
}

a:hover {
@apply text-[#252771] underline;
}

.spTeiLink {
@apply py-[5px] px-2 border-solid border-primary border rounded-[5px] font-medium text-xs transition-all duration-300 ease-in-out;
}

.spTeiLink:hover {
@apply bg-primary text-on-primary no-underline;
}

.tbHeader {
@apply w-full m-0;
}

.profileHeader {
@apply flex gap-[3%] items-start;
}

.pNorm {
@apply mb-[10px];
}

.imgCaption {
@apply pb-2 italic text-xs text-center;
}

.h3ProfileTypology {
@apply mt-4 mb-1 border-b-0 font-medium text-[1.2rem];
}

.h3Profile {
@apply mt-4 mb-1 border-dotted border-primary border-b font-medium text-[1.2rem];
}

.dvImgProfile {
@apply order-1;
}
</style>
4 changes: 2 additions & 2 deletions components/text-window-content.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const props = defineProps<Props>();
const { params } = toRefs(props);

const { data, isPending, isPlaceholderData } = useTextById(params);
const onClick = useAnchorClickHandler();
const openNewWindowFromAnchor = useAnchorClickHandler();

const isLoading = computed(() => {
return isPending.value || isPlaceholderData.value;
Expand All @@ -20,7 +20,7 @@ const isLoading = computed(() => {
:class="{ 'opacity-50 grayscale': isLoading }"
>
<!-- eslint-disable-next-line vue/no-v-html, vuejs-accessibility/click-events-have-key-events, vuejs-accessibility/no-static-element-interactions -->
<div v-if="data" class="prose max-w-3xl p-8" @click="onClick" v-html="data" />
<div v-if="data" class="prose max-w-3xl p-8" @click="openNewWindowFromAnchor" v-html="data" />

<Centered v-if="isLoading">
<LoadingIndicator />
Expand Down
2 changes: 2 additions & 0 deletions components/window-content.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ const props = defineProps<Props>();
<template>
<GeoMapWindowContent v-if="props.item.kind === 'geo-map'" :params="props.item.params" />
<TextWindowContent v-else-if="props.item.kind === 'text'" :params="props.item.params" />
<ProfileWindowContent v-else-if="props.item.kind === 'profile'" :params="props.item.params" />
<FeatureWindowContent v-else-if="props.item.kind === 'feature'" :params="props.item.params" />
<pre v-else>{{ props }}</pre>
</template>
4 changes: 2 additions & 2 deletions composables/use-anchor-click-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function useAnchorClickHandler() {
/**
* Intercept anchor clicks to open window instead of navigating.
*/
function onClick(event: MouseEvent) {
function openNewWindowFromAnchor(event: MouseEvent) {
const element = event.target;

if (element instanceof HTMLAnchorElement) {
Expand All @@ -31,5 +31,5 @@ export function useAnchorClickHandler() {
}
}

return onClick;
return openNewWindowFromAnchor;
}
16 changes: 16 additions & 0 deletions composables/use-feature-by-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useQuery } from "@tanstack/vue-query";

export function useFeatureById(params: MaybeRef<{ id: string }>, options?: { enabled?: boolean }) {
const api = useApiClient();

return useQuery({
enabled: options?.enabled,
queryKey: ["get-feature-by-id", params] as const,
async queryFn({ queryKey: [, params] }) {
const response = await api.vicav.getLingFeature(params, {
headers: { accept: "application/xml" },
});
return response.text();
},
});
}
16 changes: 16 additions & 0 deletions composables/use-profile-by-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useQuery } from "@tanstack/vue-query";

export function useProfileById(params: MaybeRef<{ id: string }>, options?: { enabled?: boolean }) {
const api = useApiClient();

return useQuery({
enabled: options?.enabled,
queryKey: ["get-profile-by-id", params] as const,
async queryFn({ queryKey: [, params] }) {
const response = await api.vicav.getProfile(params, {
headers: { accept: "application/xml" },
});
return response.text();
},
});
}
16 changes: 16 additions & 0 deletions stores/use-windows-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ export interface TextWindowItem extends WindowItemBase {
};
}

export interface ProfileWindowItem extends WindowItemBase {
kind: "profile";
params: {
id: string;
};
}

export interface FeatureWindowItem extends WindowItemBase {
kind: "feature";
params: {
id: string;
};
}

export type WindowItem =
| BibliographyQueryWindowItem
| CorpusQueryWindowItem
Expand All @@ -74,7 +88,9 @@ export type WindowItem =
| DataListWindowItem
| DictionaryEntryWindowItem
| DictionaryQueryWindowItem
| FeatureWindowItem
| GeoMapWindowItem
| ProfileWindowItem
| SampleTextWindowItem
| TextWindowItem;

Expand Down
2 changes: 2 additions & 0 deletions utils/is-window-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export const windowTypeMap: Record<WindowType, WindowItemKind> = {
SampleText: "sample-text",
Text: "text",
WMap: "geo-map",
Profile: "profile",
Feature: "feature",
};

export function isWindowType(value: string | undefined): value is WindowType {
Expand Down
Loading