Upgraded dependencies, bumped to Node 24.
This commit is contained in:
@@ -1,235 +1,6 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div
|
||||
v-if="context === 'admin'"
|
||||
class="revs-header"
|
||||
>
|
||||
<Checkbox
|
||||
label="Show finalized"
|
||||
:checked="showReviewed"
|
||||
@change="(checked) => { showReviewed = checked; reloadRevisions(); }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ul
|
||||
class="revs nolist"
|
||||
:class="{ [`revs-${context}`]: true }"
|
||||
>
|
||||
<li
|
||||
v-for="rev in curatedRevisions"
|
||||
:key="`rev-${rev.id}`"
|
||||
class="rev"
|
||||
:class="{
|
||||
reviewed: reviewedRevisions.has(rev.id),
|
||||
expanded: context === 'admin' || expanded.has(rev.id)
|
||||
}"
|
||||
>
|
||||
<template v-if="context === 'admin' || expanded.has(rev.id)">
|
||||
<div class="rev-header">
|
||||
<a
|
||||
:href="`/${domain.slice(0, -1)}/${rev.sceneId || rev.actorId}/${rev.base.slug}`"
|
||||
target="_blank"
|
||||
class="rev-link rev-scene nolink noshrink"
|
||||
>{{ rev.sceneId || rev.actorId }}@{{ rev.hash.slice(0, 6) }}</a>
|
||||
|
||||
<a
|
||||
:href="`/${domain.slice(0, -1)}/${rev.sceneId || rev.actorId}/${rev.base.slug}`"
|
||||
target="_blank"
|
||||
class="rev-link rev-title nolink ellipsis"
|
||||
>{{ rev.base.title || rev.base.name }}</a>
|
||||
|
||||
<div class="rev-details noshrink">
|
||||
<a
|
||||
v-if="rev.user"
|
||||
:href="`/user/${rev.user.username}`"
|
||||
target="_blank"
|
||||
class="rev-username nolink"
|
||||
>{{ rev.user.username }}</a>
|
||||
|
||||
<time
|
||||
:datetime="rev.createdAt"
|
||||
class="rev-created"
|
||||
>{{ format(rev.createdAt, 'yyyy-MM-dd hh:mm') }}</time>
|
||||
</div>
|
||||
|
||||
<div class="rev-actions noshrink">
|
||||
<span
|
||||
v-if="rev.review && context === 'admin'"
|
||||
class="approved"
|
||||
:class="{ rejected: !rev.review.isApproved }"
|
||||
>{{ rev.review.isApproved ? 'Approved' : 'Rejected' }} by <a
|
||||
:href="`/user/${rev.review.username}`"
|
||||
target="_blank"
|
||||
class="nolink"
|
||||
>{{ rev.review.username }}</a> {{ format(rev.review.reviewedAt, 'yyyy-MM-dd hh:mm') }}</span>
|
||||
|
||||
<template v-else-if="context === 'admin'">
|
||||
<Icon
|
||||
v-tooltip="`Ban user from submitting revisions`"
|
||||
icon="user-block"
|
||||
class="review-reject review-ban"
|
||||
@click="banEditor(rev)"
|
||||
/>
|
||||
|
||||
<Icon
|
||||
v-tooltip="`Reject revision`"
|
||||
icon="blocked"
|
||||
class="review-reject"
|
||||
@click="reviewRevision(rev, false)"
|
||||
/>
|
||||
|
||||
<input
|
||||
v-model="feedbacks[rev.id]"
|
||||
placeholder="Feedback"
|
||||
class="input"
|
||||
>
|
||||
|
||||
<Icon
|
||||
v-tooltip="`Approve and apply revision`"
|
||||
icon="checkmark"
|
||||
class="review-approve"
|
||||
@click="reviewRevision(rev, true)"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="rev-deltas">
|
||||
<li
|
||||
v-for="(delta, index) in rev.deltas"
|
||||
:key="`delta-${rev.id}-${index}`"
|
||||
class="delta"
|
||||
>
|
||||
<span class="delta-key ellipsis">{{ delta.key }}</span>
|
||||
|
||||
<div class="delta-deltas">
|
||||
<span class="delta-from delta-value">
|
||||
<Socials
|
||||
v-if="delta.key === 'socials'"
|
||||
:rev="rev"
|
||||
:index="index"
|
||||
:socials="rev.base[delta.key]"
|
||||
/>
|
||||
|
||||
<ul
|
||||
v-else-if="Array.isArray(rev.base[delta.key])"
|
||||
class="nolist"
|
||||
>[
|
||||
<li
|
||||
v-for="item in rev.base[delta.key]"
|
||||
:key="`item-${rev.id}-${index}-${item.id}`"
|
||||
class="delta-item"
|
||||
:class="{ modified: item.modified }"
|
||||
>{{ item.name || item.id || item }}</li> ]
|
||||
</ul>
|
||||
|
||||
<Avatar
|
||||
v-else-if="delta.key === 'avatar'"
|
||||
:avatar="avatarsById[rev.base[delta.key]]"
|
||||
class="delta-avatar"
|
||||
/>
|
||||
|
||||
<template v-else-if="rev.base[delta.key] instanceof Date">{{ format(rev.base[delta.key], 'yyyy-MM-dd hh:mm') }}</template>
|
||||
<template v-else>{{ rev.base[delta.key] }}</template>
|
||||
</span>
|
||||
|
||||
<span class="delta-arrow">⇒</span>
|
||||
|
||||
<span class="delta-to delta-value">
|
||||
<Socials
|
||||
v-if="delta.key === 'socials'"
|
||||
:rev="rev"
|
||||
:index="index"
|
||||
:socials="delta.value"
|
||||
/>
|
||||
|
||||
<ul
|
||||
v-else-if="Array.isArray(delta.value)"
|
||||
class="nolist"
|
||||
>[
|
||||
<li
|
||||
v-for="item in delta.value"
|
||||
:key="`item-${rev.id}-${index}-${item.id}`"
|
||||
class="delta-item"
|
||||
:class="{ modified: item.modified }"
|
||||
>{{ item.name || item.id || item }}</li> ]
|
||||
</ul>
|
||||
|
||||
<Avatar
|
||||
v-else-if="delta.key === 'avatar'"
|
||||
:avatar="avatarsById[delta.value]"
|
||||
class="delta-avatar"
|
||||
/>
|
||||
|
||||
<template v-else-if="delta.value instanceof Date">{{ format(delta.value, 'yyyy-MM-dd hh:mm') }}</template>
|
||||
<template v-else>{{ delta.value }}</template>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div
|
||||
v-if="rev.comment"
|
||||
class="rev-comment"
|
||||
>
|
||||
{{ rev.comment }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="rev-compact"
|
||||
@click="expanded.add(rev.id)"
|
||||
>
|
||||
|
||||
<span class="rev-scene nolink noshrink"><template v-if="context !== 'scene' && context !== 'actor'">{{ rev.sceneId || rev.actorId }}</template>@{{ rev.hash.slice(0, 6) }}</span>
|
||||
|
||||
<span
|
||||
v-if="context !== 'scene'"
|
||||
class="rev-title nolink ellipsis"
|
||||
>{{ rev.base.title }}</span>
|
||||
|
||||
<span class="rev-summary">
|
||||
<span class="summary-deltas ellipsis">{{ rev.deltas.map((delta) => delta.key).join(', ') }}</span>
|
||||
|
||||
<span
|
||||
v-if="rev.comment"
|
||||
class="summary-comment ellipsis"
|
||||
>{{ rev.comment }}</span>
|
||||
</span>
|
||||
|
||||
<div class="rev-details noshrink">
|
||||
<a
|
||||
v-if="rev.user && context !== 'user'"
|
||||
:href="`/user/${rev.user.username}`"
|
||||
target="_blank"
|
||||
class="rev-username nolink ellipsis"
|
||||
@click.stop
|
||||
>{{ rev.user.username }}</a>
|
||||
|
||||
<a
|
||||
v-if="rev.user && context !== 'user'"
|
||||
v-tooltip="rev.user.username"
|
||||
:href="`/user/${rev.user.username}`"
|
||||
target="_blank"
|
||||
class="rev-avatar nolink ellipsis"
|
||||
@click.stop
|
||||
><Icon icon="user3-long" /></a>
|
||||
|
||||
<time
|
||||
:datetime="rev.createdAt"
|
||||
class="rev-created"
|
||||
>{{ format(rev.createdAt, 'yyyy-MM-dd hh:mm') }}</time>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, inject } from 'vue';
|
||||
import { format } from 'date-fns';
|
||||
import { computed, inject, ref } from 'vue';
|
||||
|
||||
import Avatar from '#/components/edit/avatar.vue';
|
||||
import Socials from '#/components/edit/revision-socials.vue';
|
||||
@@ -410,7 +181,8 @@ async function reviewRevision(revision, isApproved) {
|
||||
});
|
||||
|
||||
revisions.value = revisions.value.map((rev) => (rev.id === updatedRevision.revision.id ? updatedRevision.revision : rev));
|
||||
} catch (error) {
|
||||
}
|
||||
catch (error) {
|
||||
reviewedRevisions.value.delete(revision.id);
|
||||
}
|
||||
}
|
||||
@@ -425,6 +197,235 @@ async function banEditor(revision) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page">
|
||||
<div
|
||||
v-if="context === 'admin'"
|
||||
class="revs-header"
|
||||
>
|
||||
<Checkbox
|
||||
label="Show finalized"
|
||||
:checked="showReviewed"
|
||||
@change="(checked) => { showReviewed = checked; reloadRevisions(); }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ul
|
||||
class="revs nolist"
|
||||
:class="{ [`revs-${context}`]: true }"
|
||||
>
|
||||
<li
|
||||
v-for="rev in curatedRevisions"
|
||||
:key="`rev-${rev.id}`"
|
||||
class="rev"
|
||||
:class="{
|
||||
reviewed: reviewedRevisions.has(rev.id),
|
||||
expanded: context === 'admin' || expanded.has(rev.id),
|
||||
}"
|
||||
>
|
||||
<template v-if="context === 'admin' || expanded.has(rev.id)">
|
||||
<div class="rev-header">
|
||||
<a
|
||||
:href="`/${domain.slice(0, -1)}/${rev.sceneId || rev.actorId}/${rev.base.slug}`"
|
||||
target="_blank"
|
||||
class="rev-link rev-scene nolink noshrink"
|
||||
>{{ rev.sceneId || rev.actorId }}@{{ rev.hash.slice(0, 6) }}</a>
|
||||
|
||||
<a
|
||||
:href="`/${domain.slice(0, -1)}/${rev.sceneId || rev.actorId}/${rev.base.slug}`"
|
||||
target="_blank"
|
||||
class="rev-link rev-title nolink ellipsis"
|
||||
>{{ rev.base.title || rev.base.name }}</a>
|
||||
|
||||
<div class="rev-details noshrink">
|
||||
<a
|
||||
v-if="rev.user"
|
||||
:href="`/user/${rev.user.username}`"
|
||||
target="_blank"
|
||||
class="rev-username nolink"
|
||||
>{{ rev.user.username }}</a>
|
||||
|
||||
<time
|
||||
:datetime="rev.createdAt"
|
||||
class="rev-created"
|
||||
>{{ format(rev.createdAt, 'yyyy-MM-dd hh:mm') }}</time>
|
||||
</div>
|
||||
|
||||
<div class="rev-actions noshrink">
|
||||
<span
|
||||
v-if="rev.review && context === 'admin'"
|
||||
class="approved"
|
||||
:class="{ rejected: !rev.review.isApproved }"
|
||||
>{{ rev.review.isApproved ? 'Approved' : 'Rejected' }} by <a
|
||||
:href="`/user/${rev.review.username}`"
|
||||
target="_blank"
|
||||
class="nolink"
|
||||
>{{ rev.review.username }}</a> {{ format(rev.review.reviewedAt, 'yyyy-MM-dd hh:mm') }}</span>
|
||||
|
||||
<template v-else-if="context === 'admin'">
|
||||
<Icon
|
||||
v-tooltip="{ content: 'Ban user from submitting revisions', ariaId: `rev-ban-${rev.id}` }"
|
||||
icon="user-block"
|
||||
class="review-reject review-ban"
|
||||
@click="banEditor(rev)"
|
||||
/>
|
||||
|
||||
<Icon
|
||||
v-tooltip="{ content: 'Reject revision', ariaId: `rev-reject-${rev.id}` }"
|
||||
icon="blocked"
|
||||
class="review-reject"
|
||||
@click="reviewRevision(rev, false)"
|
||||
/>
|
||||
|
||||
<input
|
||||
v-model="feedbacks[rev.id]"
|
||||
placeholder="Feedback"
|
||||
class="input"
|
||||
>
|
||||
|
||||
<Icon
|
||||
v-tooltip="{ content: 'Approve and apply revision', ariaId: `rev-approve-${rev.id}` }"
|
||||
icon="checkmark"
|
||||
class="review-approve"
|
||||
@click="reviewRevision(rev, true)"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="rev-deltas">
|
||||
<li
|
||||
v-for="(delta, index) in rev.deltas"
|
||||
:key="`delta-${rev.id}-${index}`"
|
||||
class="delta"
|
||||
>
|
||||
<span class="delta-key ellipsis">{{ delta.key }}</span>
|
||||
|
||||
<div class="delta-deltas">
|
||||
<span class="delta-from delta-value">
|
||||
<Socials
|
||||
v-if="delta.key === 'socials'"
|
||||
:rev="rev"
|
||||
:index="index"
|
||||
:socials="rev.base[delta.key]"
|
||||
/>
|
||||
|
||||
<ul
|
||||
v-else-if="Array.isArray(rev.base[delta.key])"
|
||||
class="nolist"
|
||||
>[
|
||||
<li
|
||||
v-for="item in rev.base[delta.key]"
|
||||
:key="`item-${rev.id}-${index}-${item.id}`"
|
||||
class="delta-item"
|
||||
:class="{ modified: item.modified }"
|
||||
>{{ item.name || item.id || item }}</li> ]
|
||||
</ul>
|
||||
|
||||
<Avatar
|
||||
v-else-if="delta.key === 'avatar'"
|
||||
:avatar="avatarsById[rev.base[delta.key]]"
|
||||
class="delta-avatar"
|
||||
/>
|
||||
|
||||
<template v-else-if="rev.base[delta.key] instanceof Date">{{ format(rev.base[delta.key], 'yyyy-MM-dd hh:mm') }}</template>
|
||||
<template v-else>{{ rev.base[delta.key] }}</template>
|
||||
</span>
|
||||
|
||||
<span class="delta-arrow">⇒</span>
|
||||
|
||||
<span class="delta-to delta-value">
|
||||
<Socials
|
||||
v-if="delta.key === 'socials'"
|
||||
:rev="rev"
|
||||
:index="index"
|
||||
:socials="delta.value"
|
||||
/>
|
||||
|
||||
<ul
|
||||
v-else-if="Array.isArray(delta.value)"
|
||||
class="nolist"
|
||||
>[
|
||||
<li
|
||||
v-for="item in delta.value"
|
||||
:key="`item-${rev.id}-${index}-${item.id}`"
|
||||
class="delta-item"
|
||||
:class="{ modified: item.modified }"
|
||||
>{{ item.name || item.id || item }}</li> ]
|
||||
</ul>
|
||||
|
||||
<Avatar
|
||||
v-else-if="delta.key === 'avatar'"
|
||||
:avatar="avatarsById[delta.value]"
|
||||
class="delta-avatar"
|
||||
/>
|
||||
|
||||
<template v-else-if="delta.value instanceof Date">{{ format(delta.value, 'yyyy-MM-dd hh:mm') }}</template>
|
||||
<template v-else>{{ delta.value }}</template>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div
|
||||
v-if="rev.comment"
|
||||
class="rev-comment"
|
||||
>
|
||||
{{ rev.comment }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="rev-compact"
|
||||
@click="expanded.add(rev.id)"
|
||||
>
|
||||
|
||||
<span class="rev-scene nolink noshrink"><template v-if="context !== 'scene' && context !== 'actor'">{{ rev.sceneId || rev.actorId }}</template>@{{ rev.hash.slice(0, 6) }}</span>
|
||||
|
||||
<span
|
||||
v-if="context !== 'scene'"
|
||||
class="rev-title nolink ellipsis"
|
||||
>{{ rev.base.title }}</span>
|
||||
|
||||
<span class="rev-summary">
|
||||
<span class="summary-deltas ellipsis">{{ rev.deltas.map((delta) => delta.key).join(', ') }}</span>
|
||||
|
||||
<span
|
||||
v-if="rev.comment"
|
||||
class="summary-comment ellipsis"
|
||||
>{{ rev.comment }}</span>
|
||||
</span>
|
||||
|
||||
<div class="rev-details noshrink">
|
||||
<a
|
||||
v-if="rev.user && context !== 'user'"
|
||||
:href="`/user/${rev.user.username}`"
|
||||
target="_blank"
|
||||
class="rev-username nolink ellipsis"
|
||||
@click.stop
|
||||
>{{ rev.user.username }}</a>
|
||||
|
||||
<a
|
||||
v-if="rev.user && context !== 'user'"
|
||||
v-tooltip="{ content: rev.user.username, ariaId: `rev-user-${rev.id}` }"
|
||||
:href="`/user/${rev.user.username}`"
|
||||
target="_blank"
|
||||
class="rev-avatar nolink ellipsis"
|
||||
@click.stop
|
||||
><Icon icon="user3-long" /></a>
|
||||
|
||||
<time
|
||||
:datetime="rev.createdAt"
|
||||
class="rev-created"
|
||||
>{{ format(rev.createdAt, 'yyyy-MM-dd hh:mm') }}</time>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.page {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user