import { type BCMSEntryLite, BCMSJwtRoleName, type BCMSLanguage, type BCMSMedia, BCMSPropType, type BCMSTemplate, type BCMSUserPolicyTemplate, } from '@becomes/cms-sdk/types'; import { computed, defineComponent, onBeforeUpdate, onMounted, onUnmounted, type PropType, ref, } from 'vue'; import BCMSTimestampDisplay from '../timestamp-display'; import BCMSLink from '../link'; import BCMSIcon from '../icon'; import { BCMSOverflowMenu, BCMSOverflowMenuItem } from '../overflow'; import { BCMSEmptyState, BCMSImage } from '..'; import { useTranslation } from '../../translations'; import type { BCMSWhereIsItUsedItem } from '../../types'; const CHUNK_SIZE = 10; const component = defineComponent({ props: { template: { type: Object as PropType, required: true }, entries: { type: Array as PropType, required: true }, lng: String, visibleLanguage: { type: Object as PropType<{ data: BCMSLanguage; index: number }>, required: true, }, policy: { type: Object as PropType, required: true, }, }, emits: { remove: (_: BCMSEntryLite) => { return true; }, duplicate: (_: BCMSEntryLite) => { return true; }, }, setup(props, ctx) { const translations = computed(() => { return useTranslation(); }); let visibleChunks = 1; const showToIndex = ref(CHUNK_SIZE); let tidBuffer = ''; const store = window.bcms.vue.store; const entries = computed(() => { if (props.entries.length === 0) { return []; } const template = store.getters.template_findOne( (e) => e._id === props.entries[0].templateId, ); return props.entries.map((entry) => { let status = ''; if (entry.status) { const fullStatus = store.getters.status_findOne( (e) => e._id === entry.status, ); if (fullStatus) { status = fullStatus.label; } } let imageId: string | undefined; let subtitle: string | undefined; let meta = entry.meta.find((e) => e.lng === props.lng); if (!meta) { meta = entry.meta[0]; } if (template) { for (let i = 2; i < meta.props.length; i++) { const prop = meta.props[i]; const tProp = template.props.find((e) => e.id === prop.id); if (tProp && prop.data) { if ( tProp.type === BCMSPropType.MEDIA && (prop.data as BCMSMedia[])[0] ) { imageId = (prop.data as BCMSMedia[])[0]._id; } else if (tProp.type === BCMSPropType.STRING) { subtitle = (prop.data as string[])[0]; } } } } return { ...entry, title: (meta.props[0].data as string[])[0], image: store.getters.media_findOne((e) => e._id === imageId), subtitle, status, }; }); }); const hasData = computed(() => { return { image: !!entries.value.find((e) => e.image), status: !!entries.value.find((e) => e.status), }; }); function loadMore() { visibleChunks++; showToIndex.value = visibleChunks * CHUNK_SIZE; } function onScroll(event: Event) { const el = event.target as HTMLBodyElement; if ( showToIndex.value < props.entries.length && el.scrollTop + window.innerHeight === el.scrollHeight ) { loadMore(); } } async function whereIsUsed(data: { eid: string; tid: string; title: string; }) { await window.bcms.util.throwable( async () => { const result = await window.bcms.sdk.entry.whereIsItUsed({ templateId: data.tid, entryId: data.eid, }); const user = await window.bcms.sdk.user.get(); const policy = user.customPool.policy; const items: BCMSWhereIsItUsedItem[] = []; for (let i = 0; i < result.length; i++) { const item = result[i]; if ( user.roles[0].name === BCMSJwtRoleName.ADMIN || policy.templates.find((e) => e._id === item.tid) ) { const template = await window.bcms.sdk.template.get(item.tid); const entry = await window.bcms.sdk.entry.getLite({ templateId: item.tid, entryId: item.eid, }); items.push({ type: 'entry', label: template.label, id: entry.cid, template: { id: template.cid, label: template.label, }, linkText: (entry.meta[0].props[0].data as string[])[0], }); } } return items; }, async (items) => { window.bcms.modal.whereIsItUsed.show({ colsVisible: { label: true, location: true, }, title: translations.value.modal.whereIsItUsed.groupTitle({ label: data.title, }), items, }); }, ); } document.body.addEventListener('scroll', onScroll); onMounted(() => { tidBuffer = props.template._id; }); onBeforeUpdate(() => { if (tidBuffer !== props.template._id) { tidBuffer = props.template._id; visibleChunks = 1; showToIndex.value = CHUNK_SIZE; document.body.scrollTo({ top: 0 }); } }); onUnmounted(() => { document.body.removeEventListener('scroll', onScroll); }); return () => ( <> {props.entries.length > 0 ? ( <>
  • {hasData.value.image ?
    : ''}
    {translations.value.page.entries.table.createdAt}
    {translations.value.page.entries.table.updatedAt}
    {hasData.value.status ? (
    {translations.value.page.entries.table.status}
    ) : ( '' )}
    {translations.value.page.entries.table.title}
  • {entries.value.map((entryLite, entryLiteIndex) => { if (entryLiteIndex > showToIndex.value) { return ''; } return (
  • {hasData.value.image ? (
    {entryLite.image ? ( ) : ( '' )}
    ) : ( '' )}
    {hasData.value.status ? (
    {entryLite.status || ''}
    ) : ( '' )}
    {entryLite.title} {entryLite.subtitle ? (
    {entryLite.subtitle .split(' ') .map((e) => { if (e.length > 20) { return ( e.slice(0, 10) + '[...]' + e.slice(e.length - 10, e.length) ); } }) .join(' ')}
    ) : ( '' )}
    {props.policy.put ? translations.value.page.entries.table.edit : translations.value.page.entries.table.view} {props.policy.post && props.policy.put ? ( { ctx.emit('duplicate', entryLite); }} /> ) : ( '' )} { window.bcms.modal.entry.viewModel.show({ templateId: entryLite.templateId, entryId: entryLite._id, }); }} /> { whereIsUsed({ eid: entryLite._id, tid: entryLite.templateId, title: entryLite.title, }); }} /> {props.policy.delete ? ( { ctx.emit('remove', entryLite); }} /> ) : ( '' )}
  • ); })}
) : ( )} ); }, }); export default component;