Skip to content

Commit 55c249f

Browse files
committed
redesign: replace preset+additional with unified CLI/Apps package groups
1 parent db51fea commit 55c249f

File tree

1 file changed

+72
-149
lines changed

1 file changed

+72
-149
lines changed

src/routes/dashboard/+page.svelte

Lines changed: 72 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,14 @@
116116
return Array.from(selectedPackages.keys()).filter((pkg) => !presetPkgs.has(pkg));
117117
}
118118
119-
function getGroupedExtras(): { cli: string[]; apps: string[]; taps: string[] } {
120-
const extras = getExtraPackages();
119+
function getGroupedPackages(): { cli: string[]; apps: string[] } {
121120
const cli: string[] = [];
122121
const apps: string[] = [];
123-
const taps: string[] = [];
124-
for (const pkg of extras) {
125-
const t = selectedPackages.get(pkg) || 'formula';
122+
for (const [pkg, t] of selectedPackages) {
126123
if (t === 'cask') apps.push(pkg);
127-
else if (t === 'tap') taps.push(pkg);
128124
else cli.push(pkg);
129125
}
130-
return { cli, apps, taps };
126+
return { cli, apps };
131127
}
132128
133129
@@ -517,72 +513,47 @@
517513
<p class="form-hint">After installing packages, OpenBoot will clone this repo and deploy configs via stow.</p>
518514
</div>
519515

520-
<div class="packages-section">
521-
<div class="packages-header">
522-
<span class="packages-title">Packages from "{formData.base_preset}" preset</span>
523-
<button class="expand-btn" onclick={() => presetExpanded = !presetExpanded}>
524-
{presetExpanded ? 'Collapse' : 'Expand'} ({selectedPackages.size} selected)
525-
</button>
516+
{#if true}
517+
{@const grouped = getGroupedPackages()}
518+
<div class="packages-section">
519+
<div class="packages-header">
520+
<span class="packages-title">Packages</span>
521+
<span class="extra-count">{selectedPackages.size} selected</span>
522+
</div>
523+
524+
<div class="packages-group">
525+
<div class="group-header">
526+
<span class="group-label">CLI</span>
527+
<span class="group-count">{grouped.cli.length}</span>
526528
</div>
527-
<p class="packages-hint">Click to toggle. Gray = won't install.</p>
528-
<div class="preset-packages" class:expanded={presetExpanded}>
529-
{#each presetExpanded ? getPresetPackages(formData.base_preset) : getPresetPackages(formData.base_preset).slice(0, 12) as pkg}
530-
<button
531-
class="preset-tag"
532-
class:excluded={!selectedPackages.has(pkg)}
533-
onclick={() => togglePresetPackage(pkg)}
534-
>{pkg}</button>
535-
{/each}
536-
{#if !presetExpanded && getPresetPackages(formData.base_preset).length > 12}
537-
<button class="preset-tag more" onclick={() => presetExpanded = true}>
538-
+{getPresetPackages(formData.base_preset).length - 12} more
529+
<div class="group-tags">
530+
{#each grouped.cli as pkg}
531+
<button type="button" class="pkg-tag" onclick={() => togglePackage(pkg, 'formula')}>
532+
{pkg}<span class="remove-icon">×</span>
539533
</button>
534+
{/each}
535+
{#if grouped.cli.length === 0}
536+
<span class="group-empty">No CLI packages</span>
540537
{/if}
541538
</div>
542539
</div>
543540

544-
<div class="packages-section">
545-
<div class="packages-header">
546-
<span class="packages-title">Additional Packages</span>
547-
{#if getExtraPackages().length > 0}
548-
<span class="extra-count">{getExtraPackages().length} added</span>
549-
{/if}
550-
</div>
551-
{#if getExtraPackages().length > 0}
552-
{@const grouped = getGroupedExtras()}
553-
<div class="selected-extras">
554-
{#if grouped.cli.length > 0}
555-
<div class="extras-group">
556-
<span class="group-label">CLI</span>
557-
{#each grouped.cli as pkg}
558-
<button type="button" class="extra-tag" onclick={() => togglePackage(pkg, 'formula')}>
559-
{pkg}<span class="remove-icon">×</span>
560-
</button>
561-
{/each}
562-
</div>
563-
{/if}
564-
{#if grouped.apps.length > 0}
565-
<div class="extras-group">
566-
<span class="group-label">Apps</span>
567-
{#each grouped.apps as pkg}
568-
<button type="button" class="extra-tag" onclick={() => togglePackage(pkg, 'cask')}>
569-
{pkg}<span class="remove-icon">×</span>
570-
</button>
571-
{/each}
572-
</div>
573-
{/if}
574-
{#if grouped.taps.length > 0}
575-
<div class="extras-group">
576-
<span class="group-label">Taps</span>
577-
{#each grouped.taps as pkg}
578-
<button type="button" class="extra-tag" onclick={() => togglePackage(pkg, 'tap')}>
579-
{pkg}<span class="remove-icon">×</span>
580-
</button>
581-
{/each}
582-
</div>
541+
<div class="packages-group">
542+
<div class="group-header">
543+
<span class="group-label">Apps</span>
544+
<span class="group-count">{grouped.apps.length}</span>
545+
</div>
546+
<div class="group-tags">
547+
{#each grouped.apps as pkg}
548+
<button type="button" class="pkg-tag" onclick={() => togglePackage(pkg, 'cask')}>
549+
{pkg}<span class="remove-icon">×</span>
550+
</button>
551+
{/each}
552+
{#if grouped.apps.length === 0}
553+
<span class="group-empty">No GUI apps</span>
583554
{/if}
584555
</div>
585-
{/if}
556+
</div>
586557
<div class="packages-search">
587558
<input
588559
type="text"
@@ -617,6 +588,7 @@
617588
<div class="search-hint">Type at least 2 characters to search Homebrew packages</div>
618589
{/if}
619590
</div>
591+
{/if}
620592

621593
<div class="form-group">
622594
<label class="form-label">Custom Post-Install Script (Optional)</label>
@@ -1045,113 +1017,64 @@
10451017
margin-bottom: 12px;
10461018
}
10471019
1048-
.packages-hint {
1049-
font-size: 0.75rem;
1050-
color: var(--text-muted);
1051-
margin-bottom: 10px;
1020+
.packages-title {
1021+
font-size: 1rem;
1022+
font-weight: 500;
10521023
}
10531024
1054-
.expand-btn {
1055-
background: none;
1056-
border: none;
1057-
color: var(--accent);
1025+
.extra-count {
10581026
font-size: 0.8rem;
1059-
cursor: pointer;
1060-
padding: 4px 8px;
1061-
}
1062-
1063-
.expand-btn:hover {
1064-
text-decoration: underline;
1065-
}
1066-
1067-
.preset-packages {
1068-
display: flex;
1069-
flex-wrap: wrap;
1070-
gap: 6px;
1071-
max-height: 80px;
1072-
overflow: hidden;
1073-
transition: max-height 0.3s ease;
1074-
}
1075-
1076-
.preset-packages.expanded {
1077-
max-height: none;
1027+
color: var(--text-muted);
10781028
}
10791029
1080-
.preset-tag {
1081-
padding: 4px 10px;
1082-
background: var(--bg-tertiary);
1083-
border: 1px solid var(--border);
1084-
border-radius: 4px;
1085-
font-size: 0.75rem;
1086-
color: var(--text-secondary);
1087-
font-family: 'JetBrains Mono', monospace;
1088-
cursor: pointer;
1089-
transition: all 0.15s;
1030+
.packages-group {
1031+
margin-bottom: 16px;
10901032
}
10911033
1092-
.preset-tag:hover {
1093-
border-color: var(--accent);
1034+
.packages-group:last-child {
1035+
margin-bottom: 0;
10941036
}
10951037
1096-
.preset-tag.excluded {
1097-
opacity: 0.4;
1098-
text-decoration: line-through;
1099-
background: transparent;
1038+
.group-header {
1039+
display: flex;
1040+
align-items: center;
1041+
gap: 8px;
1042+
margin-bottom: 8px;
11001043
}
11011044
1102-
.preset-tag.more {
1103-
background: transparent;
1104-
border-style: dashed;
1045+
.group-label {
1046+
font-size: 0.7rem;
1047+
text-transform: uppercase;
1048+
letter-spacing: 0.08em;
11051049
color: var(--text-muted);
1050+
font-weight: 600;
11061051
}
11071052
1108-
.packages-title {
1109-
font-size: 1rem;
1110-
font-weight: 500;
1111-
}
1112-
1113-
.extra-count {
1114-
font-size: 0.8rem;
1115-
color: var(--accent);
1116-
}
1117-
1118-
.selected-extras {
1119-
margin-bottom: 12px;
1120-
padding: 10px;
1121-
background: rgba(255, 255, 255, 0.02);
1122-
border: 1px solid var(--border);
1123-
border-radius: 8px;
1053+
.group-count {
1054+
font-size: 0.65rem;
1055+
color: var(--text-muted);
1056+
opacity: 0.6;
11241057
}
11251058
1126-
.extras-group {
1059+
.group-tags {
11271060
display: flex;
11281061
flex-wrap: wrap;
1129-
align-items: center;
11301062
gap: 6px;
1131-
margin-bottom: 8px;
1132-
}
1133-
1134-
.extras-group:last-child {
1135-
margin-bottom: 0;
11361063
}
11371064
1138-
.group-label {
1139-
font-size: 0.6rem;
1140-
text-transform: uppercase;
1141-
letter-spacing: 0.05em;
1065+
.group-empty {
1066+
font-size: 0.8rem;
11421067
color: var(--text-muted);
1143-
font-weight: 600;
1144-
width: 32px;
1145-
flex-shrink: 0;
1068+
opacity: 0.4;
11461069
}
11471070
1148-
.extra-tag {
1071+
.pkg-tag {
11491072
display: inline-flex;
11501073
align-items: center;
11511074
gap: 4px;
11521075
padding: 4px 8px;
1153-
background: rgba(255, 255, 255, 0.08);
1154-
border: 1px solid rgba(255, 255, 255, 0.12);
1076+
background: var(--bg-tertiary);
1077+
border: 1px solid var(--border);
11551078
color: var(--text-secondary);
11561079
border-radius: 4px;
11571080
font-size: 0.75rem;
@@ -1160,18 +1083,18 @@
11601083
transition: all 0.15s;
11611084
}
11621085
1163-
.extra-tag:hover {
1164-
background: rgba(255, 255, 255, 0.14);
1165-
color: var(--text-primary);
1086+
.pkg-tag:hover {
1087+
border-color: var(--danger);
1088+
color: var(--danger);
11661089
}
11671090
11681091
.remove-icon {
11691092
font-size: 0.9rem;
11701093
font-weight: bold;
1171-
opacity: 0.7;
1094+
opacity: 0.5;
11721095
}
11731096
1174-
.extra-tag:hover .remove-icon {
1097+
.pkg-tag:hover .remove-icon {
11751098
opacity: 1;
11761099
}
11771100

0 commit comments

Comments
 (0)