Skip to content

Commit

Permalink
81 create feature component (#96)
Browse files Browse the repository at this point in the history
feature lists working
  • Loading branch information
ctot-nondef authored Dec 5, 2023
2 parents 0b9ec21 + 7596a57 commit 6a28c10
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 4 deletions.
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

0 comments on commit 6a28c10

Please sign in to comment.