diff --git a/e2e/constants/selectors.ts b/e2e/constants/selectors.ts
index b0e961e3ec..d0206e7ce1 100644
--- a/e2e/constants/selectors.ts
+++ b/e2e/constants/selectors.ts
@@ -128,7 +128,7 @@ export const cssSelectors = {
// TASK DETAIL PANEL SELECTORS
// ============================================================================
RIGHT_PANEL: '.right-panel',
- DETAIL_PANEL: 'dialog-task-detail-panel, task-detail-panel',
+ DETAIL_PANEL: 'task-detail-panel',
DETAIL_PANEL_BTN: '.show-additional-info-btn',
SCHEDULE_TASK_ITEM:
'task-detail-item:has(mat-icon:text("alarm")), task-detail-item:has(mat-icon:text("today")), task-detail-item:has(mat-icon:text("schedule"))',
diff --git a/e2e/utils/schedule-task-helper.ts b/e2e/utils/schedule-task-helper.ts
index 3401e2a69a..0249f484c7 100644
--- a/e2e/utils/schedule-task-helper.ts
+++ b/e2e/utils/schedule-task-helper.ts
@@ -4,7 +4,7 @@ import { fillTimeInput } from './time-input-helper';
// Selectors for scheduling
const DETAIL_PANEL_BTN = '.show-additional-info-btn';
-const DETAIL_PANEL_SELECTOR = 'dialog-task-detail-panel, task-detail-panel';
+const DETAIL_PANEL_SELECTOR = 'task-detail-panel';
const DETAIL_PANEL_SCHEDULE_ITEM =
'task-detail-item:has(mat-icon:text("alarm")), ' +
'task-detail-item:has(mat-icon:text("today")), ' +
diff --git a/scripts/remove-unused-log-imports.ts b/scripts/remove-unused-log-imports.ts
index da9b7656b1..348065ee71 100644
--- a/scripts/remove-unused-log-imports.ts
+++ b/scripts/remove-unused-log-imports.ts
@@ -15,7 +15,6 @@ const filesToFix = [
'src/app/features/schedule/map-schedule-data/insert-blocked-blocks-view-entries-for-schedule.ts',
'src/app/features/schedule/map-schedule-data/map-to-schedule-days.ts',
'src/app/features/task-repeat-cfg/sort-repeatable-task-cfg.ts',
- 'src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.ts',
'src/app/features/work-context/store/work-context-meta.helper.ts',
'src/app/root-store/index.ts',
'src/app/ui/duration/input-duration-formly/input-duration-formly.component.ts',
diff --git a/src/app/core-ui/main-header/mobile-side-panel-menu/mobile-side-panel-menu.component.scss b/src/app/core-ui/main-header/mobile-side-panel-menu/mobile-side-panel-menu.component.scss
deleted file mode 100644
index 6e74bfca33..0000000000
--- a/src/app/core-ui/main-header/mobile-side-panel-menu/mobile-side-panel-menu.component.scss
+++ /dev/null
@@ -1,55 +0,0 @@
-:host {
- display: contents;
-}
-
-// Mobile dropdown wrapper
-.mobile-dropdown-wrapper {
- position: relative;
-}
-
-// Mobile dropdown
-.mobile-dropdown {
- position: absolute;
- display: flex;
- transition: var(--transition-standard);
- top: 100%;
- flex-direction: column;
- left: 50%;
- transform: translateX(-50%);
- z-index: 2;
- pointer-events: none;
-
- &.isVisible {
- pointer-events: all;
- }
-
- button {
- transition: var(--transition-standard);
- transform: translateY(-100%);
- opacity: 0;
- position: relative;
- z-index: 2;
- margin-top: var(--s);
- margin-left: 0;
-
- @for $i from 2 through 7 {
- &:nth-child(#{$i}) {
- transform: translateY(#{$i * -100%});
- }
- }
- }
-
- &.isVisible button {
- transform: translateY(0);
- opacity: 1;
- }
-}
-
-// Active button styles
-button.active {
- background-color: var(--sidenav-bg);
-
- &.isCustomized {
- background-color: var(--c-accent);
- }
-}
diff --git a/src/app/core-ui/main-header/mobile-side-panel-menu/mobile-side-panel-menu.component.ts b/src/app/core-ui/main-header/mobile-side-panel-menu/mobile-side-panel-menu.component.ts
deleted file mode 100644
index 5899a61041..0000000000
--- a/src/app/core-ui/main-header/mobile-side-panel-menu/mobile-side-panel-menu.component.ts
+++ /dev/null
@@ -1,229 +0,0 @@
-import {
- ChangeDetectionStrategy,
- Component,
- computed,
- inject,
- signal,
-} from '@angular/core';
-import { MatIconModule } from '@angular/material/icon';
-import { MatButtonModule } from '@angular/material/button';
-import { MatTooltipModule } from '@angular/material/tooltip';
-import { MatMenuModule } from '@angular/material/menu';
-import { TranslateModule } from '@ngx-translate/core';
-import { LayoutService } from '../../layout/layout.service';
-import { TaskViewCustomizerService } from '../../../features/task-view-customizer/task-view-customizer.service';
-import { TaskViewCustomizerPanelComponent } from '../../../features/task-view-customizer/task-view-customizer-panel/task-view-customizer-panel.component';
-import { T } from '../../../t.const';
-import { KeyboardConfig } from '@sp/keyboard-config';
-import { GlobalConfigService } from '../../../features/config/global-config.service';
-import { Store } from '@ngrx/store';
-import {
- selectActivePluginId,
- selectIsShowPluginPanel,
-} from '../../layout/store/layout.reducer';
-import { toSignal } from '@angular/core/rxjs-interop';
-import { PluginBridgeService } from '../../../plugins/plugin-bridge.service';
-import { PluginIconComponent } from '../../../plugins/ui/plugin-icon/plugin-icon.component';
-import { togglePluginPanel } from '../../layout/store/layout.actions';
-import { NavigationEnd, Router } from '@angular/router';
-import { filter, map, startWith } from 'rxjs/operators';
-import { BreakpointObserver } from '@angular/cdk/layout';
-
-@Component({
- selector: 'mobile-side-panel-menu',
- standalone: true,
- imports: [
- MatIconModule,
- MatButtonModule,
- MatTooltipModule,
- MatMenuModule,
- TranslateModule,
- PluginIconComponent,
- TaskViewCustomizerPanelComponent,
- ],
- template: `
-
-
-
-
-
- @for (button of sidePanelButtons(); track button.pluginId) {
-
- }
-
-
-
-
-
-
- @if (isIssuesPanelEnabled()) {
-
-
- }
-
- @if (isProjectNotesEnabled()) {
-
-
- }
-
-
- `,
- styleUrls: ['./mobile-side-panel-menu.component.scss'],
- changeDetection: ChangeDetectionStrategy.OnPush,
-})
-export class MobileSidePanelMenuComponent {
- readonly T = T;
- readonly layoutService = inject(LayoutService);
- readonly taskViewCustomizerService = inject(TaskViewCustomizerService);
- readonly breakpointObserver = inject(BreakpointObserver);
-
- private _globalConfigService = inject(GlobalConfigService);
- private _pluginBridge = inject(PluginBridgeService);
- private _store = inject(Store);
- private _router = inject(Router);
-
- // State signals
- readonly isShowMobileMenu = signal(false);
-
- // Convert observables to signals
- readonly isRouteWithSidePanel = toSignal(
- this._router.events.pipe(
- filter((event): event is NavigationEnd => event instanceof NavigationEnd),
- map((event) => true), // Always true since right-panel is now global
- startWith(true), // Always true since right-panel is now global
- ),
- { initialValue: true },
- );
-
- readonly isWorkViewPage = toSignal(
- this._router.events.pipe(
- filter((event): event is NavigationEnd => event instanceof NavigationEnd),
- map((event) => !!event.urlAfterRedirects.match(/tasks$/)),
- startWith(!!this._router.url.match(/tasks$/)),
- ),
- { initialValue: !!this._router.url.match(/tasks$/) },
- );
-
- readonly kb: KeyboardConfig = this._globalConfigService.cfg()?.keyboard || {};
-
- // Plugin-related signals
- readonly sidePanelButtons = this._pluginBridge.sidePanelButtons;
- readonly activePluginId = toSignal(this._store.select(selectActivePluginId));
- readonly isShowPluginPanel = toSignal(this._store.select(selectIsShowPluginPanel));
-
- // Navigation signals
- readonly currentRoute = toSignal(
- this._router.events.pipe(
- filter((event) => event instanceof NavigationEnd),
- map(() => this._router.url),
- ),
- { initialValue: this._router.url },
- );
-
- readonly isWorkView = computed(() => {
- const url = this.currentRoute();
- return url.includes('/active/') || url.includes('/tag/') || url.includes('/project/');
- });
-
- // Panel state signals
- readonly isShowNotes = computed(() => this.layoutService.isShowNotes());
- readonly isShowIssuePanel = computed(() => this.layoutService.isShowIssuePanel());
- readonly isIssuesPanelEnabled = computed(
- () => this._globalConfigService.appFeatures().isIssuesPanelEnabled,
- );
- readonly isProjectNotesEnabled = computed(
- () => this._globalConfigService.appFeatures().isProjectNotesEnabled,
- );
- readonly isShowTaskViewCustomizerPanel = computed(() =>
- this.layoutService.isShowTaskViewCustomizerPanel(),
- );
-
- // Computed signal for active panel
- readonly hasActivePanel = computed(() => {
- return !!(
- this.isShowNotes() ||
- this.isShowIssuePanel() ||
- this.isShowTaskViewCustomizerPanel() ||
- (this.activePluginId() && this.isShowPluginPanel())
- );
- });
-
- toggleMenu(): void {
- this.isShowMobileMenu.update((v) => !v);
- }
-
- onPluginButtonClick(button: {
- pluginId: string;
- onClick?: () => void;
- label?: string;
- icon?: string;
- }): void {
- this._store.dispatch(togglePluginPanel(button.pluginId));
-
- if (button.onClick) {
- button.onClick();
- }
-
- // Close mobile menu after action
- this.isShowMobileMenu.set(false);
- }
-
- toggleIssuePanel(): void {
- this.layoutService.toggleAddTaskPanel();
- this.isShowMobileMenu.set(false);
- }
-
- toggleNotes(): void {
- this.layoutService.toggleNotes();
- this.isShowMobileMenu.set(false);
- }
-}
diff --git a/src/app/core/theme/validated-color-palettes.const.ts b/src/app/core/theme/validated-color-palettes.const.ts
deleted file mode 100644
index 87ceb21926..0000000000
--- a/src/app/core/theme/validated-color-palettes.const.ts
+++ /dev/null
@@ -1,196 +0,0 @@
-import { WorkContextThemeCfg } from '../../features/work-context/work-context.model';
-
-/**
- * Pre-validated color palette that meets WCAG AA contrast standards (4.5:1)
- * for both light and dark themes when used on standard backgrounds.
- */
-export interface ValidatedColorPalette {
- /** Display name for the palette */
- name: string;
- /** Theme configuration with validated colors */
- theme: WorkContextThemeCfg;
- /** Description for UI display */
- description?: string;
-}
-
-/**
- * Collection of pre-validated color palettes.
- * All palettes are tested to meet WCAG AA contrast standards (4.5:1 ratio)
- * on both light (#f8f8f7) and dark (#131314) backgrounds.
- */
-export const VALIDATED_COLOR_PALETTES: readonly ValidatedColorPalette[] = [
- {
- name: 'Purple & Pink (Default)',
- description: 'The classic Super Productivity theme',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#8b4a9d', // Darker purple for better contrast (was #a05db1)
- huePrimary: '500',
- accent: '#d81b60', // Darker pink for better contrast (was #ff4081)
- hueAccent: '500',
- warn: '#c62828', // Darker red for better contrast (was #e11826)
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Ocean Blue',
- description: 'Professional blue tones',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#1976d2', // Material Blue 700
- huePrimary: '500',
- accent: '#0277bd', // Light Blue 800
- hueAccent: '500',
- warn: '#c62828', // Red 800
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Forest Green',
- description: 'Calming natural greens',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#388e3c', // Green 700
- huePrimary: '500',
- accent: '#00796b', // Teal 700
- hueAccent: '500',
- warn: '#d32f2f', // Red 700
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Sunset Orange',
- description: 'Warm and energetic',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#e64a19', // Deep Orange 700
- huePrimary: '500',
- accent: '#f57c00', // Orange 700
- hueAccent: '500',
- warn: '#c62828', // Red 800
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Deep Teal',
- description: 'Modern and sophisticated',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#00796b', // Teal 700
- huePrimary: '500',
- accent: '#0097a7', // Cyan 700
- hueAccent: '500',
- warn: '#c62828', // Red 800
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Ruby Red',
- description: 'Bold and striking',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#c62828', // Red 800
- huePrimary: '500',
- accent: '#ad1457', // Pink 800
- hueAccent: '500',
- warn: '#d84315', // Deep Orange 800
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Indigo Night',
- description: 'Deep and focused',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#283593', // Indigo 800
- huePrimary: '500',
- accent: '#303f9f', // Indigo 700
- hueAccent: '500',
- warn: '#c62828', // Red 800
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Amber Glow',
- description: 'Bright and cheerful',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#f57f17', // Yellow 800
- huePrimary: '500',
- accent: '#ef6c00', // Orange 800
- hueAccent: '500',
- warn: '#c62828', // Red 800
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Slate Gray',
- description: 'Neutral and elegant',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#455a64', // Blue Gray 700
- huePrimary: '500',
- accent: '#546e7a', // Blue Gray 600
- hueAccent: '500',
- warn: '#c62828', // Red 800
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
- {
- name: 'Lime Fresh',
- description: 'Vibrant and lively',
- theme: {
- isAutoContrast: true,
- isDisableBackgroundTint: false,
- primary: '#689f38', // Light Green 700
- huePrimary: '500',
- accent: '#7cb342', // Light Green 600
- hueAccent: '500',
- warn: '#c62828', // Red 800
- hueWarn: '500',
- backgroundImageDark: null,
- backgroundImageLight: null,
- },
- },
-] as const;
-
-/**
- * Get a validated palette by name
- */
-export const getValidatedPalette = (name: string): ValidatedColorPalette | undefined => {
- return VALIDATED_COLOR_PALETTES.find((p) => p.name === name);
-};
-
-/**
- * Get the default validated palette
- */
-export const getDefaultValidatedPalette = (): ValidatedColorPalette => {
- return VALIDATED_COLOR_PALETTES[0];
-};
diff --git a/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.html b/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.html
deleted file mode 100644
index 39c61b70b7..0000000000
--- a/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
- {{
- isEdit
- ? (T.F.TAG.D_EDIT.EDIT | translate: { title: title })
- : (T.F.TAG.D_EDIT.ADD | translate: { title: title })
- }}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.scss b/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.scss
deleted file mode 100644
index 3ff81a562c..0000000000
--- a/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.scss
+++ /dev/null
@@ -1,24 +0,0 @@
-@use '../../../../styles/_globals.scss' as *;
-
-:host {
- display: flex;
- flex-direction: column;
- justify-content: stretch;
- align-items: stretch;
- max-width: 600px;
-
- @include mq(xs) {
- width: 70vw;
- }
-
- :host-context([dir='rtl']) {
- direction: rtl;
- }
-}
-
-.form-wrapper {
- display: flex;
- flex-direction: column;
- justify-content: stretch;
- align-items: stretch;
-}
diff --git a/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.ts b/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.ts
deleted file mode 100644
index 610b066c82..0000000000
--- a/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.component.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { ChangeDetectionStrategy, Component, inject, OnDestroy } from '@angular/core';
-import {
- MAT_DIALOG_DATA,
- MatDialogActions,
- MatDialogContent,
- MatDialogRef,
- MatDialogTitle,
-} from '@angular/material/dialog';
-import { T } from '../../../t.const';
-import { TaskService } from '../../tasks/task.service';
-import { DialogEditTagsForTaskPayload } from './dialog-edit-tags-for-task.payload';
-import { truncate } from '../../../util/truncate';
-import { TagService } from '../tag.service';
-import { Task } from '../../tasks/task.model';
-import { unique } from '../../../util/unique';
-import { Observable, Subscription } from 'rxjs';
-import { Tag } from '../tag.model';
-import { ChipListInputComponent } from '../../../ui/chip-list-input/chip-list-input.component';
-import { MatButton } from '@angular/material/button';
-import { AsyncPipe } from '@angular/common';
-import { TranslatePipe } from '@ngx-translate/core';
-import { Store } from '@ngrx/store';
-import { TaskSharedActions } from '../../../root-store/meta/task-shared.actions';
-import { addTag } from '../store/tag.actions';
-
-@Component({
- selector: 'dialog-edit-tags',
- templateUrl: './dialog-edit-tags-for-task.component.html',
- styleUrls: ['./dialog-edit-tags-for-task.component.scss'],
- changeDetection: ChangeDetectionStrategy.OnPush,
- imports: [
- MatDialogTitle,
- MatDialogContent,
- ChipListInputComponent,
- MatDialogActions,
- MatButton,
- AsyncPipe,
- TranslatePipe,
- ],
-})
-export class DialogEditTagsForTaskComponent implements OnDestroy {
- private _taskService = inject(TaskService);
- private _tagService = inject(TagService);
- private _store = inject(Store);
- private _matDialogRef =
- inject>(MatDialogRef);
- data = inject(MAT_DIALOG_DATA);
-
- T: typeof T = T;
- title: string = truncate(this.data.task.title, 20);
- task$: Observable = this._taskService.getByIdLive$(this.data.task.id);
- task: Task = this.data.task;
- tagIds: string[] = [...this.data.task.tagIds];
- isEdit: boolean = this.data.task.tagIds && this.data.task.tagIds.length > 0;
- tagSuggestions$: Observable = this._tagService.tagsNoMyDayAndNoList$;
-
- private _subs: Subscription = new Subscription();
-
- constructor() {
- this._subs.add(
- this.task$.subscribe((task) => {
- this.tagIds = task.tagIds;
- this.task = task;
- }),
- );
- }
-
- ngOnDestroy(): void {
- this._subs.unsubscribe();
- }
-
- close(): void {
- this._matDialogRef.close();
- }
-
- addTag(id: string): void {
- this._updateTags(unique([...this.tagIds, id]));
- }
-
- addNewTag(title: string): void {
- const cleanTitle = (t: string): string => {
- return t.replace('#', '');
- };
-
- const tag = this._tagService.createTagObject({ title: cleanTitle(title) });
- this._store.dispatch(addTag({ tag }));
- this._store.dispatch(
- TaskSharedActions.addTagToTask({ tagId: tag.id, taskId: this.task.id }),
- );
- }
-
- removeTag(id: string): void {
- const updatedTagIds = this.tagIds.filter((tagId) => tagId !== id);
- this._updateTags(updatedTagIds);
- }
-
- private _updateTags(newTagIds: string[]): void {
- this._taskService.updateTags(this.task, unique(newTagIds));
- }
-}
diff --git a/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.payload.ts b/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.payload.ts
deleted file mode 100644
index e4abcdcd27..0000000000
--- a/src/app/features/tag/dialog-edit-tags/dialog-edit-tags-for-task.payload.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { Task } from '../../tasks/task.model';
-
-export interface DialogEditTagsForTaskPayload {
- task: Task;
-}
diff --git a/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.html b/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.html
deleted file mode 100644
index eb7f4bab3d..0000000000
--- a/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
- @if (task$ | async; as task) {
-
- }
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.scss b/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.scss
deleted file mode 100644
index 79ac70fa5f..0000000000
--- a/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-@use '../../../../styles/_globals.scss' as *;
-
-:host {
- mat-dialog-content {
- padding: 0;
- border-radius: var(--card-border-radius);
- max-width: 450px;
- max-height: 75vh;
- min-width: 340px;
-
- background: var(--bg-lightest) !important;
-
- @include mq(xxxs) {
- min-width: 380px;
- }
- @include mq(xs) {
- min-width: 450px;
- max-height: 85vh;
- }
- }
-
- &::ng-deep {
- .task-title-wrapper {
- padding-right: var(--s) !important;
- }
-
- task .hover-controls {
- display: none !important;
- }
- }
-}
diff --git a/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.ts b/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.ts
deleted file mode 100644
index 51c1711a01..0000000000
--- a/src/app/features/tasks/dialog-task-detail-panel/dialog-task-detail-panel.component.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { ChangeDetectionStrategy, Component, inject, OnDestroy } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import {
- MAT_DIALOG_DATA,
- MatDialogContent,
- MatDialogRef,
-} from '@angular/material/dialog';
-import { Store } from '@ngrx/store';
-import { selectSelectedTask } from '../store/task.selectors';
-import { T } from 'src/app/t.const';
-import { TranslateModule } from '@ngx-translate/core';
-import { setSelectedTask } from '../store/task.actions';
-import { TaskDetailTargetPanel } from '../task.model';
-import { skipWhile } from 'rxjs/operators';
-import { TaskDetailPanelComponent } from '../task-detail-panel/task-detail-panel.component';
-
-@Component({
- selector: 'dialog-task-detail-panel',
- imports: [CommonModule, TranslateModule, MatDialogContent, TaskDetailPanelComponent],
- templateUrl: './dialog-task-detail-panel.component.html',
- styleUrl: './dialog-task-detail-panel.component.scss',
- changeDetection: ChangeDetectionStrategy.OnPush,
-})
-export class DialogTaskDetailPanelComponent implements OnDestroy {
- data = inject<{
- taskId: string;
- }>(MAT_DIALOG_DATA);
- private _matDialogRef =
- inject>(MatDialogRef);
- private _store = inject(Store);
-
- T: typeof T = T;
- task$ = this._store.select(selectSelectedTask).pipe(skipWhile((v) => !v));
-
- constructor() {
- const data = this.data;
-
- this._store.dispatch(
- setSelectedTask({
- id: data.taskId,
- taskDetailTargetPanel: TaskDetailTargetPanel.DONT_OPEN_PANEL,
- isSkipToggle: true,
- }),
- );
- // this.task$.subscribe((v) => TaskLog.log(`task$`, v));
- }
-
- // close(): void {
- // this._matDialogRef.close();
- // }
- ngOnDestroy(): void {
- this._store.dispatch(
- setSelectedTask({
- id: null,
- }),
- );
- }
-}
diff --git a/src/app/plugins/ui/plugin-menu.component.ts b/src/app/plugins/ui/plugin-menu.component.ts
deleted file mode 100644
index 27d572195b..0000000000
--- a/src/app/plugins/ui/plugin-menu.component.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
-import { PluginBridgeService } from '../plugin-bridge.service';
-import { MatMenuItem } from '@angular/material/menu';
-import { PluginIconComponent } from './plugin-icon/plugin-icon.component';
-import { toSignal } from '@angular/core/rxjs-interop';
-import { filter, map } from 'rxjs/operators';
-import { NavigationEnd, Router } from '@angular/router';
-
-@Component({
- selector: 'plugin-menu',
- template: `
- @for (menuEntry of menuEntries(); track menuEntry.pluginId + menuEntry.label) {
-
- }
- `,
- styles: [
- `
- .plugin-menu-entry {
- width: 100%;
- justify-content: flex-start;
- margin-bottom: 4px;
- &.isActive {
- color: var(--c-primary);
- font-weight: bold;
-
- mat-icon {
- color: var(--c-primary);
- }
- }
-
- mat-icon,
- plugin-icon {
- margin-right: 16px;
- }
- }
- `,
- ],
- changeDetection: ChangeDetectionStrategy.OnPush,
- imports: [MatMenuItem, PluginIconComponent],
-})
-export class PluginMenuComponent {
- private readonly _pluginBridge = inject(PluginBridgeService);
- private readonly _router = inject(Router);
-
- readonly currentRoute = toSignal(
- this._router.events.pipe(
- filter((event) => event instanceof NavigationEnd),
- map(() => this._router.url),
- ),
- { initialValue: this._router.url },
- );
-
- readonly menuEntries = this._pluginBridge.menuEntries;
-
- isActive(pluginId: string): boolean {
- return this.currentRoute().includes(pluginId);
- }
-}
diff --git a/src/app/ui/help-box/help-box.component.html b/src/app/ui/help-box/help-box.component.html
deleted file mode 100644
index e461c26b77..0000000000
--- a/src/app/ui/help-box/help-box.component.html
+++ /dev/null
@@ -1,19 +0,0 @@
-@if (isVisible()) {
-
-}
diff --git a/src/app/ui/help-box/help-box.component.scss b/src/app/ui/help-box/help-box.component.scss
deleted file mode 100644
index f1bee5cc93..0000000000
--- a/src/app/ui/help-box/help-box.component.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-:host {
- display: block;
- position: sticky;
- top: var(--s2);
- background: var(--bg);
- z-index: 200;
- margin: var(--s);
- border: 2px solid var(--separator-color);
- border-radius: var(--card-border-radius);
-
- .help-box {
- position: relative;
- padding: var(--s);
- border: 1px solid var(--color-border);
- border-radius: var(--card-border-radius);
- background-color: var(--color-bg-info);
- }
-
- .close-btn {
- position: absolute;
- top: var(--s-half);
- right: var(--s-half);
- }
-
- //.help-box-content {}
-
- :host-context([dir='rtl']) {
- .close-btn {
- right: unset;
- left: var(--s-half);
- }
- }
-}
diff --git a/src/app/ui/help-box/help-box.component.ts b/src/app/ui/help-box/help-box.component.ts
deleted file mode 100644
index ba49bff6fd..0000000000
--- a/src/app/ui/help-box/help-box.component.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import {
- ChangeDetectionStrategy,
- Component,
- Input,
- OnInit,
- WritableSignal,
- signal,
-} from '@angular/core';
-import { MatIcon } from '@angular/material/icon';
-import { MatIconButton } from '@angular/material/button';
-import { expandFadeAnimation } from '../animations/expand.ani';
-import { lsGetBoolean, lsSetItem } from '../../util/ls-util';
-
-@Component({
- selector: 'help-box',
- templateUrl: './help-box.component.html',
- styleUrls: ['./help-box.component.scss'],
- changeDetection: ChangeDetectionStrategy.OnPush,
- animations: [expandFadeAnimation],
- imports: [MatIcon, MatIconButton],
-})
-export class HelpBoxComponent implements OnInit {
- @Input({ required: true }) lsKey!: string;
-
- isVisible: WritableSignal = signal(true);
-
- ngOnInit(): void {
- // Check localStorage to determine if the help box should be shown
- const isDismissed = lsGetBoolean(this.lsKey, false);
- this.isVisible.set(!isDismissed);
- }
-
- onClose(): void {
- // Set the localStorage key to true to indicate the box was dismissed
- lsSetItem(this.lsKey, true);
- this.isVisible.set(false);
- }
-}
diff --git a/src/app/ui/stuck/stuck.directive.ts b/src/app/ui/stuck/stuck.directive.ts
deleted file mode 100644
index a9dece07fd..0000000000
--- a/src/app/ui/stuck/stuck.directive.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { AfterViewInit, Directive, ElementRef, OnDestroy, inject } from '@angular/core';
-const DEFAULT_PINNED_CLASS = 'is-stuck';
-
-@Directive({
- selector: '[stuck]',
- standalone: true,
-})
-export class StuckDirective implements AfterViewInit, OnDestroy {
- private elRef = inject(ElementRef);
-
- private _observer?: IntersectionObserver;
-
- ngAfterViewInit(): void {
- const el = this.elRef.nativeElement as HTMLElement;
- this._observer = new IntersectionObserver(
- // ([e]) => e.target.classList.toggle(DEFAULT_PINNED_CLASS, e.intersectionRatio < 1),
- ([e]) => {
- e.target.classList.toggle(DEFAULT_PINNED_CLASS, !e.isIntersecting);
- // Log.log(e.boundingClientRect.top, e);
- // Log.log('top', e.boundingClientRect.top < 0, e.isIntersecting);
- // if (e.boundingClientRect.top < 0) {
- // e.target.classList.toggle(DEFAULT_PINNED_CLASS, e.isIntersecting);
- // }
- },
- {
- rootMargin: '0px',
- threshold: 1,
- },
- );
-
- this._observer.observe(el);
- }
-
- ngOnDestroy(): void {
- if (!this._observer) {
- throw new Error('Observer is not defined');
- }
- this._observer.unobserve(this.elRef.nativeElement as HTMLElement);
- this._observer.disconnect();
- }
-}
diff --git a/src/app/ui/tree-dnd/tree-drop-zones.component.ts b/src/app/ui/tree-dnd/tree-drop-zones.component.ts
deleted file mode 100644
index 20228f51ae..0000000000
--- a/src/app/ui/tree-dnd/tree-drop-zones.component.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { ChangeDetectionStrategy, Component, input } from '@angular/core';
-
-@Component({
- selector: 'tree-drop-zones',
- standalone: true,
- template: `
-
-
- `,
- styles: [
- `
- .drop {
- height: 50%;
- pointer-events: none;
- width: 100%;
- background: transparent;
- position: absolute;
- z-index: 1;
-
- :host-context(.tree.is-dragging) & {
- pointer-events: all;
- background: rgba(0, 123, 255, 0.1);
- z-index: 10;
- }
-
- &:hover {
- background: rgba(0, 123, 255, 0.15);
- }
- }
-
- .drop--before,
- .drop--after {
- }
-
- .drop--before {
- top: 0px;
-
- :host-context(.tree.is-dragging) & {
- background: rgba(255, 165, 0, 0.1); /* Light orange when dragging */
- }
-
- &.is-over {
- background: rgba(
- 255,
- 165,
- 0,
- 0.25
- ) !important; /* Darker orange when hovering */
- }
- }
-
- .drop--after {
- bottom: 0px;
-
- :host-context(.tree.is-dragging) & {
- background: rgba(34, 139, 34, 0.1); /* Light green when dragging */
- }
-
- &.is-over {
- background: rgba(34, 139, 34, 0.25) !important; /* Darker green when hovering */
- }
- }
- `,
- ],
- changeDetection: ChangeDetectionStrategy.OnPush,
-})
-export class TreeDropZonesComponent {
- readonly nodeId = input.required();
- readonly overBefore = input(false);
- readonly overAfter = input(false);
-}