{"version":3,"file":"NewCollectionButton.vue_vue_type_script_setup_true_lang-DQquihr8.js","sources":["../../../ui/src/components/collections/CollectionCatalogListColumns.vue","../../../ui/src/components/collections/CollectionKebabMenu.vue","../../../ui/src/components/collections/CollectionCatalogListItem.vue","../../../ui/src/components/collections/CollectionCatalogList.vue","../../../ui/src/components/collections/CollectionCatalogGridCard.vue","../../../ui/src/components/collections/CollectionCatalog.vue","../../../ui/src/components/buttons/NewCollectionButton.vue"],"sourcesContent":["<template>\n <div class=\"flex flex-wrap items-center gap-4 py-4 pl-5 pr-4 sm:py-0.5\">\n <div class=\"min-w-0 flex-[2]\">\n <slot name=\"title\" />\n </div>\n\n <div class=\"min-w-0 flex-[5] max-sm:order-last max-sm:w-full max-sm:flex-none\">\n <slot name=\"description\" />\n </div>\n\n <div class=\"min-w-0 max-sm:self-start max-sm:pt-1 sm:flex-[2]\">\n <slot name=\"count\" />\n </div>\n\n <!-- Hidden on mobile -->\n <div class=\"hidden w-28 text-right sm:block\">\n <slot name=\"modified\" />\n </div>\n\n <div class=\"w-5 min-w-0 max-sm:-translate-y-1 max-sm:self-start\">\n <slot name=\"menu\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { MenuButton, MenuItem, MenuItems } from '@headlessui/vue';\nimport { useCollectionsStore } from '~/stores/collections-store';\nimport type { Collection } from '~/utilities/pyscript-api-models';\nimport DropdownMenu from '~/components/DropdownMenu.vue';\nimport IconMenu from '~icons/carbon/overflow-menu-vertical';\nimport IconTrashCan from '~icons/carbon/trash-can';\nimport IconPencil from '~icons/mdi/pencil-outline';\n\ndefineProps<{\n collection: Collection;\n}>();\n\nconst collectionsStore = useCollectionsStore();\n</script>\n\n<template>\n <DropdownMenu>\n <template #button>\n <MenuButton\n class=\"rounded-full p-1 text-sm text-new-gray-800 outline-none transition-colors hover:bg-new-gray-100/50 dark:text-new-gray-100\"\n aria-label=\"Menu\"\n >\n <IconMenu aria-hidden=\"true\" class=\"shrink-0 text-lg\" />\n </MenuButton>\n </template>\n\n <template #menu>\n <MenuItems class=\"three-dot-menu__panel --right min-w-[8rem]\">\n <MenuItem>\n <button\n class=\"three-dot-menu__item-btn\"\n @click=\"collectionsStore.openCollectionModal(collection)\"\n >\n <IconPencil aria-hidden=\"true\" class=\"text-sm\" />\n <span\n class=\"three-dot-menu__item-text\"\n :data-content=\"$t('buttons.edit')\"\n v-text=\"$t('buttons.edit')\"\n />\n </button>\n </MenuItem>\n\n <MenuItem>\n <button\n class=\"three-dot-menu__item-btn hover:!bg-error-600 hover:text-white\"\n @click=\"collectionsStore.deleteCollection(collection.id)\"\n >\n <IconTrashCan aria-hidden=\"true\" class=\"text-sm\" />\n <span\n class=\"three-dot-menu__item-text\"\n :data-content=\"$t('buttons.delete')\"\n v-text=\"$t('buttons.delete')\"\n />\n </button>\n </MenuItem>\n </MenuItems>\n </template>\n </DropdownMenu>\n</template>\n\n<style scoped lang=\"postcss\"></style>\n","<script lang=\"ts\" setup>\nimport { computed } from 'vue';\nimport { formatTimeAgo } from '@vueuse/core';\nimport CollectionCatalogListColumns from '~/components/collections/CollectionCatalogListColumns.vue';\nimport CollectionKebabMenu from '~/components/collections/CollectionKebabMenu.vue';\nimport type { Collection } from '~/utilities/pyscript-api-models';\nimport { useUserStore } from '~/stores/user-store';\nimport { useCollectionsStore } from '~/stores/collections-store';\nimport IconLock from '~icons/material-symbols/lock';\n\nconst props = defineProps<{\n collection: Collection;\n lastItem: boolean;\n}>();\n\ndefineEmits<{\n (e: 'collectionDeleted', value: Collection): void;\n (e: 'collectionUpdated', value: Collection): void;\n}>();\n\nconst userStore = useUserStore();\nconst collectionsStore = useCollectionsStore();\n\nconst isCollectionOwner = computed(() => {\n if (!userStore.isLoggedIn) return false;\n return userStore.user?.id === props.collection.user_id;\n});\n\nconst lastEdited = computed(() => {\n return formatTimeAgo(new Date(props.collection.updated_at));\n});\n</script>\n\n<template>\n <CollectionCatalogListColumns\n class=\"group relative block px-2 text-13 hover:bg-new-gray-50 hover:dark:bg-new-gray-900\"\n :class=\"[lastItem ? 'rounded-b' : 'border-b border-new-gray-50 dark:border-new-gray-950/60']\"\n >\n <template #title>\n <div class=\"flex items-center gap-2\">\n <router-link\n :to=\"{\n name: 'collection-projects',\n params: {\n collectionId: collection.id,\n usernameOrUserId: collection.username || collection.user_id,\n },\n }\"\n class=\"truncate text-sm font-medium before:absolute before:inset-0 before:block\"\n >\n {{ collection.name }}\n </router-link>\n\n <IconLock\n v-if=\"collection.private\"\n v-tooltip=\"{\n placement: 'bottom',\n content: 'Private Project',\n }\"\n class=\"shrink-0 text-xs text-new-blue-400\"\n />\n </div>\n\n <div class=\"truncate text-xs text-black/60 dark:text-white/60 sm:hidden sm:text-13\">\n {{ lastEdited }}\n </div>\n </template>\n\n <template #description>\n <div class=\"text-black/60 dark:text-white/60\">\n <button\n v-if=\"!collection.description && isCollectionOwner\"\n class=\"relative italic hover:underline\"\n @click=\"collectionsStore.openCollectionModal(collection)\"\n >\n Add a description...\n </button>\n\n <p v-else class=\"line-clamp-3 sm:line-clamp-none sm:truncate\">{{\n collection.description\n }}</p>\n </div>\n </template>\n\n <template #count>\n <span\n class=\"block text-nowrap text-right text-xs text-black/60 dark:text-white/60 sm:text-left\"\n >{{ $t('collections.project_count', collection.projects.length) }}</span\n >\n </template>\n\n <template #modified>\n <p class=\"truncate px-1 text-right\">\n <span class=\"leading-tight text-black/60 dark:text-white/60\">{{ lastEdited }}</span>\n </p>\n </template>\n\n <template #menu>\n <CollectionKebabMenu\n :collection=\"collection\"\n @collection-deleted=\"$emit('collectionDeleted', $event)\"\n @collection-updated=\"$emit('collectionUpdated', $event)\"\n />\n </template>\n </CollectionCatalogListColumns>\n</template>\n","<script setup lang=\"ts\">\nimport CollectionCatalogListColumns from '~/components/collections/CollectionCatalogListColumns.vue';\nimport type { Collection } from '~/utilities/pyscript-api-models';\nimport CollectionCatalogListItem from '~/components/collections/CollectionCatalogListItem.vue';\nimport { useSortPreference } from '~/composables/sort-preference';\nimport IconChevronDown from '~icons/carbon/chevron-down';\n\ndefineProps<{\n collectionList: Collection[];\n}>();\n\ndefineEmits<{\n (e: 'collectionDeleted', value: Collection): void;\n (e: 'collectionUpdated', value: Collection): void;\n}>();\n\nconst { updateSort, savedSort } = useSortPreference();\n</script>\n\n<template>\n <TransitionGroup\n tag=\"section\"\n name=\"collections-list-slide\"\n class=\"relative rounded border border-new-gray-100/70 bg-white dark:border-new-gray-950/60 dark:bg-gray-675\"\n >\n <div\n class=\"hidden border-b border-new-gray-50 py-2 text-sm font-medium dark:border-new-gray-950/60 sm:block\"\n >\n <CollectionCatalogListColumns>\n <template #title>\n <button\n class=\"flex w-full items-center gap-2 hover:underline\"\n @click=\"\n updateSort({\n sortBy: 'name',\n sortOrder: savedSort.sortOrder === 'desc' ? 'asc' : 'desc',\n })\n \"\n >\n <span>Title</span>\n <IconChevronDown\n class=\"shrink-0 text-13\"\n :class=\"[\n savedSort.sortBy === 'name' && savedSort.sortOrder === 'asc' ? 'rotate-180' : '',\n savedSort.sortBy === 'name' ? '' : 'opacity-0',\n ]\"\n />\n </button>\n </template>\n\n <template #description>\n <span class=\"cursor-default\">Description</span>\n </template>\n\n <template #count>\n <span class=\"cursor-default\">Count</span>\n </template>\n\n <template #modified>\n <button\n class=\"flex w-full items-center justify-end gap-2 hover:underline\"\n @click=\"\n updateSort({\n sortBy: 'updated_at',\n sortOrder: savedSort.sortOrder === 'desc' ? 'asc' : 'desc',\n })\n \"\n >\n <span class=\"whitespace-nowrap\">Last Modified</span>\n <IconChevronDown\n class=\"-mr-5 shrink-0 text-13\"\n :class=\"[\n savedSort.sortBy === 'updated_at' && savedSort.sortOrder === 'asc'\n ? 'rotate-180'\n : '',\n savedSort.sortBy === 'updated_at' ? '' : 'opacity-0',\n ]\"\n />\n </button>\n </template>\n </CollectionCatalogListColumns>\n </div>\n\n <CollectionCatalogListItem\n v-for=\"(collection, index) of collectionList\"\n :key=\"collection.id\"\n :collection=\"collection\"\n :last-item=\"index === collectionList.length - 1\"\n @collection-deleted=\"$emit('collectionDeleted', $event)\"\n @collection-updated=\"$emit('collectionUpdated', $event)\"\n />\n </TransitionGroup>\n</template>\n\n<style lang=\"postcss\" scoped>\n/* Only add animations if the user doesn't prefer reduced motion. */\n@media (prefers-reduced-motion: no-preference) {\n .collections-list-slide {\n &-move,\n &-enter-active,\n &-leave-active {\n transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);\n }\n\n &-enter-from,\n &-leave-to {\n opacity: 0;\n transform: scaleY(0.01) translate(30px, 0);\n }\n\n &-leave-active {\n position: absolute;\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { Collection } from '~/utilities/pyscript-api-models';\nimport CollectionKebabMenu from '~/components/collections/CollectionKebabMenu.vue';\nimport { useUserStore } from '~/stores/user-store';\nimport IconLock from '~icons/material-symbols/lock';\nimport { useCollectionsStore } from '~/stores/collections-store';\n\nconst props = defineProps<{\n collection: Collection;\n}>();\n\nconst userStore = useUserStore();\nconst collectionsStore = useCollectionsStore();\n\nconst isCollectionOwner = computed(() => {\n if (!userStore.isLoggedIn) return false;\n return userStore.user?.id === props.collection.user_id;\n});\n</script>\n\n<template>\n <div class=\"group relative block pb-1\">\n <div\n class=\"absolute -bottom-1 top-0 w-full rounded border border-new-gray-100 bg-white dark:border-new-gray-950/80 dark:bg-gray-675\"\n />\n <div\n class=\"absolute -bottom-0 top-0 w-full rounded border border-new-gray-100/90 bg-white dark:border-new-gray-950/80 dark:bg-gray-675\"\n />\n\n <div\n class=\"relative flex h-full flex-col rounded rounded-br-[32px] border border-new-gray-100/80 bg-white p-5 transition-shadow group-hover:border-new-gray-100 group-hover:shadow-lg dark:border-new-gray-950/80 dark:bg-gray-675 group-hover:dark:border-new-gray-400\"\n >\n <router-link\n :to=\"{\n name: 'collection-projects',\n params: {\n collectionId: collection.id,\n usernameOrUserId: collection.username || collection.user_id,\n },\n }\"\n class=\"mb-2 w-full truncate pr-4 text-sm font-semibold before:absolute before:inset-[0_0_-8px_0] before:block\"\n >\n {{ collection.name }}\n </router-link>\n\n <CollectionKebabMenu\n v-if=\"isCollectionOwner\"\n :collection=\"collection\"\n class=\"absolute right-2.5 top-4\"\n />\n\n <div class=\"mt-1 h-[3lh] text-sm text-new-gray-600 dark:text-new-gray-400\">\n <button\n v-if=\"!collection.description && isCollectionOwner\"\n class=\"relative italic hover:underline\"\n @click=\"collectionsStore.openCollectionModal(collection)\"\n >\n Add a description...\n </button>\n <p class=\"line-clamp-3\">\n {{ collection.description }}\n </p>\n </div>\n\n <div\n class=\"mt-4 flex items-center gap-1 text-xs font-medium text-new-gray-500 dark:text-new-gray-300\"\n >\n <IconLock v-if=\"collection.private\" class=\"inline-block shrink-0 text-new-blue-400\" />\n\n <span>{{ $t('collections.project_count', collection.projects.length) }}</span>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped lang=\"postcss\"></style>\n","<script setup lang=\"ts\">\nimport { useListGridViewPreference } from '~/composables/list-grid-view-preference';\nimport type { Collection } from '~/utilities/pyscript-api-models';\nimport CollectionCatalogList from '~/components/collections/CollectionCatalogList.vue';\nimport CollectionCatalogGrid from '~/components/collections/CollectionCatalogGrid.vue';\n\ndefineProps<{\n collections: Collection[];\n}>();\n\nconst { savedView } = useListGridViewPreference();\n</script>\n\n<template>\n <CollectionCatalogGrid v-if=\"savedView === 'grid'\" :collections=\"collections\" />\n\n <CollectionCatalogList v-else :collection-list=\"collections\" />\n</template>\n","<script setup lang=\"ts\">\nimport { useCollectionsStore } from '~/stores/collections-store';\nimport IconAdd from '~icons/carbon/add';\n\nconst collectionsStore = useCollectionsStore();\n</script>\n\n<template>\n <button\n class=\"btn --primary --space-sm inline-flex items-center gap-2 text-sm\"\n @click=\"() => collectionsStore.openCollectionModal()\"\n >\n <IconAdd class=\"-mx-1.5 text-base\" />\n <span>\n {{ $t('states.no_items_created.button_text', { noun: $t('states.noun.collections', 1) }) }}\n </span>\n </button>\n</template>\n\n<style scoped lang=\"postcss\"></style>\n"],"names":["_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_sfc_render","_ctx","_cache","_openBlock","_createElementBlock","_hoisted_6","collectionsStore","useCollectionsStore","props","__props","userStore","useUserStore","isCollectionOwner","computed","_a","lastEdited","formatTimeAgo","updateSort","savedSort","useSortPreference","savedView","useListGridViewPreference"],"mappings":"keAESA,GAAA,CAAA,MAAM,4DAAkB,EAIxBC,GAAA,CAAA,MAAM,kBAAmE,EAIzEC,GAAA,CAAA,MAAM,mEAAmD,EAKzDC,GAAA,CAAA,MAAM,mDAAiC,EAIvCC,GAAA,CAAA,MAAM,iCAAqD,mEAlBlE,SAAAC,GAAAC,EAAAC,EAAA,CACE,OAAAC,EAAA,EAEMC,EAAA,MAAAT,GAAA,GADiB,MAAAC,GAAA,oBAGvB,CAAA,IAC6B,MAAAC,GAAA,0BAG7B,CAAA,IACuB,MAAAC,GAAA,oBAIvB,CAAA,IAC0B,MAAAC,GAAA,uBAG1B,CAAA,IACsB,MAAAM,GAAA,sZCP1B,MAAMC,EAAmBC,mnDCHzB,MAAMC,EAAQC,EAURC,EAAYC,IACZL,EAAmBC,IAEnBK,EAAoBC,EAAS,IAAM,OACvC,OAAKH,EAAU,aACRI,EAAAJ,EAAU,OAAV,YAAAI,EAAgB,MAAON,EAAM,WAAW,QADb,EACa,CAChD,EAEKO,EAAaF,EAAS,IACnBG,EAAc,IAAI,KAAKR,EAAM,WAAW,UAAU,CAAC,CAC3D,u1DCdD,KAAM,CAAE,WAAAS,EAAY,UAAAC,CAAU,EAAIC,EAAkB,0qECRpD,MAAMX,EAAQC,EAIRC,EAAYC,IACZL,EAAmBC,IAEnBK,EAAoBC,EAAS,IAAM,OACvC,OAAKH,EAAU,aACRI,EAAAJ,EAAU,OAAV,YAAAI,EAAgB,MAAON,EAAM,WAAW,QADb,EACa,CAChD,64CCRK,KAAA,CAAE,UAAAY,GAAcC,kOCNtB,MAAMf,EAAmBC"}