This commit is contained in:
Juergen Kunz
2025-06-27 23:48:39 +00:00
parent 811737adcd
commit 7e14645ed7
2 changed files with 367 additions and 88 deletions

View File

@ -15,6 +15,21 @@ Update multiple components with shadcn-aligned styling and improved animations
- Added visual separators between tabs for better distinction
- Added subtle hover backgrounds for improved interactivity
- Refactored tabs component code for better maintainability and elegance
- Updated dees-appui-activitylog with shadcn-aligned styling:
- Updated background and text colors to match shadcn palette
- Enhanced topbar with better spacing and typography
- Improved activity entries with subtle hover states and better spacing
- Added activity type icons with color-coded backgrounds (login, logout, view, create, update)
- Added date separators ("Today", "Yesterday") for better temporal organization
- Enhanced streaming indicators with animated pulse effect
- Redesigned searchbox with modern input styling, search icon, and focus states
- Added custom scrollbar styling for consistency
- Updated timestamps to be more subtle with tabular number formatting
- Refined shadow effects for better visual hierarchy
- Added subtle box shadow to component for depth
- Added fade-in animation for new activity entries
- Improved user name highlighting with better typography
- Updated context menu with more relevant actions
- Improved overall spacing and visual consistency across components
## 2025-06-27 - 1.10.1 - fix(modal)

View File

@ -11,27 +11,46 @@ import {
import * as domtools from '@design.estate/dees-domtools';
import { DeesContextmenu } from './dees-contextmenu.js';
import './dees-icon.js';
@customElement('dees-appui-activitylog')
export class DeesAppuiActivitylog extends DeesElement {
// STATIC
public static demo = () => html`<dees-appui-activitylog></dees-appui-activitylog>`;
public static demo = () => html`
<style>
.demo-container {
display: flex;
justify-content: center;
align-items: center;
height: 600px;
background: ${cssManager.bdTheme('#f4f4f5', '#09090b')};
padding: 32px;
}
</style>
<div class="demo-container">
<dees-appui-activitylog></dees-appui-activitylog>
</div>
`;
// INSTANCE
public static styles = [
cssManager.defaultStyles,
css`
:host {
color: ${cssManager.bdTheme('#333', '#fff')};
color: ${cssManager.bdTheme('#09090b', '#fafafa')};
position: relative;
display: block;
width: 100%;
max-width: 300px;
max-width: 320px;
height: 100%;
background: ${cssManager.bdTheme('#f8f8f8', '#111c28')};
font-family: 'Intel One Mono', sans-serif;
border-left: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
font-family: 'Geist Mono', monospace;
border-left: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
cursor: default;
box-shadow: ${cssManager.bdTheme(
'-4px 0 12px rgba(0, 0, 0, 0.02)',
'-4px 0 12px rgba(0, 0, 0, 0.2)'
)};
}
.maincontainer {
position: absolute;
@ -44,108 +63,265 @@ export class DeesAppuiActivitylog extends DeesElement {
.topbar {
position: absolute;
top: 0px;
height: 32px;
height: 40px;
width: 100%;
padding: 0px 12px 0px 12px;
background: ${cssManager.bdTheme('#ffffff', '#0e151f')};
border-bottom: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
padding: 0px 16px;
background: ${cssManager.bdTheme('#ffffff', '#09090b')};
border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
display: flex;
align-items: center;
}
.topbar .heading {
text-align: left;
line-height: 24px;
padding-top: 8px;
font-weight: 500;
font-weight: 600;
font-size: 14px;
font-family: 'Geist Sans', sans-serif;
color: ${cssManager.bdTheme('#666', '#ccc')};
color: ${cssManager.bdTheme('#09090b', '#fafafa')};
}
.activityContainer {
position: absolute;
top: 32px;
bottom: 40px;
top: 40px;
bottom: 48px;
width: 100%;
padding: 8px 0px;
overflow-y: scroll;
padding: 12px 0px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: ${cssManager.bdTheme('#e5e7eb', '#27272a')} transparent;
}
.activityContainer::-webkit-scrollbar {
width: 6px;
}
.activityContainer::-webkit-scrollbar-track {
background: transparent;
}
.activityContainer::-webkit-scrollbar-thumb {
background: ${cssManager.bdTheme('#e5e7eb', '#27272a')};
border-radius: 3px;
}
.activityContainer::-webkit-scrollbar-thumb:hover {
background: ${cssManager.bdTheme('#d4d4d8', '#3f3f46')};
}
.streamingIndicator {
font-size: 12px;
font-size: 11px;
text-align: center;
padding-top: 16px;
color: ${cssManager.bdTheme('#666', '#888')}
padding: 16px;
color: ${cssManager.bdTheme('#71717a', '#71717a')};
font-family: 'Geist Sans', sans-serif;
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.streamingIndicator::before {
content: '';
width: 6px;
height: 6px;
background: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
border-radius: 50%;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 0.4; transform: scale(0.8); }
50% { opacity: 1; transform: scale(1.2); }
}
.streamingIndicator.bottom {
padding-top: 0px;
padding-top: 8px;
padding-bottom: 16px;
}
.activityentry {
min-height: 30px;
font-size: 12px;
padding: 8px 16px;
border-bottom: 1px dotted ${cssManager.bdTheme('#00000020', '#ffffff20')};
min-height: 36px;
font-size: 13px;
padding: 10px 16px;
border-bottom: 1px solid ${cssManager.bdTheme('#f4f4f5', '#18181b')};
transition: all 0.15s ease;
display: flex;
align-items: center;
gap: 8px;
line-height: 1.4;
animation: fadeIn 0.3s ease-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-4px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.activityentry:last-of-type {
border-bottom: 1px solid transparent;
border-bottom: none;
}
.activityentry:hover {
background: ${cssManager.bdTheme('#00000005', '#00000080')};
background: ${cssManager.bdTheme('#f4f4f5', '#18181b')};
}
.timestamp {
color: ${cssManager.bdTheme('#e57373', '#ff8787')};
color: ${cssManager.bdTheme('#71717a', '#71717a')};
font-weight: 500;
font-size: 12px;
font-variant-numeric: tabular-nums;
flex-shrink: 0;
min-width: 45px;
}
.activity-icon {
width: 28px;
height: 28px;
border-radius: 6px;
background: ${cssManager.bdTheme('#f4f4f5', '#18181b')};
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 14px;
}
.activity-icon.login {
background: ${cssManager.bdTheme('rgba(34, 197, 94, 0.1)', 'rgba(34, 197, 94, 0.1)')};
color: ${cssManager.bdTheme('#16a34a', '#22c55e')};
}
.activity-icon.logout {
background: ${cssManager.bdTheme('rgba(239, 68, 68, 0.1)', 'rgba(239, 68, 68, 0.1)')};
color: ${cssManager.bdTheme('#dc2626', '#ef4444')};
}
.activity-icon.view {
background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.1)', 'rgba(59, 130, 246, 0.1)')};
color: ${cssManager.bdTheme('#2563eb', '#3b82f6')};
}
.activity-icon.create {
background: ${cssManager.bdTheme('rgba(168, 85, 247, 0.1)', 'rgba(168, 85, 247, 0.1)')};
color: ${cssManager.bdTheme('#9333ea', '#a855f7')};
}
.activity-icon.update {
background: ${cssManager.bdTheme('rgba(251, 146, 60, 0.1)', 'rgba(251, 146, 60, 0.1)')};
color: ${cssManager.bdTheme('#ea580c', '#fb923c')};
}
.activity-text {
flex: 1;
color: ${cssManager.bdTheme('#18181b', '#e4e4e7')};
}
.activity-user {
font-weight: 600;
color: ${cssManager.bdTheme('#09090b', '#fafafa')};
}
.date-separator {
padding: 12px 16px 8px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: ${cssManager.bdTheme('#71717a', '#71717a')};
background: ${cssManager.bdTheme('#f9fafb', '#09090b')};
border-bottom: 1px solid ${cssManager.bdTheme('#f4f4f5', '#18181b')};
position: sticky;
top: 0;
z-index: 1;
}
.searchbox {
position: absolute;
bottom: 0px;
width: 100%;
height: 40px;
background: ${cssManager.bdTheme('#ffffff', '#0e151f')};
border-top: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
height: 48px;
background: ${cssManager.bdTheme('#ffffff', '#09090b')};
border-top: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
padding: 8px;
}
.searchbox input {
color: ${cssManager.bdTheme('#333', '#fff')};
background: none;
.search-wrapper {
position: relative;
width: 100%;
height: 40px;
line-height: 32px;
border: none;
padding: 4px 12px;
font-family: 'Intel One Mono', sans-serif;
height: 32px;
}
.search-icon {
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
color: ${cssManager.bdTheme('#71717a', '#71717a')};
font-size: 14px;
pointer-events: none;
transition: color 0.15s ease;
}
.searchbox input {
color: ${cssManager.bdTheme('#09090b', '#fafafa')};
background: ${cssManager.bdTheme('#f4f4f5', '#18181b')};
width: 100%;
height: 100%;
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
border-radius: 6px;
padding: 0 12px 0 36px;
font-family: 'Geist Sans', sans-serif;
font-size: 13px;
transition: all 0.15s ease;
}
.searchbox input::placeholder {
color: ${cssManager.bdTheme('#71717a', '#71717a')};
}
.searchbox input:focus {
outline: none;
border-color: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(59, 130, 246, 0.1)', 'rgba(59, 130, 246, 0.1)')};
}
.searchbox input:focus ~ .search-icon,
.search-wrapper:has(input:focus) .search-icon {
color: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
}
.bottomShadow {
position: absolute;
width: 100%;
height: 32px;
bottom: 40px;
height: 24px;
bottom: 48px;
background: ${cssManager.bdTheme(
'linear-gradient(180deg, #f8f8f800 0%, #ffffff 100%)',
'linear-gradient(180deg, #111c2800 0%, #0e151f 100%)'
'linear-gradient(180deg, transparent 0%, #fafafa 100%)',
'linear-gradient(180deg, transparent 0%, #0a0a0a 100%)'
)};
pointer-events: none;
opacity: 0.8;
}
.topShadow {
position: absolute;
width: 100%;
height: 32px;
top: 32px;
height: 24px;
top: 40px;
background: ${cssManager.bdTheme(
'linear-gradient(0deg, #f8f8f800 0%, #ffffff 100%)',
'linear-gradient(0deg, #111c2800 0%, #0e151f 100%)'
'linear-gradient(0deg, transparent 0%, #fafafa 100%)',
'linear-gradient(0deg, transparent 0%, #0a0a0a 100%)'
)};
pointer-events: none;
opacity: 0.8;
}
`,
];
@ -159,86 +335,174 @@ export class DeesAppuiActivitylog extends DeesElement {
<div class="heading">Activity Log</div>
</div>
<div class="activityContainer">
<div class="streamingIndicator">streaming...</div>
<div class="streamingIndicator">Live Updates</div>
<div class="date-separator">Today</div>
<div class="activityentry" @contextmenu=${async eventArg => {
DeesContextmenu.openContextMenuWithOptions(eventArg, [
{
name: 'app settings',
name: 'Copy activity',
action: async () => {},
},
{
name: 'account settings',
name: 'View details',
action: async () => {},
},
{
name: 'logout',
name: 'Filter by user',
action: async () => {},
},
]);
}}>
<span class="timestamp">22:01:</span> Max Mustermann logged in
<span class="timestamp">22:20</span>
<div class="activity-icon logout">
<dees-icon .icon=${'lucide:logOut'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> logged out
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:02:</span> Max Mustermann viewed an invoice
<span class="timestamp">22:19</span>
<div class="activity-icon update">
<dees-icon .icon=${'lucide:checkCircle'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> approved a payment
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:03:</span> Max Mustermann added a new contact
<span class="timestamp">22:18</span>
<div class="activity-icon view">
<dees-icon .icon=${'lucide:archive'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> archived an invoice
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:04:</span> Max Mustermann updated account settings
<span class="timestamp">22:17</span>
<div class="activity-icon login">
<dees-icon .icon=${'lucide:logIn'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> logged in
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:05:</span> Max Mustermann logged out
<span class="timestamp">22:16</span>
<div class="activity-icon logout">
<dees-icon .icon=${'lucide:logOut'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> logged out
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:06:</span> Max Mustermann logged in
<span class="timestamp">22:15</span>
<div class="activity-icon update">
<dees-icon .icon=${'lucide:key'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> changed password
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:07:</span> Max Mustermann created a new invoice
<span class="timestamp">22:14</span>
<div class="activity-icon create">
<dees-icon .icon=${'lucide:userPlus'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> added a new user
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:08:</span> Max Mustermann sent an invoice
<span class="timestamp">22:13</span>
<div class="activity-icon view">
<dees-icon .icon=${'lucide:messageCircle'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> contacted support
</div>
</div>
<div class="date-separator">Yesterday</div>
<div class="activityentry">
<span class="timestamp">22:09:</span> Max Mustermann viewed reports
<span class="timestamp">18:45</span>
<div class="activity-icon update">
<dees-icon .icon=${'lucide:trash2'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> deleted an invoice
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:10:</span> Max Mustermann logged out
<span class="timestamp">17:30</span>
<div class="activity-icon login">
<dees-icon .icon=${'lucide:logIn'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> logged in
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:11:</span> Max Mustermann logged in
<span class="timestamp">16:15</span>
<div class="activity-icon logout">
<dees-icon .icon=${'lucide:logOut'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> logged out
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:12:</span> Max Mustermann deleted an invoice
<span class="timestamp">14:20</span>
<div class="activity-icon view">
<dees-icon .icon=${'lucide:barChart'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> viewed reports
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:13:</span> Max Mustermann contacted support
<span class="timestamp">13:45</span>
<div class="activity-icon create">
<dees-icon .icon=${'lucide:send'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> sent an invoice
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:14:</span> Max Mustermann added a new user
<span class="timestamp">13:30</span>
<div class="activity-icon create">
<dees-icon .icon=${'lucide:filePlus'}></dees-icon>
</div>
<div class="activity-text">
<span class="activity-user">Max Mustermann</span> created a new invoice
</div>
</div>
<div class="activityentry">
<span class="timestamp">22:15:</span> Max Mustermann changed password
</div>
<div class="activityentry">
<span class="timestamp">22:16:</span> Max Mustermann logged out
</div>
<div class="activityentry">
<span class="timestamp">22:17:</span> Max Mustermann logged in
</div>
<div class="activityentry">
<span class="timestamp">22:18:</span> Max Mustermann archived an invoice
</div>
<div class="activityentry">
<span class="timestamp">22:19:</span> Max Mustermann approved a payment
</div>
<div class="activityentry">
<span class="timestamp">22:20:</span> Max Mustermann logged out
</div>
<div class="streamingIndicator bottom">loading more...</div>
<div class="streamingIndicator bottom">Loading History</div>
</div>
<div class="searchbox">
<input type="text" placeholder="Search" />
<div class="search-wrapper">
<dees-icon class="search-icon" .icon=${'lucide:search'}></dees-icon>
<input type="text" placeholder="Search activities, users..." />
</div>
</div>
<div class="topShadow"></div>
<div class="bottomShadow"></div>