|
1 | 1 | <script lang="ts"> |
2 | 2 | import { Button } from '$lib/elements/forms'; |
3 | | - import { DropList, GridItem1, CardContainer, Paginator } from '$lib/components'; |
| 3 | + import { DropList, GridItem1, CardContainer } from '$lib/components'; |
| 4 | + import ArchivedPaginationWithLimit from './archivedPaginationWithLimit.svelte'; |
4 | 5 | import { |
5 | 6 | Badge, |
6 | 7 | Icon, |
|
45 | 46 | projectsToArchive: Models.Project[]; |
46 | 47 | organization: Organization; |
47 | 48 | currentPlan: Plan; |
| 49 | + archivedTotalOverall: number; |
| 50 | + archivedOffset: number; |
| 51 | + limit: number; |
48 | 52 | } |
49 | 53 |
|
50 | | - let { projectsToArchive, organization, currentPlan }: Props = $props(); |
| 54 | + let { |
| 55 | + projectsToArchive, |
| 56 | + organization, |
| 57 | + currentPlan, |
| 58 | + archivedTotalOverall, |
| 59 | + archivedOffset, |
| 60 | + limit |
| 61 | + }: Props = $props(); |
51 | 62 |
|
52 | 63 | // Track Read-only info droplist per archived project |
53 | 64 | let readOnlyInfoOpen = $state<Record<string, boolean>>({}); |
|
153 | 164 |
|
154 | 165 | {#if projectsToArchive.length > 0} |
155 | 166 | <div class="archive-projects-margin-top"> |
156 | | - <Accordion title="Archived projects" badge={`${projectsToArchive.length}`}> |
| 167 | + <Accordion title="Archived projects" badge={`${archivedTotalOverall}`}> |
157 | 168 | <Typography.Text tag="p" size="s"> |
158 | 169 | These projects have been archived and are read-only. You can view and migrate their |
159 | 170 | data. |
160 | 171 | </Typography.Text> |
161 | 172 |
|
162 | 173 | <div class="archive-projects-margin"> |
163 | | - <Paginator |
164 | | - items={projectsToArchive} |
165 | | - limit={6} |
166 | | - hidePages={false} |
167 | | - hideFooter={projectsToArchive.length <= 6}> |
168 | | - {#snippet children(items)} |
169 | | - <CardContainer disableEmpty={true} total={projectsToArchive.length}> |
170 | | - {#each items as project} |
171 | | - {@const platforms = filterPlatforms( |
172 | | - project.platforms.map((platform) => |
173 | | - getPlatformInfo(platform.type) |
174 | | - ) |
175 | | - )} |
176 | | - {@const formatted = formatName(project.name)} |
177 | | - <GridItem1> |
178 | | - <svelte:fragment slot="eyebrow"> |
179 | | - {project?.platforms?.length |
180 | | - ? project?.platforms?.length |
181 | | - : 'No'} apps |
182 | | - </svelte:fragment> |
183 | | - <svelte:fragment slot="title">{formatted}</svelte:fragment> |
184 | | - <svelte:fragment slot="status"> |
185 | | - <div class="status-container"> |
186 | | - <DropList |
187 | | - bind:show={readOnlyInfoOpen[project.$id]} |
188 | | - placement="bottom-start" |
189 | | - noArrow> |
190 | | - <Tag |
191 | | - size="s" |
192 | | - style="white-space: nowrap;" |
193 | | - on:click={(e) => { |
194 | | - e.preventDefault(); |
195 | | - e.stopPropagation(); |
196 | | - readOnlyInfoOpen = { |
197 | | - ...readOnlyInfoOpen, |
198 | | - [project.$id]: |
199 | | - !readOnlyInfoOpen[project.$id] |
200 | | - }; |
201 | | - }}> |
202 | | - <Icon icon={IconInfo} size="s" /> |
203 | | - <span>Read only</span> |
204 | | - </Tag> |
205 | | - <svelte:fragment slot="list"> |
206 | | - <li |
207 | | - class="drop-list-item u-width-250" |
208 | | - style="padding: var(--space-5, 12px) var(--space-6, 16px)"> |
209 | | - <span class="u-block u-mb-8"> |
210 | | - Archived projects are read-only. You can |
211 | | - view and migrate their data, but they no |
212 | | - longer accept edits or requests. |
213 | | - </span> |
214 | | - </li> |
215 | | - </svelte:fragment> |
216 | | - </DropList> |
217 | | - <Popover |
218 | | - let:toggle |
219 | | - padding="none" |
220 | | - placement="bottom-end"> |
221 | | - <Button |
222 | | - text |
223 | | - icon |
224 | | - size="s" |
225 | | - ariaLabel="more options" |
226 | | - on:click={(e) => { |
227 | | - e.preventDefault(); |
228 | | - e.stopPropagation(); |
229 | | - toggle(e); |
230 | | - }}> |
231 | | - <Icon icon={IconDotsHorizontal} size="s" /> |
232 | | - </Button> |
233 | | - <ActionMenu.Root slot="tooltip"> |
234 | | - <ActionMenu.Item.Button |
235 | | - leadingIcon={IconInboxIn} |
236 | | - disabled={isUnarchiveDisabled()} |
237 | | - on:click={() => |
238 | | - handleUnarchiveProject(project)} |
239 | | - >Unarchive project</ActionMenu.Item.Button> |
240 | | - <ActionMenu.Item.Button |
241 | | - leadingIcon={IconSwitchHorizontal} |
242 | | - on:click={() => |
243 | | - handleMigrateProject(project)} |
244 | | - >Migrate project</ActionMenu.Item.Button> |
245 | | - </ActionMenu.Root> |
246 | | - </Popover> |
247 | | - </div> |
248 | | - </svelte:fragment> |
| 174 | + <CardContainer disableEmpty={true} total={archivedTotalOverall}> |
| 175 | + {#each projectsToArchive as project} |
| 176 | + {@const platforms = filterPlatforms( |
| 177 | + project.platforms.map((platform) => getPlatformInfo(platform.type)) |
| 178 | + )} |
| 179 | + {@const formatted = formatName(project.name)} |
| 180 | + <GridItem1> |
| 181 | + <svelte:fragment slot="eyebrow"> |
| 182 | + {project?.platforms?.length ? project?.platforms?.length : 'No'} apps |
| 183 | + </svelte:fragment> |
| 184 | + <svelte:fragment slot="title">{formatted}</svelte:fragment> |
| 185 | + <svelte:fragment slot="status"> |
| 186 | + <div class="status-container"> |
| 187 | + <DropList |
| 188 | + bind:show={readOnlyInfoOpen[project.$id]} |
| 189 | + placement="bottom-start" |
| 190 | + noArrow> |
| 191 | + <Tag |
| 192 | + size="s" |
| 193 | + style="white-space: nowrap;" |
| 194 | + on:click={(e) => { |
| 195 | + e.preventDefault(); |
| 196 | + e.stopPropagation(); |
| 197 | + readOnlyInfoOpen = { |
| 198 | + ...readOnlyInfoOpen, |
| 199 | + [project.$id]: !readOnlyInfoOpen[project.$id] |
| 200 | + }; |
| 201 | + }}> |
| 202 | + <Icon icon={IconInfo} size="s" /> |
| 203 | + <span>Read only</span> |
| 204 | + </Tag> |
| 205 | + <svelte:fragment slot="list"> |
| 206 | + <li |
| 207 | + class="drop-list-item u-width-250" |
| 208 | + style="padding: var(--space-5, 12px) var(--space-6, 16px)"> |
| 209 | + <span class="u-block u-mb-8"> |
| 210 | + Archived projects are read-only. You can view |
| 211 | + and migrate their data, but they no longer |
| 212 | + accept edits or requests. |
| 213 | + </span> |
| 214 | + </li> |
| 215 | + </svelte:fragment> |
| 216 | + </DropList> |
| 217 | + <Popover let:toggle padding="none" placement="bottom-end"> |
| 218 | + <Button |
| 219 | + text |
| 220 | + icon |
| 221 | + size="s" |
| 222 | + ariaLabel="more options" |
| 223 | + on:click={(e) => { |
| 224 | + e.preventDefault(); |
| 225 | + e.stopPropagation(); |
| 226 | + toggle(e); |
| 227 | + }}> |
| 228 | + <Icon icon={IconDotsHorizontal} size="s" /> |
| 229 | + </Button> |
| 230 | + <ActionMenu.Root slot="tooltip"> |
| 231 | + <ActionMenu.Item.Button |
| 232 | + leadingIcon={IconInboxIn} |
| 233 | + disabled={isUnarchiveDisabled()} |
| 234 | + on:click={() => handleUnarchiveProject(project)} |
| 235 | + >Unarchive project</ActionMenu.Item.Button> |
| 236 | + <ActionMenu.Item.Button |
| 237 | + leadingIcon={IconSwitchHorizontal} |
| 238 | + on:click={() => handleMigrateProject(project)} |
| 239 | + >Migrate project</ActionMenu.Item.Button> |
| 240 | + </ActionMenu.Root> |
| 241 | + </Popover> |
| 242 | + </div> |
| 243 | + </svelte:fragment> |
249 | 244 |
|
250 | | - {#each platforms.slice(0, 2) as platform} |
251 | | - {@const icon = getIconForPlatform(platform.icon)} |
252 | | - <Badge |
253 | | - variant="secondary" |
254 | | - content={platform.name} |
255 | | - style="width: max-content;"> |
256 | | - <Icon {icon} size="s" slot="start" /> |
257 | | - </Badge> |
258 | | - {/each} |
| 245 | + {#each platforms.slice(0, 2) as platform} |
| 246 | + {@const icon = getIconForPlatform(platform.icon)} |
| 247 | + <Badge |
| 248 | + variant="secondary" |
| 249 | + content={platform.name} |
| 250 | + style="width: max-content;"> |
| 251 | + <Icon {icon} size="s" slot="start" /> |
| 252 | + </Badge> |
| 253 | + {/each} |
259 | 254 |
|
260 | | - {#if platforms.length > 2} |
261 | | - <Badge |
262 | | - variant="secondary" |
263 | | - content={`+${platforms.length - 2}`} |
264 | | - style="width: max-content;" /> |
265 | | - {/if} |
| 255 | + {#if platforms.length > 2} |
| 256 | + <Badge |
| 257 | + variant="secondary" |
| 258 | + content={`+${platforms.length - 2}`} |
| 259 | + style="width: max-content;" /> |
| 260 | + {/if} |
266 | 261 |
|
267 | | - <svelte:fragment slot="icons"> |
268 | | - {#if isCloud && $regionsStore?.regions} |
269 | | - {@const region = findRegion(project)} |
270 | | - <Typography.Text>{region?.name}</Typography.Text> |
271 | | - {/if} |
272 | | - </svelte:fragment> |
273 | | - </GridItem1> |
274 | | - {/each} |
275 | | - </CardContainer> |
276 | | - {/snippet} |
277 | | - </Paginator> |
| 262 | + <svelte:fragment slot="icons"> |
| 263 | + {#if isCloud && $regionsStore?.regions} |
| 264 | + {@const region = findRegion(project)} |
| 265 | + <Typography.Text>{region?.name}</Typography.Text> |
| 266 | + {/if} |
| 267 | + </svelte:fragment> |
| 268 | + </GridItem1> |
| 269 | + {/each} |
| 270 | + </CardContainer> |
| 271 | + |
| 272 | + <div class="pagination-container"> |
| 273 | + <ArchivedPaginationWithLimit |
| 274 | + name="Archived Projects" |
| 275 | + {limit} |
| 276 | + offset={archivedOffset} |
| 277 | + total={archivedTotalOverall} /> |
| 278 | + </div> |
278 | 279 | </div> |
279 | 280 | </Accordion> |
280 | 281 | </div> |
|
307 | 308 | align-items: center; |
308 | 309 | gap: 8px; |
309 | 310 | } |
| 311 | + .pagination-container { |
| 312 | + margin-top: 16px; |
| 313 | + } |
310 | 314 | </style> |
0 commit comments