diff --git a/apps/desktop/src/cardLayout.test.js b/apps/desktop/src/cardLayout.test.js index e792c66..47a5db1 100644 --- a/apps/desktop/src/cardLayout.test.js +++ b/apps/desktop/src/cardLayout.test.js @@ -555,12 +555,19 @@ test('collection review keeps child selection and collection type controls insid /function CandidateReviewList\(\{(?[\s\S]*?)\n\}\n\nfunction CollectionSelectionCheckbox/ )?.groups.body || ''; const collectionRule = css.match(/\.collectionReviewCard\s*\{(?[^}]*)\}/s)?.groups.body || ''; + const collectionHeaderRule = css.match(/\.collectionReviewHeader\s*\{(?[^}]*)\}/s)?.groups.body || ''; const childRule = css.match(/\.collectionChildRow\s*\{(?[^}]*)\}/s)?.groups.body || ''; const collectionActionsRule = css.match(/\.collectionReviewActions\s*\{(?[^}]*)\}/s)?.groups.body || ''; const collectionTypeRule = css.match(/\.collectionReviewTypeAction\s*\{(?[^}]*)\}/s)?.groups.body || ''; + const collectionSelectionRule = css.match( + /\.collectionReviewSelectionAction\s*\{(?[^}]*)\}/s + )?.groups.body || ''; const requiredCollectionTypeRule = css.match( /\.collectionReviewTypeAction\.required\s*\{(?[^}]*)\}/s )?.groups.body || ''; + const narrowCollectionRules = css.match( + /@media \(max-width: 920px\)\s*\{(?[\s\S]*)\n\}/ + )?.groups.body || ''; assert.match(collectionSource, /aria-controls={disclosureId}/); assert.match(collectionSource, /collection\.children\.map/); @@ -604,9 +611,19 @@ test('collection review keeps child selection and collection type controls insid assert.match(collectionSource, /readOnlyLabel \?/); assert.match(collectionSource, /relativePath/); assert.match(collectionRule, /min-width:\s*0;/); - assert.match(collectionActionsRule, /display:\s*flex;/); + assert.match(collectionHeaderRule, /display:\s*grid;/); + assert.match(collectionHeaderRule, /grid-template-columns:\s*minmax\(0,\s*1fr\) minmax\(470px,\s*auto\);/); + assert.match(collectionHeaderRule, /align-items:\s*flex-start;/); + assert.match(collectionActionsRule, /display:\s*grid;/); + assert.match(collectionActionsRule, /width:\s*470px;/); + assert.match(collectionActionsRule, /grid-template-columns:\s*248px minmax\(0,\s*210px\);/); + assert.match(collectionActionsRule, /align-self:\s*start;/); assert.match(collectionTypeRule, /width:\s*248px;/); assert.match(collectionTypeRule, /box-sizing:\s*border-box;/); + assert.match(collectionSelectionRule, /grid-column:\s*2;/); + assert.match(collectionSelectionRule, /align-items:\s*flex-start;/); + assert.match(narrowCollectionRules, /\.collectionReviewActions\s*\{[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\);/s); + assert.match(narrowCollectionRules, /\.collectionReviewSelectionAction\s*\{[^}]*grid-column:\s*1;/s); assert.match(requiredCollectionTypeRule, /border-color:\s*var\(--skillbox-amber-border\);/); assert.match(requiredCollectionTypeRule, /background:\s*var\(--skillbox-surface-orange\);/); assert.match(css, /\.candidateCheck input:indeterminate \+ span/); diff --git a/apps/desktop/src/styles.css b/apps/desktop/src/styles.css index 944e92e..da85746 100644 --- a/apps/desktop/src/styles.css +++ b/apps/desktop/src/styles.css @@ -6290,10 +6290,10 @@ dd { } .collectionReviewHeader { - display: flex; + display: grid; min-width: 0; + grid-template-columns: minmax(0, 1fr) minmax(470px, auto); align-items: flex-start; - justify-content: space-between; gap: 16px; } @@ -6330,10 +6330,13 @@ dd { } .collectionReviewActions { - display: flex; - flex: 0 0 auto; - align-items: flex-start; - justify-content: flex-end; + display: grid; + width: 470px; + max-width: 100%; + grid-template-columns: 248px minmax(0, 210px); + align-items: start; + align-self: start; + justify-content: end; gap: 12px; min-width: 0; } @@ -6390,9 +6393,12 @@ dd { .collectionReviewSelectionAction { display: flex; + grid-column: 2; min-height: 38px; - align-items: center; + align-items: flex-start; + box-sizing: border-box; gap: 8px; + padding: 8px 0; } .collectionReviewSelectAll { @@ -7067,15 +7073,14 @@ dd { @media (max-width: 1100px) { .collectionReviewHeader { - align-items: stretch; - flex-direction: column; + grid-template-columns: minmax(0, 1fr); gap: 10px; } .collectionReviewActions { width: 100%; - align-items: flex-end; - justify-content: space-between; + grid-template-columns: 248px minmax(0, 210px); + justify-content: end; } .usageRankingControls { @@ -7171,13 +7176,11 @@ dd { } .collectionReviewHeader { - flex-direction: column; gap: 8px; } .collectionReviewActions { - align-items: stretch; - flex-direction: column; + grid-template-columns: minmax(0, 1fr); justify-content: flex-end; } @@ -7186,6 +7189,7 @@ dd { } .collectionReviewSelectionAction { + grid-column: 1; justify-content: flex-end; } diff --git a/crates/skillbox-core/src/tests.rs b/crates/skillbox-core/src/tests.rs index f056282..8398f5b 100644 --- a/crates/skillbox-core/src/tests.rs +++ b/crates/skillbox-core/src/tests.rs @@ -1841,31 +1841,35 @@ fn mutation_lock_preserves_parent_and_symlink_resolution_before_creation() { let executable = std::env::current_exe().unwrap(); for case in ["relative-parent", "symlink-parent"] { let root = temp_dir(&format!("managed-root-resolution-{case}")); - let holder_cwd; - let contender_cwd; - let holder_arg; - let contender_arg; - let expected; - if case == "relative-parent" { - holder_cwd = root.join("holder"); - contender_cwd = root.join("contender"); - fs::create_dir_all(&holder_cwd).unwrap(); - fs::create_dir_all(&contender_cwd).unwrap(); - holder_arg = PathBuf::from("../SkillBox"); - contender_arg = PathBuf::from("../SkillBox"); - expected = root.join("SkillBox"); - } else { - let real_parent = root.join("real"); - holder_cwd = root.join("holder"); - contender_cwd = root.join("contender"); - fs::create_dir_all(real_parent.join("child")).unwrap(); - fs::create_dir_all(&holder_cwd).unwrap(); - fs::create_dir_all(&contender_cwd).unwrap(); - std::os::unix::fs::symlink(real_parent.join("child"), root.join("alias")).unwrap(); - holder_arg = root.join("alias/../SkillBox"); - contender_arg = real_parent.join("SkillBox"); - expected = real_parent.join("SkillBox"); - } + let (holder_cwd, contender_cwd, holder_arg, contender_arg, expected) = + if case == "relative-parent" { + let holder_cwd = root.join("holder"); + let contender_cwd = root.join("contender"); + fs::create_dir_all(&holder_cwd).unwrap(); + fs::create_dir_all(&contender_cwd).unwrap(); + ( + holder_cwd, + contender_cwd, + PathBuf::from("../SkillBox"), + PathBuf::from("../SkillBox"), + root.join("SkillBox"), + ) + } else { + let real_parent = root.join("real"); + let holder_cwd = root.join("holder"); + let contender_cwd = root.join("contender"); + fs::create_dir_all(real_parent.join("child")).unwrap(); + fs::create_dir_all(&holder_cwd).unwrap(); + fs::create_dir_all(&contender_cwd).unwrap(); + std::os::unix::fs::symlink(real_parent.join("child"), root.join("alias")).unwrap(); + ( + holder_cwd, + contender_cwd, + root.join("alias/../SkillBox"), + real_parent.join("SkillBox"), + real_parent.join("SkillBox"), + ) + }; let barrier = temp_dir(&format!("managed-root-resolution-barrier-{case}")); let ready = barrier.join("ready"); let release = barrier.join("release");