app/javascript/vue/tasks/uniquify/people/components/CompareTable.vue
<template>
<div>
<div class="horizontal-left-content align-start">
<div class="column-buttons">
<h2> </h2>
<div class="horizontal-left-content">
<button
type="button"
class="button normal-input button-default separate-right"
:disabled="!(selected.id && selectedMergePerson.id)"
@click="flipPeople"
>
Flip
</button>
<ConfirmationModal ref="confirmationModal" />
<button
class="button normal-input button-submit"
@click="sendMerge"
:disabled="isMergeEmpty"
>
Merge people
</button>
</div>
</div>
<div class="title-person">
<h2>Selected person</h2>
<template v-if="selectedEmpty">
<p>This person will remain.</p>
</template>
</div>
<div class="title-merge">
<h2>Person to merge</h2>
<template v-if="!isMergeEmpty">
<p data-icon="warning">This person(s) will be deleted.</p>
<switch-component
v-model="personIndex"
use-index
:options="peopleList"
/>
</template>
</div>
</div>
<table>
<tbody>
<tr v-if="selected.id">
<td />
<td>
<div class="horizontal-left-content gap-small">
<a
target="_blank"
:href="`/people/${selected.id}`"
>
{{ selected.cached }}
</a>
<template v-if="selected.global_id">
<RadialAnnotator :global-id="selected.global_id" />
<RadialNavigation
:global-id="selected.global_id"
:redirect="false"
@delete="
() => store.dispatch(ActionNames.RemovePerson, selected)
"
/>
</template>
</div>
</td>
<td>
<div class="horizontal-left-content gap-small">
<a
target="_blank"
:href="`/people/${selectedMergePerson.id}`"
>
{{ selectedMergePerson.cached }}
</a>
<template v-if="selectedMergePerson.global_id">
<RadialAnnotator :global-id="selectedMergePerson.global_id" />
<RadialNavigation
:global-id="selectedMergePerson.global_id"
:redirect="false"
@delete="
() =>
store.dispatch(
ActionNames.RemovePerson,
selectedMergePerson
)
"
/>
</template>
</div>
</td>
</tr>
<template
v-for="(value, key, index) in selected"
:key="key"
>
<tr
v-if="!isNestedProperty(value)"
class="contextMenuCells"
:class="{
even: index % 2 == 0,
repeated:
value !== selectedMergePerson[key] && selectedMergePerson[key]
}"
>
<td
class="column-property"
v-text="humanizeValue(key)"
/>
<td
class="column-person"
v-html="humanizeValue(value)"
/>
<td
class="column-merge"
v-html="humanizeValue(selectedMergePerson[key])"
/>
</tr>
</template>
</tbody>
</table>
<TableGrid
:columns="2"
:gap="12"
>
<div>
<table-person-roles
v-show="selected.id"
title="Selected role types"
:person="selected"
/>
<table-annotations
:person="selected"
title="Selected annotations"
/>
</div>
<div>
<table-person-roles
v-show="selectedMergePerson.id"
title="Merge role types"
:person="selectedMergePerson"
/>
<table-annotations
:person="selectedMergePerson"
title="Merge annotations"
/>
</div>
</TableGrid>
</div>
</template>
<script setup>
import { computed, ref } from 'vue'
import { capitalize, humanize } from '@/helpers/strings'
import { GetterNames } from '../store/getters/getters'
import { ActionNames } from '../store/actions/actions'
import { useStore } from 'vuex'
import TableAnnotations from './Table/TableAnnotations.vue'
import TablePersonRoles from './Table/TableDescription.vue'
import RadialAnnotator from '@/components/radials/annotator/annotator'
import RadialNavigation from '@/components/radials/navigation/radial.vue'
import SwitchComponent from '@/components/ui/VSwitch'
import ConfirmationModal from '@/components/ConfirmationModal.vue'
import TableGrid from '@/components/layout/Table/TableGrid.vue'
const confirmationModal = ref(null)
const personIndex = ref(0)
const store = useStore()
const selected = computed(() => store.getters[GetterNames.GetSelectedPerson])
const selectedEmpty = computed(() => Object.keys(selected.value).length > 0)
const isMergeEmpty = computed(() => mergeList.value.length === 0)
const mergeList = computed(() => store.getters[GetterNames.GetMergePeople])
const peopleList = computed(() => mergeList.value.map((p) => p.cached))
const selectedMergePerson = computed(
() => mergeList.value[personIndex.value] || {}
)
function isNestedProperty(value) {
return Array.isArray(value) || (typeof value === 'object' && value != null)
}
async function sendMerge() {
const confirmed = await confirmationModal.value.show({
title: 'Merge people',
message: 'This will merge all selected match people to selected person.',
okButton: 'Merge',
confirmationWord: 'merge',
cancelButton: 'Cancel',
typeButton: 'submit'
})
if (confirmed) {
store.dispatch(ActionNames.ProcessMerge)
}
}
function humanizeValue(value) {
return capitalize(humanize(value))
}
function flipPeople() {
store.dispatch(ActionNames.FlipPeople, personIndex.value)
}
</script>
<style lang="scss" scoped>
.repeated {
color: red;
}
.no-difference {
display: none;
}
.column-property {
min-width: 105px;
}
.column-buttons {
min-width: 136px;
}
.column-person,
.column-merge {
min-width: 250px;
}
.title-merge,
.title-person {
min-width: 250px;
padding-left: 1em;
padding-right: 1em;
}
.circle-info-project {
border-radius: 50%;
width: 24px;
height: 24px;
}
.nulled {
background-color: #e5d2be;
}
.in-project {
background-color: #5d9ece;
}
.no-in-project {
background-color: #c38a8a;
}
</style>