From 2fe0128d4455d0279564646b84c71ec65a2f4d77 Mon Sep 17 00:00:00 2001 From: "Felix T.J. Dietrich" Date: Sun, 10 Nov 2024 17:53:32 +0100 Subject: [PATCH 1/7] initialize components --- .../workspace-add-button.component.ts | 15 +++++++++++++++ .../workspace-add-button.stories.ts | 13 +++++++++++++ .../workspace-badge/workspace-badge.component.ts | 14 ++++++++++++++ .../workspace-badge/workspace-badge.stories.ts | 13 +++++++++++++ .../workspace-option-selector.component.ts | 13 +++++++++++++ .../workspace-option-selector.stories.ts | 13 +++++++++++++ .../workspace-option.component.ts | 13 +++++++++++++ .../workspace-option/workspace-option.stories.ts | 13 +++++++++++++ .../workspace-sidebar.component.ts | 13 +++++++++++++ .../workspace-sidebar.stories.ts | 13 +++++++++++++ .../workspace-thumb/workspace-thumb.component.ts | 9 +++++++++ .../workspace-thumb/workspace-thumb.stories.ts | 13 +++++++++++++ 12 files changed, 155 insertions(+) create mode 100644 webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.component.ts create mode 100644 webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.stories.ts create mode 100644 webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts create mode 100644 webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts create mode 100644 webapp/src/app/core/workspace/workspace-option-selector/workspace-option-selector.component.ts create mode 100644 webapp/src/app/core/workspace/workspace-option-selector/workspace-option-selector.stories.ts create mode 100644 webapp/src/app/core/workspace/workspace-option/workspace-option.component.ts create mode 100644 webapp/src/app/core/workspace/workspace-option/workspace-option.stories.ts create mode 100644 webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.component.ts create mode 100644 webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.stories.ts create mode 100644 webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts create mode 100644 webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.stories.ts diff --git a/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.component.ts b/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.component.ts new file mode 100644 index 00000000..011b27e1 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-workspace-add-button', + standalone: true, + imports: [], + template: `

workspace-add-button works!

` +}) +export class WorkspaceAddButtonComponent { + // Two variants: + // - Compact for desktop + // - Full for mobile + // Opens sheet on mobile + // Popover on desktop +} diff --git a/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.stories.ts b/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.stories.ts new file mode 100644 index 00000000..93ea11ba --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.stories.ts @@ -0,0 +1,13 @@ +import { Meta, StoryObj } from '@storybook/angular'; +import { WorkspaceAddButtonComponent } from './workspace-add-button.component'; + +const meta: Meta = { + component: WorkspaceAddButtonComponent, + tags: ['autodocs'] +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts new file mode 100644 index 00000000..483b9a49 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-workspace-badge', + standalone: true, + imports: [], + template: `

workspace-badge works!

` +}) +export class WorkspaceBadgeComponent { + // Workspace thumb + text + // Opens sidebar on mobile + // Hides thumb on desktop + // Contains dropdown with workspace actions on desktop (in sidebar on mobile) +} diff --git a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts new file mode 100644 index 00000000..f92b8124 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts @@ -0,0 +1,13 @@ +import { Meta, StoryObj } from '@storybook/angular'; +import { WorkspaceBadgeComponent } from './workspace-badge.component'; + +const meta: Meta = { + component: WorkspaceBadgeComponent, + tags: ['autodocs'] +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/webapp/src/app/core/workspace/workspace-option-selector/workspace-option-selector.component.ts b/webapp/src/app/core/workspace/workspace-option-selector/workspace-option-selector.component.ts new file mode 100644 index 00000000..32f3741f --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-option-selector/workspace-option-selector.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-workspace-option-selector', + standalone: true, + imports: [], + template: `

workspace-option-selector works!

` +}) +export class WorkspaceOptionSelectorComponent { + // Two variants: + // - Compact for desktop with tooltip + // - Full for mobile as list container for the sidebar +} diff --git a/webapp/src/app/core/workspace/workspace-option-selector/workspace-option-selector.stories.ts b/webapp/src/app/core/workspace/workspace-option-selector/workspace-option-selector.stories.ts new file mode 100644 index 00000000..c19b2de9 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-option-selector/workspace-option-selector.stories.ts @@ -0,0 +1,13 @@ +import { Meta, StoryObj } from '@storybook/angular'; +import { WorkspaceOptionSelectorComponent } from './workspace-option-selector.component'; + +const meta: Meta = { + component: WorkspaceOptionSelectorComponent, + tags: ['autodocs'] +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/webapp/src/app/core/workspace/workspace-option/workspace-option.component.ts b/webapp/src/app/core/workspace/workspace-option/workspace-option.component.ts new file mode 100644 index 00000000..ec68ed66 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-option/workspace-option.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-workspace-option', + standalone: true, + imports: [], + template: `

workspace-option works!

` +}) +export class WorkspaceOptionComponent { + // Two variants: + // - Compact for desktop with tooltip + // - Full for mobile for sidebar with thumb and text +} diff --git a/webapp/src/app/core/workspace/workspace-option/workspace-option.stories.ts b/webapp/src/app/core/workspace/workspace-option/workspace-option.stories.ts new file mode 100644 index 00000000..ecb24d78 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-option/workspace-option.stories.ts @@ -0,0 +1,13 @@ +import { Meta, StoryObj } from '@storybook/angular'; +import { WorkspaceOptionComponent } from './workspace-option.component'; + +const meta: Meta = { + component: WorkspaceOptionComponent, + tags: ['autodocs'] +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.component.ts b/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.component.ts new file mode 100644 index 00000000..6c6e56a7 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-workspace-sidebar', + standalone: true, + imports: [], + template: `

workspace-sidebar works!

` +}) +export class WorkspaceSidebarComponent { + // Two variants: + // - Sidebar for desktop + // - Sheet for mobile +} diff --git a/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.stories.ts b/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.stories.ts new file mode 100644 index 00000000..b48a833a --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.stories.ts @@ -0,0 +1,13 @@ +import { Meta, StoryObj } from '@storybook/angular'; +import { WorkspaceSidebarComponent } from './workspace-sidebar.component'; + +const meta: Meta = { + component: WorkspaceSidebarComponent, + tags: ['autodocs'] +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts new file mode 100644 index 00000000..d6657ba8 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-workspace-thumb', + standalone: true, + imports: [], + template: `

workspace-thumb works!

` +}) +export class WorkspaceThumbComponent {} diff --git a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.stories.ts b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.stories.ts new file mode 100644 index 00000000..b2fb86a0 --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.stories.ts @@ -0,0 +1,13 @@ +import { Meta, StoryObj } from '@storybook/angular'; +import { WorkspaceThumbComponent } from './workspace-thumb.component'; + +const meta: Meta = { + component: WorkspaceThumbComponent, + tags: ['autodocs'] +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; From 9be0112124d0adc6f5cc39aa90420d1f6afcec09 Mon Sep 17 00:00:00 2001 From: "Felix T.J. Dietrich" Date: Sun, 10 Nov 2024 19:56:34 +0100 Subject: [PATCH 2/7] implement thumb --- .../workspace-thumb.component.ts | 38 +++++++++++++++++-- .../workspace-thumb.stories.ts | 38 ++++++++++++++++++- .../fallback/hlm-avatar-fallback.directive.ts | 2 +- .../src/lib/hlm-avatar.component.ts | 18 +++++++-- 4 files changed, 87 insertions(+), 9 deletions(-) diff --git a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts index d6657ba8..091cc19e 100644 --- a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts +++ b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts @@ -1,9 +1,39 @@ -import { Component } from '@angular/core'; +import { Component, computed, input, output } from '@angular/core'; +import { LucideAngularModule, Hammer } from 'lucide-angular'; +import { HlmAvatarModule } from '@spartan-ng/ui-avatar-helm'; +import { hlm } from '@spartan-ng/ui-core'; @Component({ selector: 'app-workspace-thumb', standalone: true, - imports: [], - template: `

workspace-thumb works!

` + imports: [HlmAvatarModule, LucideAngularModule], + template: ` + + ` }) -export class WorkspaceThumbComponent {} +export class WorkspaceThumbComponent { + protected Hammer = Hammer; + + isSelected = input(); + ringEnabled = input(true); + iconUrl = input(); + onClick = output(); + + computedClass = computed(() => { + return hlm( + 'rounded-md ring-offset-background ring-offset-2 duration-200 transition-all', + this.ringEnabled() && (this.isSelected() ? 'ring-2 ring-primary' : 'hover:ring-2 hover:ring-muted-foreground/50') + ); + }); + + handleClick(event: MouseEvent) { + this.onClick.emit(event); + } +} diff --git a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.stories.ts b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.stories.ts index b2fb86a0..391ecb91 100644 --- a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.stories.ts +++ b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.stories.ts @@ -1,9 +1,27 @@ import { Meta, StoryObj } from '@storybook/angular'; import { WorkspaceThumbComponent } from './workspace-thumb.component'; +import { fn } from '@storybook/test'; const meta: Meta = { component: WorkspaceThumbComponent, - tags: ['autodocs'] + tags: ['autodocs'], + args: { + isSelected: false, + ringEnabled: true, + iconUrl: 'https://avatars.githubusercontent.com/u/11064260?s=48&v=4', + onClick: fn() + }, + argTypes: { + isSelected: { + control: { type: 'boolean' } + }, + ringEnabled: { + control: { type: 'boolean' } + }, + iconUrl: { + control: { type: 'text' } + } + } }; export default meta; @@ -11,3 +29,21 @@ export default meta; type Story = StoryObj; export const Default: Story = {}; + +export const Selected: Story = { + args: { + isSelected: true + } +}; + +export const RingDisabled: Story = { + args: { + ringEnabled: false + } +}; + +export const NoIcon: Story = { + args: { + iconUrl: '' + } +}; diff --git a/webapp/src/libs/ui/ui-avatar-helm/src/lib/fallback/hlm-avatar-fallback.directive.ts b/webapp/src/libs/ui/ui-avatar-helm/src/lib/fallback/hlm-avatar-fallback.directive.ts index 0c2b8136..a56620c8 100644 --- a/webapp/src/libs/ui/ui-avatar-helm/src/lib/fallback/hlm-avatar-fallback.directive.ts +++ b/webapp/src/libs/ui/ui-avatar-helm/src/lib/fallback/hlm-avatar-fallback.directive.ts @@ -31,6 +31,6 @@ export class HlmAvatarFallbackDirective { }); protected readonly _computedClass = computed(() => { - return hlm('flex h-full w-full items-center justify-center rounded-full', this._autoColorTextCls() ?? 'bg-muted', this._brn?.userCls()); + return hlm('flex h-full w-full items-center justify-center', this._autoColorTextCls() ?? 'bg-muted', this._brn?.userCls()); }); } diff --git a/webapp/src/libs/ui/ui-avatar-helm/src/lib/hlm-avatar.component.ts b/webapp/src/libs/ui/ui-avatar-helm/src/lib/hlm-avatar.component.ts index afefdb0d..7dfa9b60 100644 --- a/webapp/src/libs/ui/ui-avatar-helm/src/lib/hlm-avatar.component.ts +++ b/webapp/src/libs/ui/ui-avatar-helm/src/lib/hlm-avatar.component.ts @@ -4,17 +4,22 @@ import { hlm } from '@spartan-ng/ui-core'; import { type VariantProps, cva } from 'class-variance-authority'; import type { ClassValue } from 'clsx'; -export const avatarVariants = cva('relative flex shrink-0 overflow-hidden rounded-full', { +export const avatarVariants = cva('relative flex shrink-0 overflow-hidden', { variants: { variant: { small: 'h-6 w-6 text-xs', medium: 'h-10 w-10', large: 'h-14 w-14 text-lg', extralarge: 'h-32 w-32 lg:h-40 lg:w-40 text-xl md:text-3xl' + }, + shape: { + circle: 'rounded-full', + square: 'rounded-md' } }, defaultVariants: { - variant: 'medium' + variant: 'medium', + shape: 'circle' } }); @@ -38,11 +43,18 @@ type AvatarVariants = VariantProps; }) export class HlmAvatarComponent extends BrnAvatarComponent { public readonly userClass = input('', { alias: 'class' }); - protected readonly _computedClass = computed(() => hlm(avatarVariants({ variant: this._variant() }), this.userClass())); + protected readonly _computedClass = computed(() => hlm(avatarVariants({ variant: this._variant(), shape: this._shape() }), this.userClass())); private readonly _variant = signal('medium'); + private readonly _shape = signal('circle'); + @Input() set variant(variant: AvatarVariants['variant']) { this._variant.set(variant); } + + @Input() + set shape(shape: AvatarVariants['shape']) { + this._shape.set(shape); + } } From c0ab230074a32458f16aa028a15a087fc6b45805 Mon Sep 17 00:00:00 2001 From: "Felix T.J. Dietrich" Date: Sun, 10 Nov 2024 20:17:30 +0100 Subject: [PATCH 3/7] implement workspace badge --- .../workspace-badge.component.ts | 24 ++++++++++++---- .../workspace-badge.stories.ts | 28 ++++++++++++++++++- .../workspace-thumb.component.ts | 4 +-- .../src/lib/hlm-avatar.component.ts | 1 + 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts index 483b9a49..fd1feb0a 100644 --- a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts +++ b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts @@ -1,14 +1,26 @@ -import { Component } from '@angular/core'; +import { Component, input } from '@angular/core'; +import { WorkspaceThumbComponent } from '../workspace-thumb/workspace-thumb.component'; @Component({ selector: 'app-workspace-badge', standalone: true, - imports: [], - template: `

workspace-badge works!

` + imports: [WorkspaceThumbComponent], + template: ` +
+
+ +
+ + {{ title() }} + +
+ ` }) export class WorkspaceBadgeComponent { - // Workspace thumb + text - // Opens sidebar on mobile - // Hides thumb on desktop + // Open sidebar on mobile, smaller than md + // Hide icon on desktop, show on mobile // Contains dropdown with workspace actions on desktop (in sidebar on mobile) + + title = input.required(); + iconUrl = input(); } diff --git a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts index f92b8124..61ee698e 100644 --- a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts +++ b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts @@ -3,7 +3,19 @@ import { WorkspaceBadgeComponent } from './workspace-badge.component'; const meta: Meta = { component: WorkspaceBadgeComponent, - tags: ['autodocs'] + tags: ['autodocs'], + args: { + iconUrl: 'https://avatars.githubusercontent.com/u/11064260?s=48&v=4', + title: 'AET TUM' + }, + argTypes: { + iconUrl: { + control: { type: 'text' } + }, + title: { + control: { type: 'text' } + } + } }; export default meta; @@ -11,3 +23,17 @@ export default meta; type Story = StoryObj; export const Default: Story = {}; + +Default.parameters = { + viewport: { + defaultViewport: 'responsive' + } +}; + +export const Mobile: Story = {}; + +Mobile.parameters = { + viewport: { + defaultViewport: 'mobile1' + } +}; diff --git a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts index 091cc19e..453aab7f 100644 --- a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts +++ b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts @@ -8,8 +8,8 @@ import { hlm } from '@spartan-ng/ui-core'; standalone: true, imports: [HlmAvatarModule, LucideAngularModule], template: ` - + } + +} + + + + + + + + diff --git a/webapp/src/app/core/workspace/workspace-option/workspace-option.component.ts b/webapp/src/app/core/workspace/workspace-option/workspace-option.component.ts index ec68ed66..85e41d3d 100644 --- a/webapp/src/app/core/workspace/workspace-option/workspace-option.component.ts +++ b/webapp/src/app/core/workspace/workspace-option/workspace-option.component.ts @@ -1,13 +1,45 @@ -import { Component } from '@angular/core'; +import { Component, computed, input, output } from '@angular/core'; +import { WorkspaceThumbComponent } from '../workspace-thumb/workspace-thumb.component'; +import { LucideAngularModule, Ellipsis, LogOut } from 'lucide-angular'; +import { hlm } from '@spartan-ng/ui-core'; +import { HlmTooltipComponent, HlmTooltipTriggerDirective } from '@spartan-ng/ui-tooltip-helm'; +import { BrnTooltipContentDirective } from '@spartan-ng/ui-tooltip-brain'; +import { BrnContextMenuTriggerDirective, BrnMenuTriggerDirective } from '@spartan-ng/ui-menu-brain'; +import { HlmMenuComponent, HlmMenuGroupComponent, HlmMenuItemDirective, HlmMenuItemIconDirective } from '@spartan-ng/ui-menu-helm'; @Component({ selector: 'app-workspace-option', standalone: true, - imports: [], - template: `

workspace-option works!

` + imports: [ + HlmTooltipComponent, + BrnContextMenuTriggerDirective, + HlmTooltipTriggerDirective, + BrnTooltipContentDirective, + BrnMenuTriggerDirective, + HlmMenuComponent, + HlmMenuItemDirective, + HlmMenuItemIconDirective, + HlmMenuGroupComponent, + WorkspaceThumbComponent, + LucideAngularModule + ], + templateUrl: './workspace-option.component.html' }) export class WorkspaceOptionComponent { + protected Ellipsis = Ellipsis; + protected LogOut = LogOut; + // Two variants: // - Compact for desktop with tooltip // - Full for mobile for sidebar with thumb and text + + isCompact = input.required(); + isSelected = input(); + iconUrl = input(); + title = input.required(); + + onSelect = output(); + onSignOut = output(); + + computedClass = computed(() => hlm('flex items-center gap-2 hover:bg-accent p-3 rounded-xl cursor-pointer duration-300 transition-all', this.isSelected() && 'bg-accent')); } diff --git a/webapp/src/app/core/workspace/workspace-option/workspace-option.stories.ts b/webapp/src/app/core/workspace/workspace-option/workspace-option.stories.ts index ecb24d78..2e49264b 100644 --- a/webapp/src/app/core/workspace/workspace-option/workspace-option.stories.ts +++ b/webapp/src/app/core/workspace/workspace-option/workspace-option.stories.ts @@ -1,9 +1,18 @@ import { Meta, StoryObj } from '@storybook/angular'; import { WorkspaceOptionComponent } from './workspace-option.component'; +import { fn } from '@storybook/test'; const meta: Meta = { component: WorkspaceOptionComponent, - tags: ['autodocs'] + tags: ['autodocs'], + args: { + isCompact: false, + isSelected: false, + iconUrl: 'https://avatars.githubusercontent.com/u/11064260?s=48&v=4', + title: 'AET TUM', + onSelect: fn(), + onSignOut: fn() + } }; export default meta; @@ -11,3 +20,18 @@ export default meta; type Story = StoryObj; export const Default: Story = {}; + +export const IsSelected: Story = { + args: { + isSelected: true + } +}; + +export const IsCompact: Story = { + args: { + isCompact: true + }, + parameters: { + layout: 'centered' + } +}; diff --git a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts index 453aab7f..2e128e2c 100644 --- a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts +++ b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts @@ -8,8 +8,8 @@ import { hlm } from '@spartan-ng/ui-core'; standalone: true, imports: [HlmAvatarModule, LucideAngularModule], template: ` - + ` }) export class WorkspaceAddButtonComponent { - // Two variants: - // - Compact for desktop - // - Full for mobile - // Opens sheet on mobile - // Popover on desktop + protected CirclePlus = CirclePlus; + protected Plus = Plus; + + isCompact = input.required(); + + computedClass = computed(() => hlm(this.isCompact() ? '' : 'flex gap-2 w-full justify-start')); } diff --git a/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.stories.ts b/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.stories.ts index 93ea11ba..19db74ac 100644 --- a/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.stories.ts +++ b/webapp/src/app/core/workspace/workspace-add-button/workspace-add-button.stories.ts @@ -3,7 +3,15 @@ import { WorkspaceAddButtonComponent } from './workspace-add-button.component'; const meta: Meta = { component: WorkspaceAddButtonComponent, - tags: ['autodocs'] + tags: ['autodocs'], + args: { + isCompact: false + }, + argTypes: { + isCompact: { + control: { type: 'boolean' } + } + } }; export default meta; @@ -11,3 +19,9 @@ export default meta; type Story = StoryObj; export const Default: Story = {}; + +export const IsCompact: Story = { + args: { + isCompact: true + } +}; diff --git a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.html b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.html new file mode 100644 index 00000000..6a199d4b --- /dev/null +++ b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.html @@ -0,0 +1,30 @@ +
+
+ + + + +

Workspaces

+
+ +
+ +
+
+ + + + +
+
+
+ + {{ selectedWorkspace().title }} + +
diff --git a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts index 5b5b3d20..57936cac 100644 --- a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts +++ b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.component.ts @@ -1,26 +1,40 @@ -import { Component, input } from '@angular/core'; +import { Component, input, output } from '@angular/core'; +import { BrnSheetContentDirective } from '@spartan-ng/ui-sheet-brain'; +import { HlmSheetComponent, HlmSheetContentComponent, HlmSheetFooterComponent, HlmSheetHeaderComponent, HlmSheetTitleDirective } from '@spartan-ng/ui-sheet-helm'; +import { HlmMenuSeparatorComponent } from '@spartan-ng/ui-menu-helm'; +import { HlmScrollAreaComponent } from '@spartan-ng/ui-scrollarea-helm'; import { WorkspaceThumbComponent } from '../workspace-thumb/workspace-thumb.component'; +import { WorkspaceOptionSelectorComponent } from '../workspace-option-selector/workspace-option-selector.component'; +import { WorkspaceAddButtonComponent } from '../workspace-add-button/workspace-add-button.component'; + +type Workspace = { + id: string; + title: string; + iconUrl: string; +}; @Component({ selector: 'app-workspace-badge', standalone: true, - imports: [WorkspaceThumbComponent], - template: ` -
-
- -
- - {{ title() }} - -
- ` + imports: [ + BrnSheetContentDirective, + HlmSheetComponent, + HlmSheetContentComponent, + HlmSheetHeaderComponent, + HlmSheetFooterComponent, + HlmSheetTitleDirective, + HlmScrollAreaComponent, + HlmMenuSeparatorComponent, + WorkspaceThumbComponent, + WorkspaceOptionSelectorComponent, + WorkspaceAddButtonComponent + ], + templateUrl: './workspace-badge.component.html' }) export class WorkspaceBadgeComponent { - // Open sidebar on mobile, smaller than md - // Hide icon on desktop, show on mobile - // Contains dropdown with workspace actions on desktop (in sidebar on mobile) + selectedWorkspace = input.required(); + workspaces = input.required(); - title = input.required(); - iconUrl = input(); + onSelect = output(); + onSignOut = output(); } diff --git a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts index 88ae6f0e..7b49e7a6 100644 --- a/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts +++ b/webapp/src/app/core/workspace/workspace-badge/workspace-badge.stories.ts @@ -1,19 +1,40 @@ import { Meta, StoryObj } from '@storybook/angular'; import { WorkspaceBadgeComponent } from './workspace-badge.component'; +import { fn } from '@storybook/test'; + +const workspaces = [ + { + id: '1', + title: 'AET TUM', + iconUrl: 'https://avatars.githubusercontent.com/u/11064260?s=48&v=4' + }, + { + id: '2', + title: 'Hephaestus', + iconUrl: '' + }, + { + id: '3', + title: 'Intro Course', + iconUrl: 'https://avatars.githubusercontent.com/u/11064260?s=48&v=4' + } +]; const meta: Meta = { component: WorkspaceBadgeComponent, tags: ['autodocs'], args: { - iconUrl: 'https://avatars.githubusercontent.com/u/11064260?s=48&v=4', - title: 'AET TUM' + selectedWorkspace: workspaces[0], + workspaces, + onSelect: fn(), + onSignOut: fn() }, argTypes: { - iconUrl: { - control: { type: 'text' } + selectedWorkspace: { + control: { type: 'object' } }, - title: { - control: { type: 'text' } + workspaces: { + control: { type: 'object' } } } }; diff --git a/webapp/src/app/core/workspace/workspace-option/workspace-option.component.html b/webapp/src/app/core/workspace/workspace-option/workspace-option.component.html index d3f9420c..8e4b0b93 100644 --- a/webapp/src/app/core/workspace/workspace-option/workspace-option.component.html +++ b/webapp/src/app/core/workspace/workspace-option/workspace-option.component.html @@ -13,13 +13,13 @@ } @else {
- - + + {{ title() }} @if (isSelected()) { }
diff --git a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts index 2e128e2c..7622769b 100644 --- a/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts +++ b/webapp/src/app/core/workspace/workspace-thumb/workspace-thumb.component.ts @@ -1,18 +1,19 @@ import { Component, computed, input, output } from '@angular/core'; import { LucideAngularModule, Hammer } from 'lucide-angular'; import { HlmAvatarModule } from '@spartan-ng/ui-avatar-helm'; +import { BrnSheetTriggerDirective } from '@spartan-ng/ui-sheet-brain'; import { hlm } from '@spartan-ng/ui-core'; @Component({ selector: 'app-workspace-thumb', standalone: true, - imports: [HlmAvatarModule, LucideAngularModule], + imports: [BrnSheetTriggerDirective, HlmAvatarModule, LucideAngularModule], template: ` - @@ -21,7 +22,7 @@ import { hlm } from '@spartan-ng/ui-core'; export class WorkspaceThumbComponent { protected Hammer = Hammer; - variant = input<'base' | 'medium'>('base'); + variant = input<'small' | 'base' | 'medium'>('base'); isSelected = input(); hoverRingEnabled = input(true); iconUrl = input(); diff --git a/webapp/src/libs/ui/ui-avatar-helm/src/lib/hlm-avatar.component.ts b/webapp/src/libs/ui/ui-avatar-helm/src/lib/hlm-avatar.component.ts index acf3cee9..dac6d6e2 100644 --- a/webapp/src/libs/ui/ui-avatar-helm/src/lib/hlm-avatar.component.ts +++ b/webapp/src/libs/ui/ui-avatar-helm/src/lib/hlm-avatar.component.ts @@ -8,7 +8,7 @@ export const avatarVariants = cva('relative flex shrink-0 overflow-hidden', { variants: { variant: { small: 'h-6 w-6 text-xs', - base: 'h-8 w-8 text-sm', + base: 'h-7 w-7 text-sm', medium: 'h-10 w-10', large: 'h-14 w-14 text-lg', extralarge: 'h-32 w-32 lg:h-40 lg:w-40 text-xl md:text-3xl' From 9232fc47da1d01a6f18a618937780f189d30bde3 Mon Sep 17 00:00:00 2001 From: "Felix T.J. Dietrich" Date: Sun, 10 Nov 2024 23:26:45 +0100 Subject: [PATCH 7/7] remove sidebar --- .../workspace-sidebar.component.ts | 13 ------------- .../workspace-sidebar/workspace-sidebar.stories.ts | 13 ------------- 2 files changed, 26 deletions(-) delete mode 100644 webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.component.ts delete mode 100644 webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.stories.ts diff --git a/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.component.ts b/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.component.ts deleted file mode 100644 index 6c6e56a7..00000000 --- a/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-workspace-sidebar', - standalone: true, - imports: [], - template: `

workspace-sidebar works!

` -}) -export class WorkspaceSidebarComponent { - // Two variants: - // - Sidebar for desktop - // - Sheet for mobile -} diff --git a/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.stories.ts b/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.stories.ts deleted file mode 100644 index b48a833a..00000000 --- a/webapp/src/app/core/workspace/workspace-sidebar/workspace-sidebar.stories.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Meta, StoryObj } from '@storybook/angular'; -import { WorkspaceSidebarComponent } from './workspace-sidebar.component'; - -const meta: Meta = { - component: WorkspaceSidebarComponent, - tags: ['autodocs'] -}; - -export default meta; - -type Story = StoryObj; - -export const Default: Story = {};