From e2c151194aaa4d7947b156fc73b61549010417bc Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Tue, 7 Feb 2023 20:37:03 +0000 Subject: [PATCH 01/85] Layout changes for workspace sidemenu --- app/src/assets/svg/icons/avatar.svg | 4 + app/src/assets/svg/icons/menu.svg | 11 + app/src/assets/svg/icons/settings.svg | 3 + app/src/assets/svg/icons/workspace.svg | 4 + .../aca-content/assets/app.extensions.json | 106 ++++---- projects/aca-content/assets/i18n/en.json | 15 +- .../components/header/header.component.html | 19 -- .../header/header.component.spec.ts | 1 + .../components/expand-menu.component.html | 18 +- .../directives/expansion-panel.directive.ts | 20 ++ .../navigation-menu.component.html | 35 +++ .../navigation-menu.component.scss | 32 +++ .../navigation-menu.component.ts | 31 +++ .../components/sidenav/sidenav.component.html | 28 +- .../components/sidenav/sidenav.component.scss | 252 ++++++++---------- .../lib/components/sidenav/sidenav.module.ts | 4 +- .../view-profile/view-profile.component.html | 1 - .../view-profile/view-profile.component.scss | 22 +- .../src/lib/extensions/custom-icons.module.ts | 17 ++ .../src/lib/services/icon.service.ts | 27 ++ .../aca-content/src/lib/ui/application.scss | 2 +- .../src/lib/ui/variables/variables.scss | 14 +- 22 files changed, 416 insertions(+), 250 deletions(-) create mode 100644 app/src/assets/svg/icons/avatar.svg create mode 100644 app/src/assets/svg/icons/menu.svg create mode 100644 app/src/assets/svg/icons/settings.svg create mode 100644 app/src/assets/svg/icons/workspace.svg create mode 100644 projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.html create mode 100644 projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.scss create mode 100644 projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.ts create mode 100644 projects/aca-content/src/lib/extensions/custom-icons.module.ts create mode 100644 projects/aca-content/src/lib/services/icon.service.ts diff --git a/app/src/assets/svg/icons/avatar.svg b/app/src/assets/svg/icons/avatar.svg new file mode 100644 index 0000000000..96f0cb29d4 --- /dev/null +++ b/app/src/assets/svg/icons/avatar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/assets/svg/icons/menu.svg b/app/src/assets/svg/icons/menu.svg new file mode 100644 index 0000000000..f09df24f2a --- /dev/null +++ b/app/src/assets/svg/icons/menu.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/src/assets/svg/icons/settings.svg b/app/src/assets/svg/icons/settings.svg new file mode 100644 index 0000000000..42035fd9a8 --- /dev/null +++ b/app/src/assets/svg/icons/settings.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/src/assets/svg/icons/workspace.svg b/app/src/assets/svg/icons/workspace.svg new file mode 100644 index 0000000000..5c63fd78e6 --- /dev/null +++ b/app/src/assets/svg/icons/workspace.svg @@ -0,0 +1,4 @@ + + + + diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json index 3278f3cc7e..fa7d3e417d 100644 --- a/projects/aca-content/assets/app.extensions.json +++ b/projects/aca-content/assets/app.extensions.json @@ -242,32 +242,24 @@ "id": "app.navbar.primary", "items": [ { - "id": "app.navbar.personalFiles", + "id": "app.navbar.menu", "order": 100, "icon": "folder", - "title": "APP.BROWSE.PERSONAL.SIDENAV_LINK.LABEL", - "description": "APP.BROWSE.PERSONAL.SIDENAV_LINK.TOOLTIP", - "route": "personal-files", - "rules": { - "visible": "app.isContentServiceEnabled" - } - }, - { - "id": "app.navbar.libraries.menu", - "order": 200, - "icon": "library_books", - "title": "APP.BROWSE.LIBRARIES.SIDENAV_LINK.LABEL", - "description": "APP.BROWSE.LIBRARIES.SIDENAV_LINK.TOOLTIP", + "title": "APP.BROWSE.FILE.SIDENAV_LINK.LABEL", + "description": "APP.BROWSE.FILE.SIDENAV_LINK.TOOLTIP", "rules": { "visible": "app.isContentServiceEnabled" }, "children": [ { - "id": "app.navbar.libraries.favorite", + "id": "app.navbar.personalFiles", "order": 100, - "title": "APP.BROWSE.LIBRARIES.MENU.FAVORITE_LIBRARIES.SIDENAV_LINK.LABEL", - "description": "APP.BROWSE.LIBRARIES.MENU.FAVORITE_LIBRARIES.SIDENAV_LINK.TOOLTIP", - "route": "favorite/libraries" + "title": "APP.BROWSE.PERSONAL.SIDENAV_LINK.LABEL", + "description": "APP.BROWSE.PERSONAL.SIDENAV_LINK.TOOLTIP", + "route": "personal-files", + "rules": { + "visible": "app.isContentServiceEnabled" + } }, { "id": "app.navbar.libraries.files", @@ -275,53 +267,45 @@ "title": "APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.SIDENAV_LINK.LABEL", "description": "APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.SIDENAV_LINK.TOOLTIP", "route": "libraries" + }, + { + "id": "app.navbar.libraries.favorite", + "order": 300, + "title": "APP.BROWSE.LIBRARIES.MENU.FAVORITE_LIBRARIES.SIDENAV_LINK.LABEL", + "description": "APP.BROWSE.LIBRARIES.MENU.FAVORITE_LIBRARIES.SIDENAV_LINK.TOOLTIP", + "route": "favorite/libraries" + }, + { + "id": "app.navbar.recentFiles", + "order": 400, + "title": "APP.BROWSE.RECENT.SIDENAV_LINK.LABEL", + "description": "APP.BROWSE.RECENT.SIDENAV_LINK.TOOLTIP", + "route": "recent-files" + }, + { + "id": "app.navbar.favorites", + "order": 500, + "title": "APP.BROWSE.FAVORITES.SIDENAV_LINK.LABEL", + "description": "APP.BROWSE.FAVORITES.SIDENAV_LINK.TOOLTIP", + "route": "favorites" + }, + { + "id": "app.navbar.shared", + "order": 600, + "title": "APP.BROWSE.SHARED.SIDENAV_LINK.LABEL", + "description": "APP.BROWSE.SHARED.SIDENAV_LINK.TOOLTIP", + "route": "shared" + }, + { + "id": "app.navbar.trashcan", + "order": 700, + "title": "APP.BROWSE.TRASHCAN.SIDENAV_LINK.LABEL", + "description": "APP.BROWSE.TRASHCAN.SIDENAV_LINK.TOOLTIP", + "route": "trashcan" } ] } ] - }, - { - "id": "app.navbar.secondary", - "rules": { - "visible": "app.isContentServiceEnabled" - }, - "items": [ - { - "id": "app.navbar.shared", - "order": 100, - "icon": "people", - "title": "APP.BROWSE.SHARED.SIDENAV_LINK.LABEL", - "description": "APP.BROWSE.SHARED.SIDENAV_LINK.TOOLTIP", - "route": "shared", - "rules": { - "visible": "repository.isQuickShareEnabled" - } - }, - { - "id": "app.navbar.recentFiles", - "order": 200, - "icon": "schedule", - "title": "APP.BROWSE.RECENT.SIDENAV_LINK.LABEL", - "description": "APP.BROWSE.RECENT.SIDENAV_LINK.TOOLTIP", - "route": "recent-files" - }, - { - "id": "app.navbar.favorites", - "order": 300, - "icon": "star", - "title": "APP.BROWSE.FAVORITES.SIDENAV_LINK.LABEL", - "description": "APP.BROWSE.FAVORITES.SIDENAV_LINK.TOOLTIP", - "route": "favorites" - }, - { - "id": "app.navbar.trashcan", - "order": 400, - "icon": "delete", - "title": "APP.BROWSE.TRASHCAN.SIDENAV_LINK.LABEL", - "description": "APP.BROWSE.TRASHCAN.SIDENAV_LINK.TOOLTIP", - "route": "trashcan" - } - ] } ], "toolbar": [ diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index 30f9f23213..76968185c0 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -1,6 +1,7 @@ { "APP": { "COPYRIGHT": "© 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.", + "TITLE": "Workspace", "ABOUT": { "VERSION": "Version:", "PLUGINS": { @@ -103,6 +104,13 @@ } }, "BROWSE": { + "FILE": { + "TITLE": "Files", + "SIDENAV_LINK": { + "LABEL": "Files", + "TOOLTIP": "Files" + } + }, "PERSONAL": { "TITLE": "Personal Files", "SIDENAV_LINK": { @@ -409,7 +417,12 @@ "EXPAND": "Expand", "CLOSE_LIBRARY": "Close Library" } - } + }, + "TOOLTIPS": { + "COLLAPSE_NAVIGATION": "Collapse navigation menu", + "OPTIONS_SETTINGS": "Options and settings", + "MY_PROFILE": "My profile" + } }, "NODE_SELECTOR": { "COPY_ITEM": "Copy '{{ name }}' to...", diff --git a/projects/aca-content/src/lib/components/header/header.component.html b/projects/aca-content/src/lib/components/header/header.component.html index 6db2b8bf7d..e69de29bb2 100644 --- a/projects/aca-content/src/lib/components/header/header.component.html +++ b/projects/aca-content/src/lib/components/header/header.component.html @@ -1,19 +0,0 @@ - -
- - - - - - - - -
diff --git a/projects/aca-content/src/lib/components/header/header.component.spec.ts b/projects/aca-content/src/lib/components/header/header.component.spec.ts index 02553b2a39..f4210d3b72 100644 --- a/projects/aca-content/src/lib/components/header/header.component.spec.ts +++ b/projects/aca-content/src/lib/components/header/header.component.spec.ts @@ -131,3 +131,4 @@ describe('AppHeaderComponent', () => { }); }); }); + diff --git a/projects/aca-content/src/lib/components/sidenav/components/expand-menu.component.html b/projects/aca-content/src/lib/components/sidenav/components/expand-menu.component.html index ed51d164f2..93e39280ab 100644 --- a/projects/aca-content/src/lib/components/sidenav/components/expand-menu.component.html +++ b/projects/aca-content/src/lib/components/sidenav/components/expand-menu.component.html @@ -10,7 +10,6 @@ mat-button class="action-button full-width" > - {{ item.title | translate }} @@ -18,28 +17,23 @@ - +
- + {{ item.title | translate }} +
diff --git a/projects/aca-content/src/lib/components/sidenav/directives/expansion-panel.directive.ts b/projects/aca-content/src/lib/components/sidenav/directives/expansion-panel.directive.ts index 1b01131e8a..e2c489bc16 100644 --- a/projects/aca-content/src/lib/components/sidenav/directives/expansion-panel.directive.ts +++ b/projects/aca-content/src/lib/components/sidenav/directives/expansion-panel.directive.ts @@ -63,6 +63,26 @@ export class ExpansionPanelDirective implements OnInit, OnDestroy { return false; } + isRouteAbout(): boolean { + return this.router.url.includes('/about'); + } + + isRouteProfile(): boolean { + return this.router.url.includes('/profile'); + } + + isRouteSearch(): boolean { + return this.router.url.includes('/search'); + } + + isItemExpanded() { + if (this.isRouteAbout() || this.isRouteProfile() || this.isRouteSearch()) { + return !this.hasActiveLinks(); + } else { + return this.hasActiveLinks(); + } + } + ngOnInit() { this.hasActiveChildren = this.hasActiveLinks(); diff --git a/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.html b/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.html new file mode 100644 index 0000000000..4b5c9fc0e8 --- /dev/null +++ b/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.html @@ -0,0 +1,35 @@ + + +
+ +
+
{{ userName }}
+
{{ userEmail }}
+
+
+ + + + + + + + + +
diff --git a/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.scss b/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.scss new file mode 100644 index 0000000000..633c82c7b8 --- /dev/null +++ b/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.scss @@ -0,0 +1,32 @@ +app-navigation-menu { + .app-menu-button { + height: 32px; + background: none; + line-height: 24px; + } +} + +.mat-menu-panel { + .app-menu-user-details { + display: flex; + height: 66px; + + &-button { + height: 32px; + padding: 0; + line-height: 24px; + background: none; + border: none; + margin-top: 14px; + transform: scale(1.2); + } + + &-name-mail { + line-height: 40px; + } + + &-name { + height: 24px; + } + } +} diff --git a/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.ts b/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.ts new file mode 100644 index 0000000000..ee8f5506a0 --- /dev/null +++ b/projects/aca-content/src/lib/components/sidenav/navigation-menu/navigation-menu.component.ts @@ -0,0 +1,31 @@ +/* + * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. + * + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + */ + +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { ContentApiService } from '@alfresco/aca-shared'; + +@Component({ + selector: 'app-navigation-menu', + templateUrl: './navigation-menu.component.html', + styleUrls: ['./navigation-menu.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class NavigationMenuComponent implements OnInit { + userName = ''; + userEmail = ''; + + constructor(private contentApi: ContentApiService) {} + + ngOnInit() { + this.contentApi.getPerson('-me-').subscribe((person) => { + const personDetails = person?.entry; + this.userName = personDetails.displayName; + this.userEmail = personDetails.email; + }); + } +} diff --git a/projects/aca-content/src/lib/components/sidenav/sidenav.component.html b/projects/aca-content/src/lib/components/sidenav/sidenav.component.html index 2c91866da2..8b0a19915b 100644 --- a/projects/aca-content/src/lib/components/sidenav/sidenav.component.html +++ b/projects/aca-content/src/lib/components/sidenav/sidenav.component.html @@ -1,10 +1,21 @@
-
- - +
+
+ +
{{ 'APP.TITLE' | translate }} +
+
+ +
+
+ +
+
-
@@ -12,9 +23,9 @@ - - + @@ -22,11 +33,12 @@
- + - + +
diff --git a/projects/aca-content/src/lib/components/sidenav/sidenav.component.scss b/projects/aca-content/src/lib/components/sidenav/sidenav.component.scss index 98a801dff8..6355fd3573 100644 --- a/projects/aca-content/src/lib/components/sidenav/sidenav.component.scss +++ b/projects/aca-content/src/lib/components/sidenav/sidenav.component.scss @@ -1,151 +1,129 @@ -.app-sidenav { - display: flex; - flex: 1; - flex-direction: column; - height: 100%; - overflow-y: hidden; -} - .sidenav { display: flex; flex: 1; flex-direction: column; height: 100%; - background-color: var(--theme-background-color); - - .action-menu { - display: flex; - flex-direction: column; - justify-content: center; - align-items: stretch; - } - - .section.action-menu { - padding: 8px 14px; - position: sticky; - } - - .section-sub-actions { - overflow-y: auto; - } - - .section { - padding: 8px 6px; - border-bottom: 1px solid var(--theme-divider-color); + overflow-y: hidden; + background: var(--theme-sidenav-background-color); + + &-header { + padding: 32px 0; + + &-title { + display: flex; + flex-direction: row; + align-items: center; + height: 32px; + padding: 0 24px; + + &-logo { + img { + cursor: pointer; + height: 28px; + vertical-align: middle; + } + } + + &-text { + flex: 1; + color: var(--theme-selected-text-color); + padding-left: 32px; + letter-spacing: 0.25px; + font-style: normal; + font-weight: 400; + font-size: var(--theme-body-1-font-size); + cursor: pointer; + } + } } .section:last-child { border-bottom: 0; } - .section--collapsed { - display: flex; - flex-direction: column; - align-items: center; - } - - .list-item { - padding: 12px 0; - display: flex; - align-items: center; - height: 24px; - } - - .menu { - display: flex; - flex: 1; - flex-direction: row; - } - - .full-width { - display: flex; - width: 100%; - } - - .action-button--active { - color: var(--theme-primary-color) !important; - } - - .action-button { - color: var(--theme-text-color); - } - - .action-button .action-button__label { - margin: 0 8px !important; - } - - .item { - padding: 12px 0; - flex-direction: row; - display: flex; - align-items: center; - text-decoration: none; - height: 24px; - width: 100%; - user-select: none; - } - - .app-item, - .app-item .item { - display: flex; - flex: 1; - flex-direction: row; - } - - .item:hover .action-button__label { - color: var(--theme-primary-color); - } - - .mat-expansion-panel-header { - padding: 0 8px 0 0 !important; - display: flex; - align-items: center; - font-size: 14px !important; - } - - .mat-expansion-panel { - width: 100%; - background-color: unset; - box-shadow: none !important; - } - - .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled='true']):hover { - background: none !important; - } - - .mat-expansion-indicator { - display: flex; - align-content: center; - } - - .mat-expansion-panel-body { - padding-bottom: 0; - } - - .mat-expansion-panel-header-title { - display: flex; - flex-direction: row; - align-items: center; - } -} - -.aca-menu-panel { - .action-button--active { - color: var(--theme-accent-color) !important; - } - - .action-button { - color: var(--theme-primary-color); - } - - .action-button:hover { - color: var(--theme-accent-color); - } -} + .section-sub-actions { + overflow-y: auto; -[dir='rtl'] .sidenav { - /* stylelint-disable-next-line no-descending-specificity */ - .mat-expansion-panel-header { - padding: 0 0 0 8px !important; + .mat-expansion-panel { + width: 100%; + background-color: unset; + box-shadow: none; + border-radius: 0; + + &-header { + height: 32px; + padding: 0 32px 0 0; + display: flex; + align-items: center; + border: none; + } + + &-header:hover { + background: var(--theme-hover-background-color); + } + + &-header-title { + display: flex; + flex-direction: row; + align-items: center; + } + + &-body { + padding: 0 0 16px; + font-size: var(--theme-body-1-font-size); + + .mat-button { + line-height: 32px; + } + } + + .mat-expansion-indicator { + display: flex; + align-content: center; + } + + .mat-expansion-indicator::after { + transform: rotate(226deg); + } + } + + .item { + flex-direction: row; + display: flex; + align-items: center; + text-decoration: none; + width: 100%; + user-select: none; + + &:hover .action-button__label { + color: var(--theme-selected-text-color); + } + } + + .action-button { + color: var(--theme-action-button-text-color); + height: 32px; + padding: 0 24px; + border-radius: 0; + } + + .full-width { + display: flex; + width: 100%; + } + + .action-button--active { + color: var(--theme-selected-text-color) !important; + background: var(--theme-selected-background-color); + } + + .action-panel-header { + color: var(--theme-action-button-text-color); + padding: 0 24px; + + &__label { + font-size: var(--theme-caption-font-size); + } + } } } diff --git a/projects/aca-content/src/lib/components/sidenav/sidenav.module.ts b/projects/aca-content/src/lib/components/sidenav/sidenav.module.ts index ee980ee2d1..bb751b681d 100644 --- a/projects/aca-content/src/lib/components/sidenav/sidenav.module.ts +++ b/projects/aca-content/src/lib/components/sidenav/sidenav.module.ts @@ -38,6 +38,7 @@ import { ButtonMenuComponent } from './components/button-menu.component'; import { ActionDirective } from './directives/action.directive'; import { MainActionModule } from '../main-action/main-action.module'; import { SidenavWrapperComponent } from './sidenav-wrapper/sidenav-wrapper.component'; +import { NavigationMenuComponent } from './navigation-menu/navigation-menu.component'; @NgModule({ imports: [ @@ -57,7 +58,8 @@ import { SidenavWrapperComponent } from './sidenav-wrapper/sidenav-wrapper.compo ExpandMenuComponent, ButtonMenuComponent, SidenavComponent, - SidenavWrapperComponent + SidenavWrapperComponent, + NavigationMenuComponent ], exports: [ MenuPanelDirective, diff --git a/projects/aca-content/src/lib/components/view-profile/view-profile.component.html b/projects/aca-content/src/lib/components/view-profile/view-profile.component.html index 442a4b83eb..bcbc0bdd4e 100644 --- a/projects/aca-content/src/lib/components/view-profile/view-profile.component.html +++ b/projects/aca-content/src/lib/components/view-profile/view-profile.component.html @@ -4,7 +4,6 @@ arrow_back

{{'APP.EDIT_PROFILE.MY_PROFILE' | translate}}

-
diff --git a/projects/aca-content/src/lib/components/view-profile/view-profile.component.scss b/projects/aca-content/src/lib/components/view-profile/view-profile.component.scss index 5abffab1b2..5758249c7e 100644 --- a/projects/aca-content/src/lib/components/view-profile/view-profile.component.scss +++ b/projects/aca-content/src/lib/components/view-profile/view-profile.component.scss @@ -2,24 +2,31 @@ app-view-profile { letter-spacing: .5px; .app-profile-container { - margin-top: 1rem; overflow: scroll; - height:100%; + height: 100%; width: 100%; } .app-profile-row { width: 100%; margin: 2rem 0 0; + height: 32px; + padding: 32px 0; + border-bottom: 1px solid var(--theme-header-border-color); } .app-profile-title { display: flex; - margin-left: 2rem; + flex-direction: row; + align-items: center; + height: 32px; + padding: 0 24px; } .app-profile { cursor: pointer; + margin-top: 1rem; + } .app-profile-general-row { @@ -31,7 +38,6 @@ app-view-profile { .app-profile-icon { margin-right: 1rem; - margin-top: 1rem; cursor: pointer; } @@ -49,7 +55,7 @@ app-view-profile { } .app-profile-general-bottom-radius { - border-bottom-left-radius:0; + border-bottom-left-radius: 0; border-bottom-right-radius: 0; } @@ -67,7 +73,7 @@ app-view-profile { } .app-general-edit-btn { - width:60%; + width: 60%; text-align: end; } @@ -81,7 +87,7 @@ app-view-profile { .app-selected:focus { border: 2px solid var(--theme-blue-button-color) !important; border-radius: 6px; - outline : none !important; + outline: none !important; box-shadow: 0 0 2px (--theme-blue-button-color); } @@ -161,7 +167,7 @@ app-view-profile { height: 25px; border: none; margin-top: 1.3rem; - background-color: var(--theme-dropdown-color) ; + background-color: var(--theme-dropdown-color); } .app-profile-login-dropdown-heading-forgot { diff --git a/projects/aca-content/src/lib/extensions/custom-icons.module.ts b/projects/aca-content/src/lib/extensions/custom-icons.module.ts new file mode 100644 index 0000000000..bf78629ea1 --- /dev/null +++ b/projects/aca-content/src/lib/extensions/custom-icons.module.ts @@ -0,0 +1,17 @@ +/* + * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. + * + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + */ + +import { NgModule } from '@angular/core'; +import { IconService } from '../services/icon.service'; + +@NgModule({}) +export class CustomIconsModule { + constructor(iconService: IconService) { + iconService.registerIcons(); + } +} diff --git a/projects/aca-content/src/lib/services/icon.service.ts b/projects/aca-content/src/lib/services/icon.service.ts new file mode 100644 index 0000000000..8decd5cd31 --- /dev/null +++ b/projects/aca-content/src/lib/services/icon.service.ts @@ -0,0 +1,27 @@ +/* + * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. + * + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + */ + +import { Injectable } from '@angular/core'; +import { MatIconRegistry } from '@angular/material/icon'; +import { DomSanitizer } from '@angular/platform-browser'; + +@Injectable({ + providedIn: 'root' +}) +export class IconService { + contentIcons: string[] = ['workspace', 'menu', 'avatar', 'settings']; + constructor(private matIconRegistry: MatIconRegistry, private domSanitizer: DomSanitizer) {} + public registerIcons(): void { + this.loadIcons(this.contentIcons, './assets/svg/icons'); + } + private loadIcons(iconKeys: string[], iconUrl: string): void { + iconKeys.forEach((key) => { + this.matIconRegistry.addSvgIcon(key, this.domSanitizer.bypassSecurityTrustResourceUrl(`${iconUrl}/${key}.svg`)); + }); + } +} diff --git a/projects/aca-content/src/lib/ui/application.scss b/projects/aca-content/src/lib/ui/application.scss index 1b2e6162b1..e8a3070193 100644 --- a/projects/aca-content/src/lib/ui/application.scss +++ b/projects/aca-content/src/lib/ui/application.scss @@ -48,6 +48,6 @@ ng-component { adf-layout-container, aca-search-results, ng-component { - height: 80vh; + height: 100vh; } } diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 82181de062..3475291911 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -31,6 +31,11 @@ $datetimepicker-selected-date-background: #2254b2; $datetimepicker-cell-background-color: #fff; $datetimepicker-cell-focus-border-color: #1f74db; $datetimepicker-cell-focus-background-color: rgba(33, 33, 33, 0.12); +$sidenav-background-color: #f8f8f8; +$selected-text-color: #212121; +$selected-background-color: rgba(31, 116, 219, 0.24); +$action-button-text-color: rgba(33, 35, 40, 0.7); +$tooltip-background-color: #ffffff; // CSS Variables $defaults: ( @@ -68,7 +73,14 @@ $defaults: ( --theme-datetimepicker-selected-date-background: $datetimepicker-selected-date-background, --theme-datetimepicker-cell-background: $datetimepicker-cell-background-color, --theme-datetimepicker-cell-focus-border: $datetimepicker-cell-focus-border-color, - --theme-datetimepicker-cell-focus-background: $datetimepicker-cell-focus-background-color + --theme-datetimepicker-cell-focus-background: $datetimepicker-cell-focus-background-color, + --theme-sidenav-background-color: $sidenav-background-color, + --theme-selected-text-color: $selected-text-color, + --theme-selected-background-color: $selected-background-color, + --theme-hover-background-color: $grey-text-background, + --theme-action-button-text-color: $action-button-text-color, + --theme-header-border-color: $grey-background, + --theme-tooltip-background-color: $tooltip-background-color, ); // propagates SCSS variables into the CSS variables scope From 0bfad3902a5a6e77c6fcd4598f7b5d138bde05dc Mon Sep 17 00:00:00 2001 From: SheenaMalhotra182 Date: Wed, 8 Feb 2023 12:50:39 +0530 Subject: [PATCH 02/85] added header and search layout changes --- .../aca-content/assets/app.extensions.json | 78 +++++-------- projects/aca-content/assets/i18n/en.json | 6 + .../favorite-libraries.component.html | 2 +- .../favorites/favorites.component.html | 2 +- .../lib/components/files/files.component.html | 2 +- .../header-actions.component.html | 33 ++++++ .../header-actions.component.scss | 80 +++++++++++++ .../header-actions.component.spec.ts | 109 ++++++++++++++++++ .../header-actions.component.ts | 96 +++++++++++++++ .../header-actions/header-actions.module.ts | 55 +++++++++ .../libraries/libraries.component.html | 2 +- .../recent-files/recent-files.component.html | 2 +- .../search-input-control.component.scss | 1 + .../search/search-input.service.spec.ts | 66 +++++++++++ .../components/search/search-input.service.ts | 55 +++++++++ .../search-input/search-input.component.html | 18 ++- .../search-input/search-input.component.scss | 23 +++- .../search-input.component.spec.ts | 62 +++++++++- .../search-input/search-input.component.ts | 39 ++++--- .../search/search-results.module.ts | 6 +- .../search-results.component.html | 4 +- .../search-results.component.scss | 7 ++ .../shared-files/shared-files.component.html | 2 +- .../trashcan/trashcan.component.html | 2 +- .../components/trashcan/trashcan.module.ts | 6 +- .../src/lib/ui/variables/variables.scss | 8 ++ .../document-base-page.component.ts | 26 ++++- .../page-layout/page-layout.component.scss | 4 +- .../src/lib/services/app.extension.service.ts | 14 +++ 29 files changed, 729 insertions(+), 81 deletions(-) create mode 100644 projects/aca-content/src/lib/components/header-actions/header-actions.component.html create mode 100644 projects/aca-content/src/lib/components/header-actions/header-actions.component.scss create mode 100644 projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts create mode 100644 projects/aca-content/src/lib/components/header-actions/header-actions.component.ts create mode 100644 projects/aca-content/src/lib/components/header-actions/header-actions.module.ts create mode 100644 projects/aca-content/src/lib/components/search/search-input.service.spec.ts create mode 100644 projects/aca-content/src/lib/components/search/search-input.service.ts diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json index fa7d3e417d..d3ebe0fc0d 100644 --- a/projects/aca-content/assets/app.extensions.json +++ b/projects/aca-content/assets/app.extensions.json @@ -132,44 +132,6 @@ } ], "create": [ - { - "id": "app.create.uploadFile", - "order": 100, - "icon": "file_upload", - "title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FILE", - "description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FILES", - "description-disabled": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FILES_NOT_ALLOWED", - "actions": { - "click": "UPLOAD_FILES" - }, - "rules": { - "enabled": "app.navigation.folder.canUpload", - "visible": "app.isContentServiceEnabled" - } - }, - { - "id": "app.create.uploadFolder", - "order": 200, - "icon": "file_upload", - "title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FOLDER", - "description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FOLDERS", - "description-disabled": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FOLDERS_NOT_ALLOWED", - "actions": { - "click": "UPLOAD_FOLDER" - }, - "rules": { - "enabled": "app.navigation.folder.canUpload", - "visible": "app.isContentServiceEnabled" - } - }, - { - "id": "app.create.separator.1", - "type": "separator", - "order": 300, - "rules": { - "visible": "app.isContentServiceEnabled" - } - }, { "id": "app.create.folder", "order": 400, @@ -198,14 +160,6 @@ "visible": "app.isContentServiceEnabled" } }, - { - "id": "app.create.separator.2", - "type": "separator", - "order": 650, - "rules": { - "visible": "app.isContentServiceEnabled" - } - }, { "id": "app.create.fileFromTemplate", "order": 700, @@ -237,6 +191,38 @@ } } ], + "upload": [ + { + "id": "app.create.uploadFile", + "order": 100, + "icon": "file_upload", + "title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FILE", + "description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FILES", + "description-disabled": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FILES_NOT_ALLOWED", + "actions": { + "click": "UPLOAD_FILES" + }, + "rules": { + "enabled": "app.navigation.folder.canUpload", + "visible": "app.isContentServiceEnabled" + } + }, + { + "id": "app.create.uploadFolder", + "order": 200, + "icon": "file_upload", + "title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FOLDER", + "description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FOLDERS", + "description-disabled": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FOLDERS_NOT_ALLOWED", + "actions": { + "click": "UPLOAD_FOLDER" + }, + "rules": { + "enabled": "app.navigation.folder.canUpload", + "visible": "app.isContentServiceEnabled" + } + } + ], "navbar": [ { "id": "app.navbar.primary", diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index 76968185c0..98e8891a81 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -103,6 +103,12 @@ "CREATE_LIBRARY": "Create a new File Library" } }, + "HEADER": { + "BUTTONS": { + "CREATE": "Create", + "UPLOAD": "Upload" + } + }, "BROWSE": { "FILE": { "TITLE": "Files", diff --git a/projects/aca-content/src/lib/components/favorite-libraries/favorite-libraries.component.html b/projects/aca-content/src/lib/components/favorite-libraries/favorite-libraries.component.html index eda35a440d..96becc2111 100644 --- a/projects/aca-content/src/lib/components/favorite-libraries/favorite-libraries.component.html +++ b/projects/aca-content/src/lib/components/favorite-libraries/favorite-libraries.component.html @@ -1,7 +1,7 @@ - + diff --git a/projects/aca-content/src/lib/components/favorites/favorites.component.html b/projects/aca-content/src/lib/components/favorites/favorites.component.html index 4770e1d671..d7128b9b1f 100644 --- a/projects/aca-content/src/lib/components/favorites/favorites.component.html +++ b/projects/aca-content/src/lib/components/favorites/favorites.component.html @@ -1,7 +1,7 @@ - + diff --git a/projects/aca-content/src/lib/components/files/files.component.html b/projects/aca-content/src/lib/components/files/files.component.html index 2c1bedc831..1084b433b1 100644 --- a/projects/aca-content/src/lib/components/files/files.component.html +++ b/projects/aca-content/src/lib/components/files/files.component.html @@ -1,7 +1,7 @@ - + diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.html b/projects/aca-content/src/lib/components/header-actions/header-actions.component.html new file mode 100644 index 0000000000..a5bd756abf --- /dev/null +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.html @@ -0,0 +1,33 @@ +
+
+ + + +
+ +
+
+ + + +
+ +
+
+ + + + + + +
+
\ No newline at end of file diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss b/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss new file mode 100644 index 0000000000..46124d3ace --- /dev/null +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss @@ -0,0 +1,80 @@ +.aca-page-layout-header { + // display: flex; + // align-items: center; + // flex: 0 0 65px; + // flex-basis: 96px; + // background: var(--theme-page-layout-header-background-color); + // border-bottom: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); + // padding: 0 24px; + + .adf-breadcrumb-item { + font-size: 20px !important; + font-weight: 400 !important; + letter-spacing: 0.15px !important; + } + + .app-search-input { + background: none; + } + + .action-bar { + display: flex; + flex: auto; + height: 32px; + margin-left: 24px; + + adf-toolbar-divider { + width: 24px !important; + height: 32px !important; + margin: 4px 0 0 12px !important; + } + } + + .aca-mat-button { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + letter-spacing: 0.25px; + font-weight: 500; + font-size: 14px; + font-style: normal; + border-radius: 6px; + border: none; + } + + .aca-create-button { + width: 71px !important; + min-width: 71px; + height: 32px; + background-color: var(--theme-create-button-background-color); + color: var(--theme-create-button-text-color); + text-overflow: ellipsis; + display: flex; + padding: 0; + } + + .aca-upload-button { + width: 73px !important; + min-width: 73px; + height: 32px; + background-color: var(--theme-upload-button-background-color); + color: var(--theme-upload-button-text-color); + text-overflow: ellipsis; + display: flex; + padding: 0; + margin-left: 12px; + } + + // .aca-process-button { + // width: 130px !important; + // min-width: 130px; + // height: 32px; + // background-color: var(--theme-upload-button-background-color); + // color: var(--theme-upload-button-text-color); + // text-overflow: ellipsis; + // display: flex; + // padding: 0; + // margin-left: 12px; + // } + } \ No newline at end of file diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts b/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts new file mode 100644 index 0000000000..6b11a89a66 --- /dev/null +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts @@ -0,0 +1,109 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AppTestingModule } from '../../testing/app-testing.module'; +import { HeaderActionsComponent } from './header-actions.component'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { MatButtonHarness } from '@angular/material/button/testing'; +import { MatMenuHarness } from '@angular/material/menu/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { By } from '@angular/platform-browser'; + +describe('HeaderActionsComponent', () => { + let component: HeaderActionsComponent; + let fixture: ComponentFixture; + let loader: HarnessLoader; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [AppTestingModule, NoopAnimationsModule, MatButtonModule, MatMenuModule], + declarations: [HeaderActionsComponent] + }); + + fixture = TestBed.createComponent(HeaderActionsComponent); + component = fixture.componentInstance; + loader = TestbedHarnessEnvironment.loader(fixture); + }); + + it('total number of buttons in header should be 2 if route is personal-files', async () => { + spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); + const buttons = await loader.getAllHarnesses(MatButtonHarness); + const createButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.CREATE'})); + const uploadButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.UPLOAD'})); + + expect(buttons.length).toBe(2); + expect(createButton.length).toBe(1); + expect(uploadButton.length).toBe(1); + }); + + it('total number of buttons in header should be 1 if route is libraries', async () => { + spyOn(component, 'isLibrariesRoute').and.returnValue(true); + const buttons = await loader.getAllHarnesses(MatButtonHarness); + const createButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.CREATE'})); + + expect(buttons.length).toBe(1); + expect(createButton.length).toBe(1); + }); + + it('should open and close the create menu', async () => { + spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); + const createMenu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'APP.HEADER.BUTTONS.CREATE' })); + + expect(await createMenu.isOpen()).toBe(false); + await createMenu.open(); + expect(await createMenu.isOpen()).toBe(true); + + await createMenu.close(); + expect(await createMenu.isOpen()).toBe(false); + }); + + it('should open and close the upload menu', async () => { + spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); + const uploadMenu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'APP.HEADER.BUTTONS.UPLOAD' })); + + expect(await uploadMenu.isOpen()).toBe(false); + await uploadMenu.open(); + expect(await uploadMenu.isOpen()).toBe(true); + + await uploadMenu.close(); + expect(await uploadMenu.isOpen()).toBe(false); + }); + + it('should load create menu on click of create button', async () => { + spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); + + const buttons = await loader.getHarness(MatButtonHarness.with({ selector: '.aca-create-button' })); + buttons.click(); + + const createMenu = fixture.debugElement.queryAll(By.css('.app-create-menu__root-menu app-create-menu__sub-menu')); + expect(createMenu).toBeTruthy(); + }); + + it('should load upload menu on click of upload button', async () => { + spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); + + const buttons = await loader.getHarness(MatButtonHarness.with({ selector: '.aca-upload-button' })); + buttons.click(); + + const uploadMenu = fixture.debugElement.queryAll(By.css('.app-upload-menu__root-menu app-upload-menu__sub-menu')); + expect(uploadMenu).toBeTruthy(); + }); +}); diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts b/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts new file mode 100644 index 0000000000..1aebc00ab5 --- /dev/null +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts @@ -0,0 +1,96 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2020 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { ContentManagementService } from '../../services/content-management.service'; +import { AppExtensionService, PageComponent } from '@alfresco/aca-shared'; +import { SetCurrentFolderAction, AppStore } from '@alfresco/aca-shared/store'; + +@Component({ + selector: 'aca-header-actions', + templateUrl: './header-actions.component.html', + styleUrls: ['./header-actions.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class HeaderActionsComponent extends PageComponent implements OnInit, OnDestroy { + constructor(private router: Router, store: Store, content: ContentManagementService, extensions: AppExtensionService) { + super(store, extensions, content); + } + + ngOnInit() { + super.ngOnInit(); + } + + ngOnDestroy() { + this.store.dispatch(new SetCurrentFolderAction(null)); + super.ngOnDestroy(); + } + + isPersonalFilesRoute(): boolean { + return this.router.url.includes('/personal-files'); + } + + isFavoriteLibrariesRoute(): boolean { + return this.router.url.includes('/favorite/libraries'); + } + + isLibrariesRoute(): boolean { + return this.router.url.includes('/libraries'); + } + + canShowCreateButton(): boolean { + if (this.isPersonalFilesRoute() || this.isFavoriteLibrariesRoute() || this.isLibrariesRoute()) { + return true; + } else { + return false; + } + } + + canShowUploadButton(): boolean { + if (this.isPersonalFilesRoute()) { + return true; + } else { + return false; + } + } + + canShowSearchSeparator(): boolean { + if (this.isPersonalFilesRoute() || this.isFavoriteLibrariesRoute() || this.isLibrariesRoute()) { + return true; + } else { + return false; + } + } + + isTasksRoute(): boolean { + return this.router.url.includes('/tasks'); + } + + isProcessesRoute(): boolean { + return this.router.url.includes('/processes'); + } +} diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.module.ts b/projects/aca-content/src/lib/components/header-actions/header-actions.module.ts new file mode 100644 index 0000000000..8205ec9c12 --- /dev/null +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.module.ts @@ -0,0 +1,55 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2020 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { CoreModule } from '@alfresco/adf-core'; +import { ContentModule } from '@alfresco/adf-content-services'; +import { AppCommonModule } from '../common/common.module'; +import { AppToolbarModule } from '../toolbar/toolbar.module'; +import { DirectivesModule } from '../../directives/directives.module'; +import { ContextMenuModule } from '../context-menu/context-menu.module'; +import { AppLayoutModule } from '../layout/layout.module'; +import { AppSearchInputModule } from '../search/search-input.module'; +import { HeaderActionsComponent } from './header-actions.component'; +import { MainActionModule } from '../main-action/main-action.module'; + +@NgModule({ + imports: [ + CommonModule, + CoreModule.forChild(), + ContentModule.forChild(), + DirectivesModule, + AppCommonModule, + AppToolbarModule, + ContextMenuModule, + AppLayoutModule, + AppSearchInputModule, + MainActionModule + ], + declarations: [HeaderActionsComponent], + exports: [HeaderActionsComponent] +}) +export class AppHeaderActionsModule {} diff --git a/projects/aca-content/src/lib/components/libraries/libraries.component.html b/projects/aca-content/src/lib/components/libraries/libraries.component.html index 0f7c0aa4fd..d917f51231 100644 --- a/projects/aca-content/src/lib/components/libraries/libraries.component.html +++ b/projects/aca-content/src/lib/components/libraries/libraries.component.html @@ -1,7 +1,7 @@ - + diff --git a/projects/aca-content/src/lib/components/recent-files/recent-files.component.html b/projects/aca-content/src/lib/components/recent-files/recent-files.component.html index 4c95af8f23..9004b2d2f1 100644 --- a/projects/aca-content/src/lib/components/recent-files/recent-files.component.html +++ b/projects/aca-content/src/lib/components/recent-files/recent-files.component.html @@ -1,7 +1,7 @@ - + diff --git a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.scss b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.scss index 46fa1ca03c..658fcede4e 100644 --- a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.scss +++ b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.scss @@ -22,6 +22,7 @@ $top-margin: 12px; font-size: 16px; padding-left: 15px; box-sizing: border-box; + margin-bottom: 12px !important; .mat-form-field { font-size: 16px; diff --git a/projects/aca-content/src/lib/components/search/search-input.service.spec.ts b/projects/aca-content/src/lib/components/search/search-input.service.spec.ts new file mode 100644 index 0000000000..b1f27408b8 --- /dev/null +++ b/projects/aca-content/src/lib/components/search/search-input.service.spec.ts @@ -0,0 +1,66 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2020 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { TestBed } from '@angular/core/testing'; +import { CoreModule } from '@alfresco/adf-core'; +import { TranslateModule } from '@ngx-translate/core'; +import { SearchInputService } from './search-input.service'; +import { Router } from '@angular/router'; + +describe('SearchInputService', () => { + let service: SearchInputService; + let router: Router; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), CoreModule.forRoot()] + }); + service = TestBed.inject(SearchInputService); + router = TestBed.inject(Router); + }); + + it('should not navigate to saved route when exitSearch function is called if saved route is null', () => { + const routerNavigate = spyOn(router, 'navigate'); + service.savedRoute = ''; + service.exitSearch(); + + expect(routerNavigate).not.toHaveBeenCalledWith([service.savedRoute]); + }); + + it('should navigate to saved route when exitSearch function is called', () => { + const routerNavigate = spyOn(router, 'navigate'); + service.savedRoute = '/personal-files'; + service.exitSearch(); + + expect(routerNavigate).toHaveBeenCalledWith([service.savedRoute]); + }); + + it('should navigate to Search when navigateToSearch function is called', () => { + const routerNavigate = spyOn(router, 'navigate'); + service.navigateToSearch(); + + expect(routerNavigate).toHaveBeenCalledWith(['/search']); + }); +}); diff --git a/projects/aca-content/src/lib/components/search/search-input.service.ts b/projects/aca-content/src/lib/components/search/search-input.service.ts new file mode 100644 index 0000000000..0a84306059 --- /dev/null +++ b/projects/aca-content/src/lib/components/search/search-input.service.ts @@ -0,0 +1,55 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2020 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; + +@Injectable({ + providedIn: 'root' +}) +export class SearchInputService { + savedRoute = ''; + + constructor(private router: Router) {} + + isSearchRoute(): boolean { + return this.router.url.includes('/search'); + } + + saveRoute(route: string) { + this.savedRoute = route; + } + + exitSearch() { + if (this.savedRoute.length > 0) { + this.router.navigate([this.savedRoute]); + } + } + + navigateToSearch() { + this.saveRoute(this.router.url); + this.router.navigate(['/search']); + } +} diff --git a/projects/aca-content/src/lib/components/search/search-input/search-input.component.html b/projects/aca-content/src/lib/components/search/search-input/search-input.component.html index b9a0ab48f1..33c173fbc7 100644 --- a/projects/aca-content/src/lib/components/search/search-input/search-input.component.html +++ b/projects/aca-content/src/lib/components/search/search-input/search-input.component.html @@ -1,13 +1,14 @@ -
+ - + arrow_drop_down
- + + + +
+ +
+
diff --git a/projects/aca-content/src/lib/components/search/search-input/search-input.component.scss b/projects/aca-content/src/lib/components/search/search-input/search-input.component.scss index 3aaad8e99d..8020ce16d7 100644 --- a/projects/aca-content/src/lib/components/search/search-input/search-input.component.scss +++ b/projects/aca-content/src/lib/components/search/search-input/search-input.component.scss @@ -1,5 +1,5 @@ $search-width: 594px; -$search-height: 40px; +$search-height: 32px; $search-background: #f5f6f5; $search-border-radius: 4px; $top-margin: 12px; @@ -9,8 +9,27 @@ $top-margin: 12px; width: 100%; max-width: $search-width; height: $search-height + $top-margin; + margin: 0 !important; + + .app-search-button { + width: 32px !important; + height: 32px !important; + margin-left: 0 !important; + padding-left: 0 !important; + margin-top: -4px !important; + } .app-input-form-field { + + .app-close-icon { + height: 6px; + + .mat-icon { + font-size: 18px !important; + line-height: 28px; + } + } + .mat-input-element { caret-color: var(--theme-text-color); @@ -52,6 +71,8 @@ mat-checkbox { background-color: $search-background; border-radius: $search-border-radius; height: $search-height; + margin-bottom: 0 !important; + padding-bottom: 26px !important; } .app-search-control { diff --git a/projects/aca-content/src/lib/components/search/search-input/search-input.component.spec.ts b/projects/aca-content/src/lib/components/search/search-input/search-input.component.spec.ts index 193a3a1da2..cdeeb3031a 100644 --- a/projects/aca-content/src/lib/components/search/search-input/search-input.component.spec.ts +++ b/projects/aca-content/src/lib/components/search/search-input/search-input.component.spec.ts @@ -31,12 +31,14 @@ import { SearchByTermAction, SearchActionTypes, SnackbarErrorAction, SnackbarAct import { AppHookService } from '@alfresco/aca-shared'; import { map } from 'rxjs/operators'; import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; +import { SearchInputService } from '../search-input.service'; describe('SearchInputComponent', () => { let fixture: ComponentFixture; let component: SearchInputComponent; let actions$: Actions; let appHookService: AppHookService; + let searchInputService: SearchInputService; beforeEach(() => { TestBed.configureTestingModule({ @@ -49,12 +51,21 @@ describe('SearchInputComponent', () => { actions$ = TestBed.inject(Actions); fixture = TestBed.createComponent(SearchInputComponent); appHookService = TestBed.inject(AppHookService); + searchInputService = TestBed.inject(SearchInputService); component = fixture.componentInstance; - fixture.detectChanges(); }); - it('should change flag on library400Error event', () => { + afterEach(() => { + fixture.destroy(); + }); + + it('should change flag on library400Error event', async () => { + spyOn(searchInputService, 'isSearchRoute').and.returnValue(true); + fixture.detectChanges(); + await fixture.whenStable(); + expect(component.has400LibraryError).toBe(false); + appHookService.library400Error.next(); expect(component.has400LibraryError).toBe(true); @@ -64,9 +75,14 @@ describe('SearchInputComponent', () => { expect(component.hasLibraryConstraint()).toBe(false); }); - it('should have library constraint on 400 error received', () => { + it('should have library constraint on 400 error received', async () => { + spyOn(searchInputService, 'isSearchRoute').and.returnValue(true); + fixture.detectChanges(); + await fixture.whenStable(); + const libItem = component.searchOptions.find((item) => item.key.toLowerCase().indexOf('libraries') > 0); libItem.value = true; + appHookService.library400Error.next(); expect(component.hasLibraryConstraint()).toBe(true); @@ -192,4 +208,44 @@ describe('SearchInputComponent', () => { expect(component.isContentChecked()).toBe(true); }); }); + + describe('navigateToSearch()', () => { + it('should navigate to search on click of search icon', async () => { + spyOn(searchInputService, 'isSearchRoute').and.returnValue(false); + spyOn(component, 'navigateToSearch').and.callThrough(); + spyOn(searchInputService, 'navigateToSearch').and.callThrough(); + + fixture.detectChanges(); + await fixture.whenStable(); + + const searchIcon = fixture.debugElement.nativeElement.querySelector('.app-search-button'); + searchIcon.click(); + + fixture.detectChanges(); + await fixture.whenStable(); + + expect(component.navigateToSearch).toHaveBeenCalled(); + expect(searchInputService.navigateToSearch).toHaveBeenCalledWith(); + }); + }); + + describe('exitSearch()', () => { + it('should exit search on click of close icon', async () => { + spyOn(searchInputService, 'isSearchRoute').and.returnValue(true); + spyOn(component, 'exitSearch').and.callThrough(); + spyOn(searchInputService, 'exitSearch').and.callThrough(); + + fixture.detectChanges(); + await fixture.whenStable(); + + const closeIcon = fixture.debugElement.nativeElement.querySelector('.app-close-icon'); + closeIcon.click(); + + fixture.detectChanges(); + await fixture.whenStable(); + + expect(component.exitSearch).toHaveBeenCalled(); + expect(searchInputService.exitSearch).toHaveBeenCalledWith(); + }); + }); }); diff --git a/projects/aca-content/src/lib/components/search/search-input/search-input.component.ts b/projects/aca-content/src/lib/components/search/search-input/search-input.component.ts index a445c5f5db..0ebacbdb26 100644 --- a/projects/aca-content/src/lib/components/search/search-input/search-input.component.ts +++ b/projects/aca-content/src/lib/components/search/search-input/search-input.component.ts @@ -33,6 +33,7 @@ import { Store } from '@ngrx/store'; import { Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; import { SearchInputControlComponent } from '../search-input-control/search-input-control.component'; +import { SearchInputService } from '../search-input.service'; import { SearchLibrariesQueryBuilderService } from '../search-libraries-results/search-libraries-query-builder.service'; @Component({ @@ -84,26 +85,37 @@ export class SearchInputComponent implements OnInit, OnDestroy { private config: AppConfigService, private router: Router, private store: Store, - private appHookService: AppHookService + private appHookService: AppHookService, + public searchInputService: SearchInputService ) { this.searchOnChange = this.config.get('search.aca:triggeredOnChange', true); } ngOnInit() { - this.showInputValue(); - - this.router.events - .pipe(takeUntil(this.onDestroy$)) - .pipe(filter((e) => e instanceof RouterEvent)) - .subscribe((event) => { - if (event instanceof NavigationEnd) { - this.showInputValue(); - } + if (this.searchInputService.isSearchRoute()) { + this.showInputValue(); + + this.router.events + .pipe(takeUntil(this.onDestroy$)) + .pipe(filter((e) => e instanceof RouterEvent)) + .subscribe((event) => { + if (event instanceof NavigationEnd) { + this.showInputValue(); + } + }); + + this.appHookService.library400Error.pipe(takeUntil(this.onDestroy$)).subscribe(() => { + this.has400LibraryError = true; }); + } + } + + navigateToSearch() { + this.searchInputService.navigateToSearch(); + } - this.appHookService.library400Error.pipe(takeUntil(this.onDestroy$)).subscribe(() => { - this.has400LibraryError = true; - }); + exitSearch() { + this.searchInputService.exitSearch(); } showInputValue() { @@ -139,7 +151,6 @@ export class SearchInputComponent implements OnInit, OnDestroy { } else { this.store.dispatch(new SnackbarErrorAction('APP.BROWSE.SEARCH.EMPTY_SEARCH')); } - this.trigger.closeMenu(); } onSearchChange(searchTerm: string) { diff --git a/projects/aca-content/src/lib/components/search/search-results.module.ts b/projects/aca-content/src/lib/components/search/search-results.module.ts index c30f767590..fd63912b86 100644 --- a/projects/aca-content/src/lib/components/search/search-results.module.ts +++ b/projects/aca-content/src/lib/components/search/search-results.module.ts @@ -38,6 +38,8 @@ import { AppLayoutModule } from '../layout/layout.module'; import { ContextMenuModule } from '../context-menu/context-menu.module'; import { SearchActionMenuComponent } from './search-action-menu/search-action-menu.component'; import { DocumentListCustomComponentsModule } from '../dl-custom-components/document-list-custom-components.module'; +import { AppSearchInputModule } from './search-input.module'; +import { AppHeaderActionsModule } from '../header-actions/header-actions.module'; @NgModule({ imports: [ @@ -51,7 +53,9 @@ import { DocumentListCustomComponentsModule } from '../dl-custom-components/docu AppLayoutModule, ContextMenuModule, LockedByModule, - DocumentListCustomComponentsModule + DocumentListCustomComponentsModule, + AppSearchInputModule, + AppHeaderActionsModule ], declarations: [SearchResultsComponent, SearchLibrariesResultsComponent, SearchResultsRowComponent, SearchActionMenuComponent], exports: [SearchResultsComponent, SearchLibrariesResultsComponent, SearchResultsRowComponent, SearchActionMenuComponent] diff --git a/projects/aca-content/src/lib/components/search/search-results/search-results.component.html b/projects/aca-content/src/lib/components/search/search-results/search-results.component.html index 0c652273ec..02f3e8b616 100644 --- a/projects/aca-content/src/lib/components/search/search-results/search-results.component.html +++ b/projects/aca-content/src/lib/components/search/search-results/search-results.component.html @@ -1,7 +1,7 @@ - - + + diff --git a/projects/aca-content/src/lib/components/search/search-results/search-results.component.scss b/projects/aca-content/src/lib/components/search/search-results/search-results.component.scss index e10f63ead9..f152179e11 100644 --- a/projects/aca-content/src/lib/components/search/search-results/search-results.component.scss +++ b/projects/aca-content/src/lib/components/search/search-results/search-results.component.scss @@ -3,6 +3,13 @@ $adf-chip-background: #efefef; $contrast-gray: #646569; +.adf-toolbar-search-results { + position: fixed; + right: 24px; + height: 32px; + margin-bottom: 32px !important; +} + .adf-search-results { @include flex-row; diff --git a/projects/aca-content/src/lib/components/shared-files/shared-files.component.html b/projects/aca-content/src/lib/components/shared-files/shared-files.component.html index e5f2dbec25..05607dbc7f 100644 --- a/projects/aca-content/src/lib/components/shared-files/shared-files.component.html +++ b/projects/aca-content/src/lib/components/shared-files/shared-files.component.html @@ -1,7 +1,7 @@ - + diff --git a/projects/aca-content/src/lib/components/trashcan/trashcan.component.html b/projects/aca-content/src/lib/components/trashcan/trashcan.component.html index a253fc3287..d09c651022 100644 --- a/projects/aca-content/src/lib/components/trashcan/trashcan.component.html +++ b/projects/aca-content/src/lib/components/trashcan/trashcan.component.html @@ -1,7 +1,7 @@ - + diff --git a/projects/aca-content/src/lib/components/trashcan/trashcan.module.ts b/projects/aca-content/src/lib/components/trashcan/trashcan.module.ts index 99f31f34df..863a6b015d 100644 --- a/projects/aca-content/src/lib/components/trashcan/trashcan.module.ts +++ b/projects/aca-content/src/lib/components/trashcan/trashcan.module.ts @@ -32,6 +32,8 @@ import { AppToolbarModule } from '../toolbar/toolbar.module'; import { DirectivesModule } from '../../directives/directives.module'; import { ContextMenuModule } from '../context-menu/context-menu.module'; import { AppLayoutModule } from '../layout/layout.module'; +import { AppSearchInputModule } from '../search/search-input.module'; +import { AppHeaderActionsModule } from '../header-actions/header-actions.module'; @NgModule({ imports: [ @@ -42,7 +44,9 @@ import { AppLayoutModule } from '../layout/layout.module'; AppCommonModule, AppToolbarModule, ContextMenuModule, - AppLayoutModule + AppLayoutModule, + AppSearchInputModule, + AppHeaderActionsModule ], declarations: [TrashcanComponent], exports: [TrashcanComponent] diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 3475291911..f6d50cc886 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -36,6 +36,9 @@ $selected-text-color: #212121; $selected-background-color: rgba(31, 116, 219, 0.24); $action-button-text-color: rgba(33, 35, 40, 0.7); $tooltip-background-color: #ffffff; +$create-button-text-color: #212121; +$upload-button-background-color: #2A7DE1; +$page-layout-header-background-color: #ffffff; // CSS Variables $defaults: ( @@ -81,6 +84,11 @@ $defaults: ( --theme-action-button-text-color: $action-button-text-color, --theme-header-border-color: $grey-background, --theme-tooltip-background-color: $tooltip-background-color, + --theme-page-layout-header-background-color: $page-layout-header-background-color, + --theme-create-button-background-color: $grey-text-background, + --theme-create-button-text-color: $create-button-text-color, + --theme-upload-button-background-color: $upload-button-background-color, + --theme-upload-button-text-color: $pagination-background-color, ); // propagates SCSS variables into the CSS variables scope diff --git a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts index 1e5abbbcd1..f65c1f4983 100644 --- a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts +++ b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts @@ -24,7 +24,7 @@ import { DocumentListComponent, ShareDataRow } from '@alfresco/adf-content-services'; import { ShowHeaderMode } from '@alfresco/adf-core'; -import { ContentActionRef, DocumentListPresetRef, SelectionState } from '@alfresco/adf-extensions'; +import { ContentActionRef, ContentActionType, DocumentListPresetRef, SelectionState } from '@alfresco/adf-extensions'; import { OnDestroy, OnInit, OnChanges, ViewChild, SimpleChanges, Directive } from '@angular/core'; import { Store } from '@ngrx/store'; import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging } from '@alfresco/js-api'; @@ -67,12 +67,32 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { nodeResult: NodePaging; showHeader = ShowHeaderMode.Data; filterSorting = 'name-asc'; + createActions: Array = []; + uploadActions: Array = []; + mainAction$: Observable; + actionTypes = ContentActionType; protected subscriptions: Subscription[] = []; protected constructor(protected store: Store, protected extensions: AppExtensionService, protected content: DocumentBasePageService) {} ngOnInit() { + this.mainAction$ = this.extensions.getMainAction().pipe(takeUntil(this.onDestroy$)); + + this.extensions + .getCreateActions() + .pipe(takeUntil(this.onDestroy$)) + .subscribe((actions) => { + this.createActions = actions; + }); + + this.extensions + .getUploadActions() + .pipe(takeUntil(this.onDestroy$)) + .subscribe((actions) => { + this.uploadActions = actions; + }); + this.sharedPreviewUrl$ = this.store.select(getSharedUrl); this.infoDrawerOpened$ = this.store.select(isInfoDrawerOpened).pipe(map((infoDrawerState) => !this.isOutletPreviewUrl() && infoDrawerState)); @@ -123,6 +143,10 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { this.store.dispatch(new SetSelectedNodesAction([])); } + runAction(action: string): void { + this.extensions.runActionById(action); + } + showPreview(node: MinimalNodeEntity, extras?: ViewNodeExtras) { if (node && node.entry) { let id: string; diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss index c537aed39f..318bd89d36 100644 --- a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -7,8 +7,8 @@ display: flex; align-items: center; flex: 0 0 65px; - flex-basis: 48px; - background: var(--theme-background-color); + flex-basis: 96px; + background: var(--theme-page-layout-header-background-color); border-bottom: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); padding: 0 24px; } diff --git a/projects/aca-shared/src/lib/services/app.extension.service.ts b/projects/aca-shared/src/lib/services/app.extension.service.ts index d28abdee0e..04207500a5 100644 --- a/projects/aca-shared/src/lib/services/app.extension.service.ts +++ b/projects/aca-shared/src/lib/services/app.extension.service.ts @@ -78,6 +78,7 @@ export class AppExtensionService implements RuleContext { private _contextMenuActions = new BehaviorSubject>([]); private _openWithActions = new BehaviorSubject>([]); private _createActions = new BehaviorSubject>([]); + private _uploadActions = new BehaviorSubject>([]); private _mainActions = new BehaviorSubject(null); private _sidebarActions = new BehaviorSubject>([]); @@ -157,6 +158,7 @@ export class AppExtensionService implements RuleContext { this._contextMenuActions.next(this.loader.getContentActions(config, 'features.contextMenu')); this._openWithActions.next(this.loader.getContentActions(config, 'features.viewer.openWith')); this._createActions.next(this.loader.getElements(config, 'features.create')); + this._uploadActions.next(this.loader.getElements(config, 'features.upload')); this._mainActions.next(this.loader.getFeatures(config).mainAction); this.navbar = this.loadNavBar(config); @@ -359,6 +361,18 @@ export class AppExtensionService implements RuleContext { ); } + getUploadActions(): Observable> { + return this._uploadActions.pipe( + map((uploadActions) => + uploadActions + .filter((action) => this.filterVisible(action)) + .map((action) => this.copyAction(action)) + .map((action) => this.buildMenu(action)) + .map((action) => this.setActionDisabledFromRule(action)) + ) + ); + } + getMainAction(): Observable { return this._mainActions.pipe( filter((mainAction) => mainAction && this.filterVisible(mainAction)), From f75e4912aef3f14ba3f88ea92adbe78b7d9f2c45 Mon Sep 17 00:00:00 2001 From: SheenaMalhotra182 Date: Thu, 9 Feb 2023 20:24:12 +0530 Subject: [PATCH 03/85] implemented review comments and removed process related code --- .../header-actions.component.html | 2 - .../header-actions.component.scss | 127 +++++++---------- .../header-actions.component.spec.ts | 130 +++++++++++------- .../header-actions.component.ts | 8 -- .../document-base-page.component.ts | 11 +- .../page-layout/page-layout.component.scss | 6 + 6 files changed, 140 insertions(+), 144 deletions(-) diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.html b/projects/aca-content/src/lib/components/header-actions/header-actions.component.html index a5bd756abf..0cd3517962 100644 --- a/projects/aca-content/src/lib/components/header-actions/header-actions.component.html +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.html @@ -24,8 +24,6 @@
- - diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss b/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss index 46124d3ace..6474ee2528 100644 --- a/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.scss @@ -1,80 +1,55 @@ .aca-page-layout-header { - // display: flex; - // align-items: center; - // flex: 0 0 65px; - // flex-basis: 96px; - // background: var(--theme-page-layout-header-background-color); - // border-bottom: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); - // padding: 0 24px; - .adf-breadcrumb-item { - font-size: 20px !important; - font-weight: 400 !important; - letter-spacing: 0.15px !important; - } + .app-search-input { + background: none; + } - .app-search-input { - background: none; - } - - .action-bar { - display: flex; - flex: auto; - height: 32px; - margin-left: 24px; + .action-bar { + display: flex; + flex: auto; + height: 32px; + margin-left: 24px; - adf-toolbar-divider { - width: 24px !important; - height: 32px !important; - margin: 4px 0 0 12px !important; - } - } - - .aca-mat-button { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - letter-spacing: 0.25px; - font-weight: 500; - font-size: 14px; - font-style: normal; - border-radius: 6px; - border: none; - } - - .aca-create-button { - width: 71px !important; - min-width: 71px; - height: 32px; - background-color: var(--theme-create-button-background-color); - color: var(--theme-create-button-text-color); - text-overflow: ellipsis; - display: flex; - padding: 0; - } - - .aca-upload-button { - width: 73px !important; - min-width: 73px; - height: 32px; - background-color: var(--theme-upload-button-background-color); - color: var(--theme-upload-button-text-color); - text-overflow: ellipsis; - display: flex; - padding: 0; - margin-left: 12px; - } - - // .aca-process-button { - // width: 130px !important; - // min-width: 130px; - // height: 32px; - // background-color: var(--theme-upload-button-background-color); - // color: var(--theme-upload-button-text-color); - // text-overflow: ellipsis; - // display: flex; - // padding: 0; - // margin-left: 12px; - // } - } \ No newline at end of file + adf-toolbar-divider { + width: 24px !important; + height: 32px !important; + margin: 4px 0 0 12px !important; + } + } + + .aca-mat-button { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + letter-spacing: 0.25px; + font-weight: 500; + font-size: 14px; + font-style: normal; + border-radius: 6px; + border: none; + } + + .aca-create-button { + width: 71px !important; + min-width: 71px; + height: 32px; + background-color: var(--theme-create-button-background-color); + color: var(--theme-create-button-text-color); + text-overflow: ellipsis; + display: flex; + padding: 0; + } + + .aca-upload-button { + width: 73px !important; + min-width: 73px; + height: 32px; + background-color: var(--theme-upload-button-background-color); + color: var(--theme-upload-button-text-color); + text-overflow: ellipsis; + display: flex; + padding: 0; + margin-left: 12px; + } +} \ No newline at end of file diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts b/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts index 6b11a89a66..6ae91a4e47 100644 --- a/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.spec.ts @@ -17,93 +17,125 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AppTestingModule } from '../../testing/app-testing.module'; -import { HeaderActionsComponent } from './header-actions.component'; -import { HarnessLoader } from '@angular/cdk/testing'; -import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; -import { MatButtonHarness } from '@angular/material/button/testing'; -import { MatMenuHarness } from '@angular/material/menu/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { MatButtonModule } from '@angular/material/button'; -import { MatMenuModule } from '@angular/material/menu'; +import { HeaderActionsComponent } from './header-actions.component' +import { ContentActionType } from '@alfresco/adf-extensions'; +import { AppExtensionService } from '@alfresco/aca-shared'; +import { of } from 'rxjs'; import { By } from '@angular/platform-browser'; +import { CoreModule } from '@alfresco/adf-core'; +import { AppHeaderActionsModule } from './header-actions.module'; describe('HeaderActionsComponent', () => { let component: HeaderActionsComponent; let fixture: ComponentFixture; - let loader: HarnessLoader; + + let extensionService: AppExtensionService; + let getCreateActionsSpy: jasmine.Spy; + let getUploadActionsSpy: jasmine.Spy; beforeEach(() => { TestBed.configureTestingModule({ - imports: [AppTestingModule, NoopAnimationsModule, MatButtonModule, MatMenuModule], + imports: [AppTestingModule, CoreModule.forRoot(), AppHeaderActionsModule], declarations: [HeaderActionsComponent] }); fixture = TestBed.createComponent(HeaderActionsComponent); component = fixture.componentInstance; - loader = TestbedHarnessEnvironment.loader(fixture); + extensionService = TestBed.inject(AppExtensionService); + + getCreateActionsSpy = spyOn(extensionService, 'getCreateActions'); + getCreateActionsSpy.and.returnValue( + of([ + { + id: 'action1', + type: ContentActionType.button, + title: 'create action one' + }, + { + id: 'action2', + type: ContentActionType.button, + title: 'create action two' + } + ]) + ); + + getUploadActionsSpy = spyOn(extensionService, 'getUploadActions'); + getUploadActionsSpy.and.returnValue( + of([ + { + id: 'action3', + type: ContentActionType.button, + title: 'upload action one' + } + ]) + ); + + fixture = TestBed.createComponent(HeaderActionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); }); it('total number of buttons in header should be 2 if route is personal-files', async () => { spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); - const buttons = await loader.getAllHarnesses(MatButtonHarness); - const createButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.CREATE'})); - const uploadButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.UPLOAD'})); + fixture.detectChanges(); + + const buttons = fixture.debugElement.queryAll(By.css('.action-bar > .aca-mat-button')); + const createButton: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="create-button"]')).nativeElement; + const uploadButton: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="upload-button"]')).nativeElement; expect(buttons.length).toBe(2); - expect(createButton.length).toBe(1); - expect(uploadButton.length).toBe(1); + expect(createButton).toBeTruthy(); + expect(uploadButton).toBeTruthy(); }); it('total number of buttons in header should be 1 if route is libraries', async () => { spyOn(component, 'isLibrariesRoute').and.returnValue(true); - const buttons = await loader.getAllHarnesses(MatButtonHarness); - const createButton = await loader.getAllHarnesses(MatButtonHarness.with({text: 'APP.HEADER.BUTTONS.CREATE'})); + fixture.detectChanges(); + + const buttons = fixture.debugElement.queryAll(By.css('.action-bar > .aca-mat-button')); + const createButton: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="create-button"]')).nativeElement; expect(buttons.length).toBe(1); - expect(createButton.length).toBe(1); + expect(createButton).toBeTruthy(); }); - it('should open and close the create menu', async () => { - spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); - const createMenu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'APP.HEADER.BUTTONS.CREATE' })); + async function clickCreateMenu() { + fixture.detectChanges(); + await fixture.whenStable(); - expect(await createMenu.isOpen()).toBe(false); - await createMenu.open(); - expect(await createMenu.isOpen()).toBe(true); + const button: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="create-button"]')).nativeElement; + button.click(); + } - await createMenu.close(); - expect(await createMenu.isOpen()).toBe(false); - }); - - it('should open and close the upload menu', async () => { - spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); - const uploadMenu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'APP.HEADER.BUTTONS.UPLOAD' })); + async function clickUploadMenu() { + fixture.detectChanges(); + await fixture.whenStable(); - expect(await uploadMenu.isOpen()).toBe(false); - await uploadMenu.open(); - expect(await uploadMenu.isOpen()).toBe(true); - - await uploadMenu.close(); - expect(await uploadMenu.isOpen()).toBe(false); - }); + const button: HTMLButtonElement = fixture.debugElement.query(By.css('[data-automation-id="upload-button"]')).nativeElement; + button.click(); + } - it('should load create menu on click of create button', async () => { + it('should render menu items when create menu is opened' , async () => { spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); + await clickCreateMenu(); - const buttons = await loader.getHarness(MatButtonHarness.with({ selector: '.aca-create-button' })); - buttons.click(); + const menuItems = fixture.debugElement.queryAll(By.css('.app-toolbar-menu-item')); + expect(menuItems.length).toBe(2); - const createMenu = fixture.debugElement.queryAll(By.css('.app-create-menu__root-menu app-create-menu__sub-menu')); - expect(createMenu).toBeTruthy(); + const menuItemOne: HTMLSpanElement = (menuItems[0].nativeElement as HTMLButtonElement).querySelector('[data-automation-id="menu-item-title"]'); + const menuItemTwo: HTMLSpanElement = (menuItems[1].nativeElement as HTMLButtonElement).querySelector('[data-automation-id="menu-item-title"]'); + expect(menuItemOne.innerText).toBe('create action one'); + expect(menuItemTwo.innerText).toBe('create action two'); }); - it('should load upload menu on click of upload button', async () => { + it('should render menu items when upload menu is opened', async () => { spyOn(component, 'isPersonalFilesRoute').and.returnValue(true); + await clickUploadMenu(); - const buttons = await loader.getHarness(MatButtonHarness.with({ selector: '.aca-upload-button' })); - buttons.click(); + const menuItems = fixture.debugElement.queryAll(By.css('.app-toolbar-menu-item')); + expect(menuItems.length).toBe(1); - const uploadMenu = fixture.debugElement.queryAll(By.css('.app-upload-menu__root-menu app-upload-menu__sub-menu')); - expect(uploadMenu).toBeTruthy(); + const menuItemOne: HTMLSpanElement = (menuItems[0].nativeElement as HTMLButtonElement).querySelector('[data-automation-id="menu-item-title"]'); + expect(menuItemOne.innerText).toBe('upload action one'); }); }); diff --git a/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts b/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts index 1aebc00ab5..c3371dbd5c 100644 --- a/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts +++ b/projects/aca-content/src/lib/components/header-actions/header-actions.component.ts @@ -85,12 +85,4 @@ export class HeaderActionsComponent extends PageComponent implements OnInit, OnD return false; } } - - isTasksRoute(): boolean { - return this.router.url.includes('/tasks'); - } - - isProcessesRoute(): boolean { - return this.router.url.includes('/processes'); - } } diff --git a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts index f65c1f4983..d93d90a81c 100644 --- a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts +++ b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts @@ -24,7 +24,7 @@ import { DocumentListComponent, ShareDataRow } from '@alfresco/adf-content-services'; import { ShowHeaderMode } from '@alfresco/adf-core'; -import { ContentActionRef, ContentActionType, DocumentListPresetRef, SelectionState } from '@alfresco/adf-extensions'; +import { ContentActionRef, DocumentListPresetRef, SelectionState } from '@alfresco/adf-extensions'; import { OnDestroy, OnInit, OnChanges, ViewChild, SimpleChanges, Directive } from '@angular/core'; import { Store } from '@ngrx/store'; import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging } from '@alfresco/js-api'; @@ -69,15 +69,12 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { filterSorting = 'name-asc'; createActions: Array = []; uploadActions: Array = []; - mainAction$: Observable; - actionTypes = ContentActionType; protected subscriptions: Subscription[] = []; protected constructor(protected store: Store, protected extensions: AppExtensionService, protected content: DocumentBasePageService) {} ngOnInit() { - this.mainAction$ = this.extensions.getMainAction().pipe(takeUntil(this.onDestroy$)); this.extensions .getCreateActions() @@ -92,7 +89,7 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { .subscribe((actions) => { this.uploadActions = actions; }); - + this.sharedPreviewUrl$ = this.store.select(getSharedUrl); this.infoDrawerOpened$ = this.store.select(isInfoDrawerOpened).pipe(map((infoDrawerState) => !this.isOutletPreviewUrl() && infoDrawerState)); @@ -143,10 +140,6 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { this.store.dispatch(new SetSelectedNodesAction([])); } - runAction(action: string): void { - this.extensions.runActionById(action); - } - showPreview(node: MinimalNodeEntity, extras?: ViewNodeExtras) { if (node && node.entry) { let id: string; diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss index 318bd89d36..fa0e809034 100644 --- a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -11,6 +11,12 @@ background: var(--theme-page-layout-header-background-color); border-bottom: 1px solid var(--theme-border-color, rgba(0, 0, 0, 0.07)); padding: 0 24px; + + .adf-breadcrumb-item { + font-size: 20px !important; + font-weight: 400 !important; + letter-spacing: 0.15px !important; + } } .aca-page-layout-content { From 977e27354cde1908abec80ae0553bc980839fb93 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Thu, 9 Feb 2023 17:40:52 +0000 Subject: [PATCH 04/85] Added expand and collapse functionality --- .../aca-about/src/lib/about.component.html | 4 +- .../aca-about/src/lib/about.component.scss | 10 ++++ projects/aca-about/src/lib/about.component.ts | 6 ++- projects/aca-content/assets/i18n/en.json | 3 +- .../components/sidenav/sidenav.component.html | 4 +- .../components/sidenav/sidenav.component.ts | 10 +++- .../view-profile/view-profile.component.html | 2 +- .../view-profile/view-profile.component.scss | 10 ++++ .../view-profile/view-profile.component.ts | 5 +- .../content-service-extension.service.ts | 8 +++ .../page-layout/page-layout.component.html | 14 ++++-- .../page-layout/page-layout.component.scss | 50 +++++++++++++++---- .../page-layout/page-layout.component.ts | 19 ++++++- .../page-layout/page-layout.module.ts | 3 +- 14 files changed, 122 insertions(+), 26 deletions(-) diff --git a/projects/aca-about/src/lib/about.component.html b/projects/aca-about/src/lib/about.component.html index 5791cb2fc5..b2e7a735e1 100644 --- a/projects/aca-about/src/lib/about.component.html +++ b/projects/aca-about/src/lib/about.component.html @@ -1,5 +1,4 @@ - - + @@ -26,4 +25,3 @@ - diff --git a/projects/aca-about/src/lib/about.component.scss b/projects/aca-about/src/lib/about.component.scss index caf329f4a9..ad19c222c4 100644 --- a/projects/aca-about/src/lib/about.component.scss +++ b/projects/aca-about/src/lib/about.component.scss @@ -2,3 +2,13 @@ adf-about { padding: 10px; width: 100%; } + +.app-about-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + bottom: 0; + right: 0; + height: 100%; +} diff --git a/projects/aca-about/src/lib/about.component.ts b/projects/aca-about/src/lib/about.component.ts index 0ffe39444e..dc857db341 100644 --- a/projects/aca-about/src/lib/about.component.ts +++ b/projects/aca-about/src/lib/about.component.ts @@ -29,6 +29,7 @@ import { AppExtensionService, ExtensionRef } from '@alfresco/adf-extensions'; import { AuthenticationService, RepositoryInfo } from '@alfresco/adf-core'; import { DiscoveryApiService } from '@alfresco/adf-content-services'; import { PACKAGE_JSON } from './package-json.token'; +import { ContentServiceExtensionService } from '../../../aca-content/src/lib/services/content-service-extension.service'; @Component({ selector: 'app-about-page', @@ -40,6 +41,7 @@ export class AboutComponent implements OnInit { dev = false; extensions$: Observable; repository: RepositoryInfo = null; + hideSidenav: boolean; constructor( @Inject(DEV_MODE_TOKEN) devMode, @@ -48,7 +50,8 @@ export class AboutComponent implements OnInit { public packageJson, private authService: AuthenticationService, private appExtensions: AppExtensionService, - private discovery: DiscoveryApiService + private discovery: DiscoveryApiService, + private contentServices: ContentServiceExtensionService ) { this.dev = !devMode; this.extensions$ = this.appExtensions.references$; @@ -58,6 +61,7 @@ export class AboutComponent implements OnInit { if (this.authService.isEcmLoggedIn()) { this.setECMInfo(); } + this.contentServices.cast.subscribe((data) => (this.hideSidenav = data)); } setECMInfo() { diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index 98e8891a81..f3ba71655c 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -427,7 +427,8 @@ "TOOLTIPS": { "COLLAPSE_NAVIGATION": "Collapse navigation menu", "OPTIONS_SETTINGS": "Options and settings", - "MY_PROFILE": "My profile" + "MY_PROFILE": "My profile", + "EXPAND_NAVIGATION": "Expand navigation" } }, "NODE_SELECTOR": { diff --git a/projects/aca-content/src/lib/components/sidenav/sidenav.component.html b/projects/aca-content/src/lib/components/sidenav/sidenav.component.html index 8b0a19915b..6da2dcfb19 100644 --- a/projects/aca-content/src/lib/components/sidenav/sidenav.component.html +++ b/projects/aca-content/src/lib/components/sidenav/sidenav.component.html @@ -1,8 +1,8 @@ -
+
-