|
1 | 1 | <script> |
2 | | - import { Icon, Listbox, Option } from '@sveltia/ui'; |
| 2 | + import { Icon, Listbox, Option, OptionGroup } from '@sveltia/ui'; |
3 | 3 | import { sleep } from '@sveltia/utils/misc'; |
4 | 4 | import equal from 'fast-deep-equal'; |
5 | 5 | import { _, locale as appLocale } from 'svelte-i18n'; |
|
41 | 41 | /> |
42 | 42 | {/if} |
43 | 43 | <Listbox aria-label={$_('asset_folder_list')} aria-controls="assets-container"> |
44 | | - {#each folders as folder ([folder.collectionName, folder.fileName, folder.internalPath].join(':'))} |
45 | | - {#await sleep() then} |
46 | | - {@const { collectionName, internalPath, entryRelative, hasTemplateTags } = folder} |
47 | | - {@const collection = collectionName ? getCollection(collectionName) : undefined} |
48 | | - <!-- Can’t upload assets if collection assets are saved at entry-relative paths --> |
49 | | - {@const uploadDisabled = entryRelative || hasTemplateTags} |
50 | | - {@const selected = equal($selectedAssetFolder, folder)} |
51 | | - <Option |
52 | | - selected={$isSmallScreen ? false : selected} |
53 | | - label={$appLocale ? getFolderLabelByCollection(folder) : ''} |
54 | | - onSelect={() => { |
55 | | - goto(`/assets/${internalPath ?? '-/all'}`, { |
56 | | - transitionType: 'forwards', |
57 | | - // An internal path can be shared by multiple collections, files and fields. Pass the |
58 | | - // folder info as history state so we can distinguish these different asset folders |
59 | | - // while keeping the URL clean. |
60 | | - state: { folder }, |
61 | | - }); |
62 | | - }} |
63 | | - ondragover={(event) => { |
64 | | - event.preventDefault(); |
| 44 | + <OptionGroup label={$_('asset_location.repository')}> |
| 45 | + {#each folders as folder ([folder.collectionName, folder.fileName, folder.internalPath].join(':'))} |
| 46 | + {#await sleep() then} |
| 47 | + {@const { collectionName, internalPath, entryRelative, hasTemplateTags } = folder} |
| 48 | + {@const collection = collectionName ? getCollection(collectionName) : undefined} |
| 49 | + <!-- Can’t upload assets if collection assets are saved at entry-relative paths --> |
| 50 | + {@const uploadDisabled = entryRelative || hasTemplateTags} |
| 51 | + {@const selected = equal($selectedAssetFolder, folder)} |
| 52 | + <Option |
| 53 | + selected={$isSmallScreen ? false : selected} |
| 54 | + label={$appLocale ? getFolderLabelByCollection(folder) : ''} |
| 55 | + onSelect={() => { |
| 56 | + goto(`/assets/${internalPath ?? '-/all'}`, { |
| 57 | + transitionType: 'forwards', |
| 58 | + // An internal path can be shared by multiple collections, files and fields. Pass |
| 59 | + // the folder info as history state so we can distinguish these different asset |
| 60 | + // folders while keeping the URL clean. |
| 61 | + state: { folder }, |
| 62 | + }); |
| 63 | + }} |
| 64 | + ondragover={(event) => { |
| 65 | + event.preventDefault(); |
65 | 66 |
|
66 | | - if (uploadDisabled) { |
67 | | - return; |
68 | | - } |
| 67 | + if (uploadDisabled) { |
| 68 | + return; |
| 69 | + } |
69 | 70 |
|
70 | | - if (internalPath === undefined || selected) { |
71 | | - /** @type {DataTransfer} */ (event.dataTransfer).dropEffect = 'none'; |
72 | | - } else { |
73 | | - /** @type {DataTransfer} */ (event.dataTransfer).dropEffect = 'move'; |
74 | | - /** @type {HTMLElement} */ (event.target).classList.add('dragover'); |
75 | | - } |
76 | | - }} |
77 | | - ondragleave={(event) => { |
78 | | - event.preventDefault(); |
| 71 | + if (internalPath === undefined || selected) { |
| 72 | + /** @type {DataTransfer} */ (event.dataTransfer).dropEffect = 'none'; |
| 73 | + } else { |
| 74 | + /** @type {DataTransfer} */ (event.dataTransfer).dropEffect = 'move'; |
| 75 | + /** @type {HTMLElement} */ (event.target).classList.add('dragover'); |
| 76 | + } |
| 77 | + }} |
| 78 | + ondragleave={(event) => { |
| 79 | + event.preventDefault(); |
79 | 80 |
|
80 | | - if (uploadDisabled) { |
81 | | - return; |
82 | | - } |
| 81 | + if (uploadDisabled) { |
| 82 | + return; |
| 83 | + } |
83 | 84 |
|
84 | | - /** @type {HTMLElement} */ (event.target).classList.remove('dragover'); |
85 | | - }} |
86 | | - ondragend={(event) => { |
87 | | - event.preventDefault(); |
| 85 | + /** @type {HTMLElement} */ (event.target).classList.remove('dragover'); |
| 86 | + }} |
| 87 | + ondragend={(event) => { |
| 88 | + event.preventDefault(); |
88 | 89 |
|
89 | | - if (uploadDisabled) { |
90 | | - return; |
91 | | - } |
| 90 | + if (uploadDisabled) { |
| 91 | + return; |
| 92 | + } |
92 | 93 |
|
93 | | - /** @type {HTMLElement} */ (event.target).classList.remove('dragover'); |
94 | | - }} |
95 | | - ondrop={(event) => { |
96 | | - event.preventDefault(); |
| 94 | + /** @type {HTMLElement} */ (event.target).classList.remove('dragover'); |
| 95 | + }} |
| 96 | + ondrop={(event) => { |
| 97 | + event.preventDefault(); |
97 | 98 |
|
98 | | - if (uploadDisabled) { |
99 | | - return; |
100 | | - } |
| 99 | + if (uploadDisabled) { |
| 100 | + return; |
| 101 | + } |
101 | 102 |
|
102 | | - /** @type {HTMLElement} */ (event.target).classList.remove('dragover'); |
103 | | - // @todo Move the assets while updating entries using the files, after showing a |
104 | | - // confirmation dialog. |
105 | | - }} |
106 | | - > |
107 | | - {#snippet startIcon()} |
108 | | - <Icon name={collection?.icon || 'folder'} /> |
109 | | - {/snippet} |
110 | | - {#snippet endIcon()} |
111 | | - {#key $allAssets} |
112 | | - {#await sleep() then} |
113 | | - {@const count = ( |
114 | | - internalPath !== undefined ? getAssetsByFolder(folder) : $allAssets |
115 | | - ).length} |
116 | | - <span |
117 | | - class="count" |
118 | | - aria-label="({$_( |
119 | | - count > 1 ? 'many_assets' : count === 1 ? 'one_asset' : 'no_assets', |
120 | | - { values: { count } }, |
121 | | - )})" |
122 | | - > |
123 | | - {numberFormatter.format(count)} |
124 | | - </span> |
125 | | - {/await} |
126 | | - {/key} |
127 | | - {/snippet} |
128 | | - </Option> |
129 | | - {/await} |
130 | | - {/each} |
| 103 | + /** @type {HTMLElement} */ (event.target).classList.remove('dragover'); |
| 104 | + // @todo Move the assets while updating entries using the files, after showing a |
| 105 | + // confirmation dialog. |
| 106 | + }} |
| 107 | + > |
| 108 | + {#snippet startIcon()} |
| 109 | + <Icon name={collection?.icon || 'folder'} /> |
| 110 | + {/snippet} |
| 111 | + {#snippet endIcon()} |
| 112 | + {#key $allAssets} |
| 113 | + {#await sleep() then} |
| 114 | + {@const count = ( |
| 115 | + internalPath !== undefined ? getAssetsByFolder(folder) : $allAssets |
| 116 | + ).length} |
| 117 | + <span |
| 118 | + class="count" |
| 119 | + aria-label="({$_( |
| 120 | + count > 1 ? 'many_assets' : count === 1 ? 'one_asset' : 'no_assets', |
| 121 | + { values: { count } }, |
| 122 | + )})" |
| 123 | + > |
| 124 | + {numberFormatter.format(count)} |
| 125 | + </span> |
| 126 | + {/await} |
| 127 | + {/key} |
| 128 | + {/snippet} |
| 129 | + </Option> |
| 130 | + {/await} |
| 131 | + {/each} |
| 132 | + </OptionGroup> |
| 133 | + <!-- @todo Add external locations, including Cloudinary and Uploadcare --> |
131 | 134 | </Listbox> |
132 | 135 | </div> |
0 commit comments