Skip to content

Commit

Permalink
MIR-1419-Can't edit author in publication and related item in same xe…
Browse files Browse the repository at this point in the history
…ditor

- also use mods index and relatedItem index in name attribute to identify input elements, to prevent confusion with name index
  • Loading branch information
sebhofmann committed Jan 15, 2025
1 parent 03d931f commit 87e36cc
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 41 deletions.
48 changes: 26 additions & 22 deletions mir-webapp/src/main/vue/name-search/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div ref="root" class="form-group" v-on-click-outside="closeDrops">
<template v-if="model.i18nLoaded && model.classesLoaded">
<div ref="input" class="input-group">
<input :id="`personLabel-${model.nameIndex}`" ref="searchBox" v-model="model.search" :placeholder="model.personPlaceholder"
<input :id="`personLabel-${model.nameLocator}`" ref="searchBox" v-model="model.search" :placeholder="model.personPlaceholder"
class="form-control" type="text"
v-on:keydown.enter.prevent="startSearch()">
<div class="input-group-append">
Expand All @@ -11,7 +11,7 @@
<i class="fas fa-address-card"></i>
<span class="identifier-count">{{ model.currentIdentifier.length }}</span>
</button>
<button :id="`search-${model.nameIndex}`" class="btn btn-secondary" type="button"
<button :id="`search-${model.nameLocator}`" class="btn btn-secondary" type="button"
v-on:click.prevent="startSearch()">
{{ model.searchLabel }}
</button>
Expand Down Expand Up @@ -113,13 +113,13 @@
import {Identifier, NameSearchResult, SearchProviderRegistry} from "@/api/SearchProvider";
import {
findNameIndex,
retrieveDisplayName,
retrieveIdentifiers,
retrieveIsPerson,
storeIdentifiers,
storeIsPerson,
storeName
findNameLocator, NameLocator,
retrieveDisplayName,
retrieveIdentifiers,
retrieveIsPerson,
storeIdentifiers,
storeIsPerson,
storeName
} from "@/api/XEditorConnector";
import {LobidSearchProvider} from "@/api/LobidSearchProvider";
import {ViafSearchProvider} from "@/api/ViafSearchProvider";
Expand Down Expand Up @@ -149,7 +149,7 @@ const props = defineProps<
>()
const model = reactive({
nameIndex: undefined as number | undefined,
nameLocator: undefined as (NameLocator | undefined),
search: "",
isPerson: true as boolean,
results: [] as Array<{ name: string; searching: boolean, nameList: NameSearchResult[] }>,
Expand All @@ -174,21 +174,21 @@ const isDevMode = () => {
}
watch(() => model.currentIdentifier, (val) => {
if (!isDevMode() && model.nameIndex !== undefined) {
storeIdentifiers(model.nameIndex, model.currentIdentifier);
if (!isDevMode() && model.nameLocator !== undefined) {
storeIdentifiers(model.nameLocator, model.currentIdentifier);
}
}, {deep: true});
watch(() => model.search, (val) => {
if (!isDevMode() && model.nameIndex !== undefined) {
storeName(model.nameIndex, model.search);
if (!isDevMode() && model.nameLocator !== undefined) {
storeName(model.nameLocator, model.search);
}
}, {deep: true});
watch(() => model.isPerson, (val) => {
if (!isDevMode() && model.nameIndex !== undefined) {
storeIsPerson(model.nameIndex, model.isPerson);
if (!isDevMode() && model.nameLocator !== undefined) {
storeIsPerson(model.nameLocator, model.isPerson);
}
}, {deep: true});
Expand Down Expand Up @@ -241,10 +241,14 @@ const loadLanguage = async () => {
const initializeXEditorConnection = async () => {
if (!isDevMode() && root.value instanceof Element) {
model.nameIndex = findNameIndex(root.value);
model.search = retrieveDisplayName(model.nameIndex);
model.currentIdentifier = retrieveIdentifiers(model.nameIndex);
model.isPerson = retrieveIsPerson(model.nameIndex);
model.nameLocator = findNameLocator(root.value);
if(model.nameLocator === undefined) {
console.error("Name locator not found");
return;
}
model.search = retrieveDisplayName(model.nameLocator);
model.currentIdentifier = retrieveIdentifiers(model.nameLocator);
model.isPerson = retrieveIsPerson(model.nameLocator);
}
}
Expand Down Expand Up @@ -336,7 +340,7 @@ const getGroupSize = () => {
return (input.value instanceof HTMLElement ? input.value.clientWidth : 0);
}
const addIdentifier = async (identifier: Identifier, event?: PointerEvent) => {
const addIdentifier = async (identifier: Identifier, event?: MouseEvent) => {
// if the function is caused by user action, we do a fancy animation
if (event) {
const clickTarget = event.currentTarget as HTMLElement;
Expand Down Expand Up @@ -372,7 +376,7 @@ const removeIdentifier = (identifier: Identifier) => {
model.currentIdentifier.splice(number, 1);
}
const applyName = async (name: NameSearchResult, event: PointerEvent) => {
const applyName = async (name: NameSearchResult, event: MouseEvent) => {
const clickTarget = event.currentTarget as HTMLElement;
const clickParent = clickTarget.parentElement?.parentElement;
const resultTitle = (clickParent?.querySelector(".result-title") as HTMLElement | undefined);
Expand Down
74 changes: 55 additions & 19 deletions mir-webapp/src/main/vue/name-search/src/api/XEditorConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,57 @@

import {Identifier} from "@/api/SearchProvider";

export function findNameIndex(anyElement: Element): number {
export interface NameLocator {
modsIndex: number;
relatedItemIndex?: number;
nameIndex: number;
}

export function findNameLocator(anyElement: Element): NameLocator | undefined {
for (const child of anyElement.children) {
if (child instanceof HTMLInputElement) {
const match = child.name.match(/.*mods:name\[(\d+)\].*/);
const match = child.name.match(/(mods:mods\[(?<modsIndex>[\d+])\]\/)?(mods:relatedItem\[(?<relatedItemIndex>[\d+])\]\/)?mods:name\[(?<nameIndex>\d+)\].*/);
if (match != null && match.length > 0) {
return parseInt(match[1]);
const relatedItemGroup = match?.groups?.relatedItemIndex;
const modsGroup = match?.groups?.modsIndex;
const nameGroup = match?.groups?.nameIndex || "1";
if (!nameGroup) {
console.error("Name index not found in name locator");
return undefined;
}
if(!modsGroup){
console.error("Mods index not found in name locator");
return undefined;
}
return {
relatedItemIndex: relatedItemGroup ? parseInt(relatedItemGroup) : undefined,
modsIndex: parseInt(modsGroup),
nameIndex: parseInt(nameGroup)
}
}
}
}

if (anyElement.parentElement) {
return findNameIndex(anyElement.parentElement);
return findNameLocator(anyElement.parentElement);
} else {
return -1;
return undefined;
}
}

export function retrieveDisplayName(nameIndex: number): string {
const input = document.querySelector(`[name*="mods:name[${nameIndex}]/mods:displayForm"]`) as HTMLInputElement;
export function retrieveDisplayName(nameLocator: NameLocator): string {
const {relatedItemIndex, nameIndex} = nameLocator;
let riPart = relatedItemIndex ? `mods:relatedItem[${relatedItemIndex}]/`: "";
let modsPart = nameLocator.modsIndex ? `mods:mods[${nameLocator.modsIndex}]/` : "";
const input = document.querySelector(`[name*="${modsPart}${riPart}mods:name[${nameIndex}]/mods:displayForm"]`) as HTMLInputElement;
return input.value;
}

export function retrieveIsPerson(nameIndex: number): boolean {
const input = document.querySelector(`[name*="mods:name[${nameIndex}]/@type"]`);
export function retrieveIsPerson(nameLocator: NameLocator): boolean {
const {relatedItemIndex, nameIndex} = nameLocator;
let riPart = relatedItemIndex ? `mods:relatedItem[${relatedItemIndex}]/`: "";
let modsPart = nameLocator.modsIndex ? `mods:mods[${nameLocator.modsIndex}]/` : "";
const input = document.querySelector(`[name*="${modsPart}${riPart}mods:name[${nameIndex}]/@type"]`);
if(input instanceof HTMLInputElement || input instanceof HTMLSelectElement){
if(input.value == "personal"){
return true;
Expand All @@ -53,21 +80,27 @@ export function retrieveIsPerson(nameIndex: number): boolean {
}
}

export function storeName(nameIndex: number, name: string) {
const input = document.querySelector(`[name*="mods:name[${nameIndex}]/mods:displayForm"]`) as HTMLInputElement;
export function storeName(nameLocator: NameLocator, name: string) {
const {relatedItemIndex, nameIndex} = nameLocator;
let riPart = relatedItemIndex ? `mods:relatedItem[${relatedItemIndex}]/`: "";
let modsPart = nameLocator.modsIndex ? `mods:mods[${nameLocator.modsIndex}]/` : "";
const input = document.querySelector(`[name*="${modsPart}${riPart}mods:name[${nameIndex}]/mods:displayForm"]`) as HTMLInputElement;
input.value = name;
}

export function storeIsPerson(nameIndex:number, isPerson: boolean) {
const input = document.querySelector(`[name*="mods:name[${nameIndex}]/@type"]`);
export function storeIsPerson(nameLocator: NameLocator, isPerson: boolean) {
const {relatedItemIndex, nameIndex} = nameLocator;
let riPart = relatedItemIndex ? `mods:relatedItem[${relatedItemIndex}]/`: "";
let modsPart = nameLocator.modsIndex ? `mods:mods[${nameLocator.modsIndex}]/` : "";
const input = document.querySelector(`[name*="${modsPart}${riPart}mods:name[${nameIndex}]/@type"]`);

if(input instanceof HTMLInputElement || input instanceof HTMLSelectElement){
input.value = isPerson ? "personal" : "corporate";
}
}

export function storeIdentifiers(nameIndex: number, identifiers: Identifier[]) {
const {typeMap, identifierMap} = retrieveElementMaps(nameIndex);
export function storeIdentifiers(nameLocator: NameLocator, identifiers: Identifier[]) {
const {typeMap, identifierMap} = retrieveElementMaps(nameLocator);
console.log(["storeIdentifiers ", typeMap, identifierMap, identifiers])
Object.keys(identifierMap).map(key => parseInt(key)).sort().forEach(index => {
identifierMap[index].value = "";
Expand All @@ -80,8 +113,8 @@ export function storeIdentifiers(nameIndex: number, identifiers: Identifier[]) {
}
}

export function retrieveIdentifiers(nameIndex: number): Identifier[] {
const elementMaps = retrieveElementMaps(nameIndex);
export function retrieveIdentifiers(nameLocator: NameLocator): Identifier[] {
const elementMaps = retrieveElementMaps(nameLocator);

return Object.keys(elementMaps.identifierMap)
.map(key => parseInt(key))
Expand All @@ -93,8 +126,11 @@ export function retrieveIdentifiers(nameIndex: number): Identifier[] {
}).filter(identifier => identifier.type != "" && identifier.value != "");
}

export function retrieveElementMaps(nameIndex: number) {
const elements = document.querySelectorAll(`[name*="mods:name[${nameIndex}]/mods:nameIdentifier"]`);
export function retrieveElementMaps(nameLocator: NameLocator) {
const {relatedItemIndex, nameIndex} = nameLocator;
let riPart = relatedItemIndex ? `mods:relatedItem[${relatedItemIndex}]/`: "";
let modsPart = nameLocator.modsIndex ? `mods:mods[${nameLocator.modsIndex}]/` : "";
const elements = document.querySelectorAll(`[name*="${modsPart}${riPart}mods:name[${nameIndex}]/mods:nameIdentifier"]`);
const typeMap: Record<number, HTMLInputElement> = {};
const identifierMap: Record<number, HTMLInputElement> = {};

Expand Down

0 comments on commit 87e36cc

Please sign in to comment.