{"version":3,"file":"usePresentationItem-DcU-SVms.mjs","names":[],"sources":["../src/components/layouts/PresentationItem.vue","../src/components/layouts/PresentationItem.vue","../src/components/composable/usePresentationItem.ts"],"sourcesContent":["<!--\n  Component to display an element with its description\n-->\n<template>\n    <article\n        class=\"classic-element-container item-presentation-container mt-3\"\n        :class=\"vertical ? 'vertical-item' : ''\"\n    >\n        <router-link\n            :to=\"route\"\n            class=\"d-flex-column flex-grow-1 text-dark\"\n            :class=\"vertical ? 'flex-column' : ''\"\n        >\n            <div\n                class=\"img-box\"\n                :class=\"vertical ? 'img-box-bigger' : ''\"\n            >\n                <img\n                    v-lazy=\"useProxyImageUrl(imageUrl, tailleImage)\"\n                    :width=\"tailleImage\"\n                    :height=\"tailleImage\"\n                    aria-hidden=\"true\"\n                    :alt=\"name\"\n                    :title=\"name\"\n                >\n\n                <div class=\"tags\">\n                    <span\n                        v-for=\"tag in tags\"\n                        :key=\"tag\"\n                    >\n                        {{ tag }}\n                    </span>\n                </div>\n\n                <slot name=\"after-image\" />\n            </div>\n      \n            <div\n                class=\"classic-element-text pb-0\"\n                :class=\"{ 'pt-1': vertical }\"\n            >\n                <div class=\"element-name mb-2 basic-line-clamp\">\n                    {{ name }}\n                </div>\n                <div\n                    v-if=\"!isPhone && (description || additionalInfo)\"\n                    ref=\"descriptionItemContainer\"\n                    class=\"element-description htms-wysiwyg-content mt-0\"\n                >\n                    <div v-if=\"additionalInfo\" class=\"mb-2\">\n                        <div\n                            v-for=\"info, index in additionalInfo\"\n                            :key=\"index\"\n                            class=\"text-secondary\"\n                        >\n                            {{ info }}\n                        </div>\n                    </div>\n                    <!-- eslint-disable vue/no-v-html -->\n                    <div\n                        v-if=\"description\"\n                        ref=\"descriptionItem\"\n                        v-html=\"urlify(description || '')\"\n                    />\n                    <!-- eslint-enable -->\n                </div>\n            </div>\n        </router-link>\n    </article>\n</template>\n\n<script setup lang=\"ts\">\nimport {useResizePhone} from \"../composable/useResizePhone\";\nimport {useImageProxy} from \"../composable/useImageProxy\";\nimport displayHelper from \"../../helper/displayHelper\";\nimport { nextTick, useTemplateRef, watch, computed } from \"vue\";\nimport { RouteLocationRaw } from \"vue-router\";\n\n//Props \nconst props = defineProps<{\n    /** The route to which to redirect when clicking on element */\n    route: RouteLocationRaw|string;\n    /** The URL to the image */\n    imageUrl: string;\n    /** The name of the element */\n    name: string;\n    /** Tags associated with the element (rubriques, themes, etc) */\n    tags?: Array<string>;\n    /** Additional info displayed below name */\n    additionalInfo?: Array<string>;\n    /** The description of the element */\n    description?: string;\n    /** When true display the card vertically */\n    vertical?: boolean;\n}>();\n\n//Data\nconst descriptionItemRef = useTemplateRef('descriptionItem');\nconst descriptionItemContainerRef = useTemplateRef('descriptionItemContainer');\n\n\n//Composables\nconst { isPhone } = useResizePhone();\nconst { useProxyImageUrl } = useImageProxy();\n\n// Computed\n// Calcul de la taille de l'image\nconst tailleImage = computed(() => {\n    // L'élément fait 400 de large à la verticale, mais on prend en compte les bordures\n    if (props.vertical) {\n        return '396';\n    } else if (isPhone.value) {\n        return '246';\n    } else {\n        return '250';\n    }\n});\n\n//Watch\nwatch(isPhone, async () => {\n    nextTick(() => {\n        if (!props.description || isPhone.value) {\n            return;\n        }\n        const itemDesc = descriptionItemRef?.value as HTMLElement;\n        const itemDescContainer = descriptionItemContainerRef?.value as HTMLElement;\n        if (\n            itemDesc &&\n            itemDescContainer &&\n            itemDesc.clientHeight > itemDescContainer.clientHeight\n        ) {\n            itemDescContainer.classList.add(\"after-element-description\");\n        }\n    });\n}, { immediate: true });\n\nfunction urlify(text:string|undefined){\n    return displayHelper.urlify(text);\n}\n</script>\n\n<style scoped lang=\"scss\">\n.octopus-app {\n    .item-presentation-container {\n        @media (width <= 960px) {\n            width: 250px !important;\n            margin-right: 0.5rem;\n        }\n\n        .element-description {\n            height: 0;\n            flex-grow: 1;\n            max-height: unset;\n\n            p:first-child {\n                // Prevent unecessary space before first paragraph\n                margin-top: 0 !important;\n            }\n        }\n    }\n\n    .classic-element-container.vertical-item {\n        flex-grow: 0;\n        width: 400px;\n        flex-shrink: 0;\n    }\n\n    .img-box {\n        // Make it relative so that absolute elements associated with the image\n        // are positioned within the image box\n        position: relative;\n\n        @media (width <= 960px) {\n            height: calc(var(--octopus-image-size) - 4);\n        }\n    }\n\n    .img-box-bigger {\n        // L'élément fait 400 de large à la verticale, mais on prend en compte les bordures\n        width: 396px;\n        height: 396px;\n    }\n\n    .tags {\n        position: absolute;\n        top: 10px;\n        left: 10px;\n\n        display: flex;\n        gap: 10px;\n        flex-wrap: wrap;\n\n        > span {\n            background-color: white;\n            padding: .25em .75em;\n            font-size: 14px;\n            font-weight: bold;\n            color: var(--octopus-primary);\n            border-radius: var(--octopus-border-radius);\n            border: 1px solid color-mix(in lch, var(--octopus-primary), transparent 60%);\n\n            // Limit width\n            max-width: 200px;\n            overflow: hidden;\n            white-space: nowrap;\n            text-overflow: ellipsis;\n        }\n    }\n}\n</style>\n","<!--\n  Component to display an element with its description\n-->\n<template>\n    <article\n        class=\"classic-element-container item-presentation-container mt-3\"\n        :class=\"vertical ? 'vertical-item' : ''\"\n    >\n        <router-link\n            :to=\"route\"\n            class=\"d-flex-column flex-grow-1 text-dark\"\n            :class=\"vertical ? 'flex-column' : ''\"\n        >\n            <div\n                class=\"img-box\"\n                :class=\"vertical ? 'img-box-bigger' : ''\"\n            >\n                <img\n                    v-lazy=\"useProxyImageUrl(imageUrl, tailleImage)\"\n                    :width=\"tailleImage\"\n                    :height=\"tailleImage\"\n                    aria-hidden=\"true\"\n                    :alt=\"name\"\n                    :title=\"name\"\n                >\n\n                <div class=\"tags\">\n                    <span\n                        v-for=\"tag in tags\"\n                        :key=\"tag\"\n                    >\n                        {{ tag }}\n                    </span>\n                </div>\n\n                <slot name=\"after-image\" />\n            </div>\n      \n            <div\n                class=\"classic-element-text pb-0\"\n                :class=\"{ 'pt-1': vertical }\"\n            >\n                <div class=\"element-name mb-2 basic-line-clamp\">\n                    {{ name }}\n                </div>\n                <div\n                    v-if=\"!isPhone && (description || additionalInfo)\"\n                    ref=\"descriptionItemContainer\"\n                    class=\"element-description htms-wysiwyg-content mt-0\"\n                >\n                    <div v-if=\"additionalInfo\" class=\"mb-2\">\n                        <div\n                            v-for=\"info, index in additionalInfo\"\n                            :key=\"index\"\n                            class=\"text-secondary\"\n                        >\n                            {{ info }}\n                        </div>\n                    </div>\n                    <!-- eslint-disable vue/no-v-html -->\n                    <div\n                        v-if=\"description\"\n                        ref=\"descriptionItem\"\n                        v-html=\"urlify(description || '')\"\n                    />\n                    <!-- eslint-enable -->\n                </div>\n            </div>\n        </router-link>\n    </article>\n</template>\n\n<script setup lang=\"ts\">\nimport {useResizePhone} from \"../composable/useResizePhone\";\nimport {useImageProxy} from \"../composable/useImageProxy\";\nimport displayHelper from \"../../helper/displayHelper\";\nimport { nextTick, useTemplateRef, watch, computed } from \"vue\";\nimport { RouteLocationRaw } from \"vue-router\";\n\n//Props \nconst props = defineProps<{\n    /** The route to which to redirect when clicking on element */\n    route: RouteLocationRaw|string;\n    /** The URL to the image */\n    imageUrl: string;\n    /** The name of the element */\n    name: string;\n    /** Tags associated with the element (rubriques, themes, etc) */\n    tags?: Array<string>;\n    /** Additional info displayed below name */\n    additionalInfo?: Array<string>;\n    /** The description of the element */\n    description?: string;\n    /** When true display the card vertically */\n    vertical?: boolean;\n}>();\n\n//Data\nconst descriptionItemRef = useTemplateRef('descriptionItem');\nconst descriptionItemContainerRef = useTemplateRef('descriptionItemContainer');\n\n\n//Composables\nconst { isPhone } = useResizePhone();\nconst { useProxyImageUrl } = useImageProxy();\n\n// Computed\n// Calcul de la taille de l'image\nconst tailleImage = computed(() => {\n    // L'élément fait 400 de large à la verticale, mais on prend en compte les bordures\n    if (props.vertical) {\n        return '396';\n    } else if (isPhone.value) {\n        return '246';\n    } else {\n        return '250';\n    }\n});\n\n//Watch\nwatch(isPhone, async () => {\n    nextTick(() => {\n        if (!props.description || isPhone.value) {\n            return;\n        }\n        const itemDesc = descriptionItemRef?.value as HTMLElement;\n        const itemDescContainer = descriptionItemContainerRef?.value as HTMLElement;\n        if (\n            itemDesc &&\n            itemDescContainer &&\n            itemDesc.clientHeight > itemDescContainer.clientHeight\n        ) {\n            itemDescContainer.classList.add(\"after-element-description\");\n        }\n    });\n}, { immediate: true });\n\nfunction urlify(text:string|undefined){\n    return displayHelper.urlify(text);\n}\n</script>\n\n<style scoped lang=\"scss\">\n.octopus-app {\n    .item-presentation-container {\n        @media (width <= 960px) {\n            width: 250px !important;\n            margin-right: 0.5rem;\n        }\n\n        .element-description {\n            height: 0;\n            flex-grow: 1;\n            max-height: unset;\n\n            p:first-child {\n                // Prevent unecessary space before first paragraph\n                margin-top: 0 !important;\n            }\n        }\n    }\n\n    .classic-element-container.vertical-item {\n        flex-grow: 0;\n        width: 400px;\n        flex-shrink: 0;\n    }\n\n    .img-box {\n        // Make it relative so that absolute elements associated with the image\n        // are positioned within the image box\n        position: relative;\n\n        @media (width <= 960px) {\n            height: calc(var(--octopus-image-size) - 4);\n        }\n    }\n\n    .img-box-bigger {\n        // L'élément fait 400 de large à la verticale, mais on prend en compte les bordures\n        width: 396px;\n        height: 396px;\n    }\n\n    .tags {\n        position: absolute;\n        top: 10px;\n        left: 10px;\n\n        display: flex;\n        gap: 10px;\n        flex-wrap: wrap;\n\n        > span {\n            background-color: white;\n            padding: .25em .75em;\n            font-size: 14px;\n            font-weight: bold;\n            color: var(--octopus-primary);\n            border-radius: var(--octopus-border-radius);\n            border: 1px solid color-mix(in lch, var(--octopus-primary), transparent 60%);\n\n            // Limit width\n            max-width: 200px;\n            overflow: hidden;\n            white-space: nowrap;\n            text-overflow: ellipsis;\n        }\n    }\n}\n</style>\n","import { Emission } from \"@/stores/class/general/emission\";\nimport { state } from \"../../stores/ParamSdkStore\";\nimport { useGeneralStore } from \"../../stores/GeneralStore\";\nimport { Podcast } from \"../../stores/class/general/podcast\";\nimport { rubriquesApi } from \"../../api\";\nimport { useDayjs } from \"./useDayjs\";\nimport { unique } from \"@/helper/arrayHelper\";\n\nexport const usePresentationItem = () => {\n    const generalStore = useGeneralStore();\n    const { formatDate } = useDayjs();\n\n    function iabTags(emission: Emission): Array<string> {\n        return generalStore.storedCategories\n            .filter(cat => emission.iabIds.includes(cat.id))\n            .map(cat => cat.name);\n    }\n\n    async function rubriqueTags(element: Podcast|Emission, filterRubriquageId?: number): Promise<Array<string>> {\n        const rubriqueIds: Array<number> = [];\n        if (element.rubriqueIds) {\n            rubriqueIds.push(...element.rubriqueIds);\n        }\n        if ('emission' in element && element.emission.rubriqueIds) {\n            rubriqueIds.push(...element.emission.rubriqueIds);\n        }\n        const uniqueRubriqueIds = rubriqueIds.filter(unique);\n        const promises = uniqueRubriqueIds.map(rubriquesApi.getCachedRubrique);\n        const rubriques = await Promise.all(promises);\n\n        if (filterRubriquageId) {\n            return rubriques.filter(r => r.rubriquageId === filterRubriquageId).map(r => r.name);\n        } else {\n            return rubriques.map(r => r.name);\n        }\n    }\n    \n    async function tagsFor(element: Podcast|Emission): Promise<Array<string>|undefined> {\n        const type = state.presentationItems.tags;\n        let tags: Array<string>|undefined = undefined;\n        if (type === 'iab') {\n            const emission = 'emission' in element ? element.emission : element;\n            tags = iabTags(emission);\n        } else if (type === 'rubrique') {\n            tags = await rubriqueTags(element, state.presentationItems.tagsRubriquageId);\n        }\n\n        if (tags && state.presentationItems.tagsLimit) {\n            return tags.slice(0, state.presentationItems.tagsLimit);\n        }\n\n        return tags;\n    }\n\n    async function additionalInfoFor(element: Podcast|Emission): Promise<Array<string>|undefined> {\n        const prop = state.presentationItems.additionalInfo;\n        const restrictiveRubriquageId = state.presentationItems.restrictiveRubriquageId;\n        if (!prop?.length) {\n            return undefined;\n        }\n\n        const podcast = 'emission' in element ? element : null;\n        const emission = podcast?.emission ?? element as Emission;\n\n        const result = await Promise.all(prop.map(async property => {\n            if (property === 'date') {\n                if (podcast?.pubDate) {\n                    return formatDate(podcast.pubDate);\n                } else {\n                    return null;\n                }\n            } else if (property === 'productor') {\n                return emission.orga.name;\n            } else if (property === 'restrictive-rubrique' && restrictiveRubriquageId !== undefined) {\n                const rubriques = await rubriqueTags(element, restrictiveRubriquageId);\n                return rubriques.join(', ');\n            }\n            return null;\n        }));\n\n        return result.filter(p => p !== null);\n    }\n\n    return { tagsFor, additionalInfoFor };\n};\n"],"mappings":"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"}