diff --git a/frontend/src/components/DevicePosture.svelte b/frontend/src/components/DevicePosture.svelte index 492909c..cb7aa62 100644 --- a/frontend/src/components/DevicePosture.svelte +++ b/frontend/src/components/DevicePosture.svelte @@ -42,18 +42,6 @@ } } - function setScoreFilter(val: '' | 'low' | 'medium') { - filterScore = filterScore === val ? '' : val; - currentPage = 0; - load(0); - } - - function setEolFilter(val: OsEolStatus | '') { - filterEol = filterEol === val ? '' : val; - currentPage = 0; - load(0); - } - function clearAllFilters() { filterScore = ''; filterEol = ''; @@ -141,24 +129,23 @@
-
- - -
+
-
- - - -
+
{/if} @@ -441,10 +428,8 @@ .filter-section { display: flex; flex-direction: column; gap: 0.3rem; } .filter-section-label { font-size: var(--font-size-tiny); font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.5px; } - .status-pills { display: flex; flex-direction: column; gap: 4px; } - .status-pill { padding: 5px 10px; border-radius: 6px; border: 1px solid #d1d5db; background: white; font-size: var(--font-size-caption); font-weight: 500; cursor: pointer; color: #374151; text-align: left; transition: all 0.15s; } - .status-pill:hover { border-color: #2563eb; color: #2563eb; background: #eff6ff; } - .status-pill.active { background: #2563eb; color: white; border-color: #2563eb; } + .filter-select { padding: 0.4rem 0.6rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: var(--font-size-body-sm); width: 100%; background: white; color: #374151; } + .filter-select:focus { outline: none; border-color: #3b82f6; } .sidebar-clear-all-btn { border: none; background: #fee2e2; color: #dc2626; border-radius: 4px; padding: 0.3rem 0.6rem; cursor: pointer; font-size: var(--font-size-tiny); font-weight: 600; text-align: left; } .sidebar-clear-all-btn:hover { background: #fecaca; } @@ -595,9 +580,7 @@ :global(.dark-mode) .filter-sidebar-title { color: #9ca3af; } :global(.dark-mode) .sidebar-toggle-btn { border-color: #4b5563; color: #9ca3af; } :global(.dark-mode) .sidebar-toggle-btn:hover { background: #374151; } - :global(.dark-mode) .status-pill { background: #1e293b; border-color: #334155; color: #94a3b8; } - :global(.dark-mode) .status-pill:hover { background: #1e2d4a; border-color: #2563eb; color: #93c5fd; } - :global(.dark-mode) .status-pill.active { background: #2563eb; color: white; } + :global(.dark-mode) .filter-select { background: #283040; border-color: #4b5563; color: #e2e8f0; } :global(.dark-mode) .sidebar-stat-pill { background: #1e2d4a; border-color: #3730a3; color: #93c5fd; } :global(.dark-mode) .sidebar-clear-all-btn { background: #3b1a1a; color: #f87171; } diff --git a/frontend/src/components/PrecursorAlerts.svelte b/frontend/src/components/PrecursorAlerts.svelte index aa26e29..a164fa0 100644 --- a/frontend/src/components/PrecursorAlerts.svelte +++ b/frontend/src/components/PrecursorAlerts.svelte @@ -80,18 +80,6 @@ } } - function setStatusFilter(val: 'active' | 'resolved' | 'all') { - filterStatus = filterStatus === val ? 'all' : val; - currentPage = 0; - load(0); - } - - function setTypeFilter(val: SequenceType | '') { - filterType = filterType === val ? '' : val; - currentPage = 0; - load(0); - } - function onDeviceInput() { clearTimeout(deviceSearchTimer); deviceSearchTimer = setTimeout(() => { @@ -175,24 +163,23 @@
-
- - -
+
-
- - - -
+
{/if} @@ -467,10 +454,8 @@ .search-input { padding: 0.4rem 0.6rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: var(--font-size-body-sm); width: 100%; background: white; } .search-input:focus { outline: none; border-color: #3b82f6; } - .status-pills { display: flex; flex-direction: column; gap: 4px; } - .status-pill { padding: 5px 10px; border-radius: 6px; border: 1px solid #d1d5db; background: white; font-size: var(--font-size-caption); font-weight: 500; cursor: pointer; color: #374151; text-align: left; transition: all 0.15s; } - .status-pill:hover { border-color: #2563eb; color: #2563eb; background: #eff6ff; } - .status-pill.active { background: #2563eb; color: white; border-color: #2563eb; } + .filter-select { padding: 0.4rem 0.6rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: var(--font-size-body-sm); width: 100%; background: white; color: #374151; } + .filter-select:focus { outline: none; border-color: #3b82f6; } .sidebar-clear-all-btn { border: none; background: #fee2e2; color: #dc2626; border-radius: 4px; padding: 0.3rem 0.6rem; cursor: pointer; font-size: var(--font-size-tiny); font-weight: 600; text-align: left; } .sidebar-clear-all-btn:hover { background: #fecaca; } @@ -636,9 +621,7 @@ :global(.dark-mode) .sidebar-toggle-btn { border-color: #4b5563; color: #9ca3af; } :global(.dark-mode) .sidebar-toggle-btn:hover { background: #374151; } :global(.dark-mode) .search-input { background: #283040; border-color: #4b5563; color: #e2e8f0; } - :global(.dark-mode) .status-pill { background: #1e293b; border-color: #334155; color: #94a3b8; } - :global(.dark-mode) .status-pill:hover { background: #1e2d4a; border-color: #2563eb; color: #93c5fd; } - :global(.dark-mode) .status-pill.active { background: #2563eb; color: white; } + :global(.dark-mode) .filter-select { background: #283040; border-color: #4b5563; color: #e2e8f0; } :global(.dark-mode) .sidebar-stat-pill { background: #1e2d4a; border-color: #3730a3; color: #93c5fd; } :global(.dark-mode) .sidebar-clear-all-btn { background: #3b1a1a; color: #f87171; } diff --git a/src/main/resources/db/migration/V3__convert_enums_to_varchar.sql b/src/main/resources/db/migration/V3__convert_enums_to_varchar.sql index a88e905..81743de 100644 --- a/src/main/resources/db/migration/V3__convert_enums_to_varchar.sql +++ b/src/main/resources/db/migration/V3__convert_enums_to_varchar.sql @@ -3,18 +3,20 @@ -- named enum types reject implicit varchar casts on both INSERT and SELECT. ALTER TABLE threat_event - ALTER COLUMN severity TYPE VARCHAR(20) USING severity::VARCHAR, - ALTER COLUMN event_type TYPE VARCHAR(30) USING event_type::VARCHAR, - ALTER COLUMN attack_phase TYPE VARCHAR(40) USING attack_phase::VARCHAR; + ALTER COLUMN severity TYPE VARCHAR(20) USING severity::VARCHAR, + ALTER COLUMN event_type TYPE VARCHAR(30) USING event_type::VARCHAR, + ALTER COLUMN attack_phase TYPE VARCHAR(40) USING attack_phase::VARCHAR; ALTER TABLE threat_ioc - ALTER COLUMN ioc_type TYPE VARCHAR(30) USING ioc_type::VARCHAR, - ALTER COLUMN ioc_source TYPE VARCHAR(20) USING ioc_source::VARCHAR, - ALTER COLUMN confidence_level TYPE VARCHAR(10) USING confidence_level::VARCHAR; + ALTER COLUMN ioc_type TYPE VARCHAR(30) USING ioc_type::VARCHAR, + ALTER COLUMN source TYPE VARCHAR(20) USING source::VARCHAR, + ALTER COLUMN confidence TYPE VARCHAR(10) USING confidence::VARCHAR; +-- phases_detected is attack_phase[] array; convert to TEXT[] ALTER TABLE precursor_sequence_alert - ALTER COLUMN sequence_type TYPE VARCHAR(20) USING sequence_type::VARCHAR, - ALTER COLUMN auto_response_action TYPE VARCHAR(20) USING auto_response_action::VARCHAR; + ALTER COLUMN sequence_type TYPE VARCHAR(20) USING sequence_type::VARCHAR, + ALTER COLUMN auto_response_taken TYPE VARCHAR(20) USING auto_response_taken::VARCHAR, + ALTER COLUMN phases_detected TYPE TEXT[] USING phases_detected::TEXT[]; ALTER TABLE device_security_posture ALTER COLUMN os_eol_status TYPE VARCHAR(20) USING os_eol_status::VARCHAR;