- Update all skill SSH commands from sshpass to key-based auth (~/.ssh/archipelago-deploy) - Add proxy_connect_timeout 120s to nginx Ollama location blocks - Add new polish/sweep skills for overnight automation - Add demo content (documents, photos) for demo stack - Add .ssh/ to .gitignore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
84 lines
2.5 KiB
Markdown
84 lines
2.5 KiB
Markdown
# Skill: Polish Loading States
|
|
|
|
Add skeleton loaders, loading indicators, timeout warnings, and empty states to all async views. No view should ever show a blank screen.
|
|
|
|
## Skeleton Loader Component
|
|
|
|
Create or use a `SkeletonLoader.vue` component with the glassmorphism style:
|
|
- Background: `bg-white/5` with shimmer animation
|
|
- Rounded corners matching the card it replaces
|
|
- Animate with CSS `@keyframes shimmer` (translate gradient left to right)
|
|
- Must use global classes from style.css, not inline Tailwind
|
|
|
|
## Views to Fix
|
|
|
|
For EACH view in `neode-ui/src/views/`, verify these states exist:
|
|
|
|
### 1. Loading State
|
|
- Show skeleton placeholders immediately on mount
|
|
- Pattern:
|
|
```vue
|
|
<template>
|
|
<div v-if="isLoading">
|
|
<!-- Skeleton matching the layout -->
|
|
</div>
|
|
<div v-else>
|
|
<!-- Real content -->
|
|
</div>
|
|
</template>
|
|
```
|
|
|
|
### 2. Empty State
|
|
- When data loads but is empty (zero items)
|
|
- Show helpful message with CTA
|
|
- Pattern:
|
|
```vue
|
|
<div v-if="!isLoading && items.length === 0" class="glass-card text-center py-12">
|
|
<p class="text-white/60">No apps installed yet</p>
|
|
<router-link to="/marketplace" class="glass-button mt-4">Browse Marketplace</router-link>
|
|
</div>
|
|
```
|
|
|
|
### 3. Timeout Warning
|
|
- After 15 seconds of loading, show "Taking longer than expected..."
|
|
- After 30 seconds, show troubleshooting options
|
|
- Pattern:
|
|
```typescript
|
|
const loadingTooLong = ref(false)
|
|
let timeout: ReturnType<typeof setTimeout>
|
|
|
|
onMounted(() => {
|
|
timeout = setTimeout(() => { loadingTooLong.value = true }, 15000)
|
|
})
|
|
|
|
watch(isLoading, (val) => { if (!val) clearTimeout(timeout) })
|
|
```
|
|
|
|
## Priority Views (must have all 3 states)
|
|
|
|
1. **Apps.vue** — app grid skeleton, "No apps installed" empty state
|
|
2. **AppDetails.vue** — detail card skeleton, loading indicator
|
|
3. **Marketplace.vue** — app card grid skeleton, "Loading apps..." with timeout
|
|
4. **Dashboard.vue** — metric card skeletons
|
|
5. **Cloud.vue** — file list skeleton, "No files" empty state
|
|
6. **Settings.vue** — settings section skeleton
|
|
7. **Server.vue** — server info skeleton
|
|
|
|
## Verification
|
|
|
|
For each view, confirm:
|
|
- [ ] `isLoading` ref exists and is set properly
|
|
- [ ] Template has `v-if="isLoading"` skeleton section
|
|
- [ ] Template has empty state for zero-data case
|
|
- [ ] Loading timeout warning after 15s
|
|
- [ ] Skeleton uses global classes, not inline Tailwind
|
|
|
|
## Deploy After Fixes
|
|
|
|
Always deploy and verify on live server:
|
|
```bash
|
|
./scripts/deploy-to-target.sh --live
|
|
```
|
|
|
|
Test by throttling network in browser DevTools to observe loading states.
|