Skip to content

Commit

Permalink
implementation ( Edit Content ) : #30015 Implement Show/Hide Toggle f…
Browse files Browse the repository at this point in the history
…or Hidden Column (#30147)

### Proposed Changes
* Hide/show the content information. 
* Safe the state based on local storage. 


### Screenshots


https://github.com/user-attachments/assets/b05007a0-5316-4a53-94d7-f2f167651129

---------

Co-authored-by: Arcadio Quintero <[email protected]>
  • Loading branch information
hmoreras and oidacra authored Sep 26, 2024
1 parent 81d923d commit 9909dff
Show file tree
Hide file tree
Showing 16 changed files with 338 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,49 @@
<aside class="content-aside">
<div class="content-aside__toolbar">
<div class="tabs"></div>
<button
class="p-button p-button-sm p-button-text p-button-rounded p-button-icon-only content-aside__closeBtn"
(click)="$toggle.emit(!$collapsed())"
data-testId="toggle-button">
<svg
width="16"
height="16"
viewBox="0 0 20 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Canvas" fill="none">
<g id="icon">
<g id="Rectangle 2">
<rect
x="1"
y="1"
width="18"
height="18"
rx="1"
stroke-width="2"
stroke="#444444" />
</g>
<g id="Rectangle 2.1">
<path
d="M 0 0L 2 0L 2 20L 0 20L 0 0Z"
transform="matrix(1 1.74846e-07 -1.74846e-07 1 12 0)"
fill="#444444" />
</g>
</g>
</g>
</svg>
</button>
</div>

<section class="content-aside__section">
<div class="content-aside__header">
<h2>{{ 'Information' | dm }}</h2>
</div>
<dot-content-aside-information
[contentlet]="contentlet"
[contentType]="contentType"
[loading]="loading"
[contentlet]="$contentlet()"
[contentType]="$contentType()"
[loading]="$loading()"
data-testId="information" />
</section>

Expand All @@ -19,8 +56,8 @@ <h2>{{ 'Workflow' | dm }}</h2>
</div>
</div>
<dot-content-aside-workflow
[inode]="contentlet?.inode"
[contentType]="contentType"
[inode]="$contentlet()?.inode"
[contentType]="$contentType()"
data-testId="workflow" />
</section>
</aside>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@
overflow: auto;
}

.p-button.content-aside__closeBtn {
rect {
stroke: $color-palette-primary;
}

path {
fill: $color-palette-primary;
}
}

.content-aside__toolbar {
padding: $spacing-2;
display: flex;
justify-content: space-between;
}

.content-aside,
.content-aside__section {
display: block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ describe('DotEditContentAsideComponent', () => {
let spectator: Spectator<DotEditContentAsideComponent>;
const createComponent = createComponentFactory({
component: DotEditContentAsideComponent,
detectChanges: false,
imports: [
HttpClientTestingModule,
DotContentAsideInformationComponent,
Expand All @@ -42,8 +41,10 @@ describe('DotEditContentAsideComponent', () => {
spectator = createComponent({
props: {
contentlet: CONTENT_FORM_DATA_MOCK.contentlet,
contentType: dotcmsContentTypeBasicMock
}
contentType: dotcmsContentTypeBasicMock,
loading: false,
collapsed: false
} as unknown
});
});

Expand All @@ -70,4 +71,14 @@ describe('DotEditContentAsideComponent', () => {
);
expect(dotContentAsideWorkflowComponent.contentType).toEqual(dotcmsContentTypeBasicMock);
});

it('should emit toggle event on button click', () => {
const spy = jest.spyOn(spectator.component.$toggle, 'emit');

const toggleBtn = spectator.query('[data-testId="toggle-button"]');

spectator.click(toggleBtn);

expect(spy).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';

import { DotCMSContentType, DotCMSContentlet } from '@dotcms/dotcms-models';
import { DotMessagePipe } from '@dotcms/ui';
Expand All @@ -15,7 +15,28 @@ import { DotContentAsideWorkflowComponent } from './components/dot-content-aside
imports: [DotMessagePipe, DotContentAsideInformationComponent, DotContentAsideWorkflowComponent]
})
export class DotEditContentAsideComponent {
@Input() contentlet!: DotCMSContentlet;
@Input() contentType!: DotCMSContentType;
@Input() loading!: boolean;
/**
* A variable with the contentlet information
*/
$contentlet = input.required<DotCMSContentlet>({ alias: 'contentlet' });

/**
* A variable with the content type
*/
$contentType = input.required<DotCMSContentType>({ alias: 'contentType' });

/**
* A variable to control the loading state
*/
$loading = input.required<boolean>({ alias: 'loading' });

/**
* A variable to control the collapsed state
*/
$collapsed = input.required<boolean>({ alias: 'collapsed' });

/**
* A variable to control the toggle state
*/
$toggle = output<boolean>({ alias: 'toggle' });
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<p-toolbar class="header">
<div class="p-toolbar-group-left"></div>
<div class="p-toolbar-group-right">
<ng-content></ng-content>
<dot-workflow-actions
(actionFired)="actionFired.emit($event)"
[actions]="actions"
(actionFired)="$actionFired.emit($event)"
[actions]="$actions()"
[groupActions]="true" />
</div>
</p-toolbar>
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@
justify-content: flex-start;
flex-direction: row-reverse; // Make the order of the buttons to be from right to left
}

:host:not(.showSidebar) {
::ng-deep {
.p-toolbar {
padding-right: 0.75rem;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('DotEditContentToolbarComponent', () => {
spectator = createComponent({
props: {
actions: WORKFLOW_ACTIONS_MOCK
}
} as unknown
});
spectator.detectComponentChanges();
});
Expand All @@ -36,7 +36,7 @@ describe('DotEditContentToolbarComponent', () => {
});

it('should emit the action dot-workflow-actions emits the fired action', () => {
const spy = jest.spyOn(spectator.component.actionFired, 'emit');
const spy = jest.spyOn(spectator.component.$actionFired, 'emit');
const component = spectator.query(DotWorkflowActionsComponent);

component.actionFired.emit(WORKFLOW_ACTIONS_MOCK[0]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';

import { ToolbarModule } from 'primeng/toolbar';

Expand All @@ -14,6 +14,6 @@ import { DotWorkflowActionsComponent } from '@dotcms/ui';
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DotEditContentToolbarComponent {
@Input() actions: DotCMSWorkflowAction[];
@Output() actionFired = new EventEmitter<DotCMSWorkflowAction>();
$actions = input.required<DotCMSWorkflowAction[]>({ alias: 'actions' });
$actionFired = output<DotCMSWorkflowAction>({ alias: 'actionFired' });
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@if (vm$ | async; as vm) {
@if (vm?.contentType?.metadata?.[featuredFlagContentKEY]) {
@if (vm?.contentType?.metadata?.[$featuredFlagContentKEY()]) {
<p-messages
class="topBar"
styleClass="p-message-border-y"
Expand Down Expand Up @@ -28,12 +28,50 @@
})
"
[actions]="vm.actions"
class="header"></dot-edit-content-toolbar>
class="header"
[class.showSidebar]="vm.layout.showSidebar">
<button
[class.showSidebar]="vm.layout.showSidebar"
class="edit-content-layout__sidebar-btn p-button p-button-sm p-button-text p-button-rounded p-button-icon-only content-aside__closeBtn"
(click)="toggleSidebar()"
data-testId="sidebar-toggle">
<svg
width="16"
height="16"
viewBox="0 0 20 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Canvas" fill="none">
<g id="icon">
<g id="Rectangle 2">
<rect
x="1"
y="1"
width="18"
height="18"
rx="1"
stroke-width="2"
stroke="#444444" />
</g>
<g id="Rectangle 2.1">
<path
d="M 0 0L 2 0L 2 20L 0 20L 0 0Z"
transform="matrix(1 1.74846e-07 -1.74846e-07 1 12 0)"
fill="#444444" />
</g>
</g>
</g>
</svg>
</button>
</dot-edit-content-toolbar>
<dot-edit-content-form (changeValue)="setFormValue($event)" [formData]="vm" class="body" />
<dot-edit-content-aside
[loading]="vm.loading"
[contentlet]="vm.contentlet"
[contentType]="vm.contentType"
[collapsed]="vm.layout.showSidebar"
(toggle)="toggleSidebar()"
class="sidebar" />
} @else {
{{ 'edit.content.layout.no.content.to.show ' | dm }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@
width: 100%;
}

.edit-content-layout__sidebar-btn {
rect {
stroke: $color-palette-primary;
}

path {
fill: $color-palette-primary;
}
transition: all 300ms ease-in-out;
&.showSidebar {
width: 0;
min-width: 0;
height: 0;
padding: 0;
visibility: hidden;
}
}

.topBar {
grid-area: topBar;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ describe('EditContentLayoutComponent', () => {
actions: mockWorkflowsActions,
contentType: CONTENT_TYPE_MOCK,
contentlet: BINARY_FIELD_CONTENTLET,
loading: false
loading: false,
layout: {
showSidebar: true
}
};

beforeEach(async () => {
Expand Down Expand Up @@ -119,22 +122,22 @@ describe('EditContentLayoutComponent', () => {
spectator.detectChanges();
const toolbarComponent = spectator.query(DotEditContentToolbarComponent);
expect(toolbarComponent).toBeDefined();
expect(toolbarComponent.actions).toEqual(mockData.actions);
expect(toolbarComponent.$actions).toEqual(mockData.actions);
});

it('should pass the contentlet and contentType to the DotEditContentAside Component', () => {
spectator.detectChanges();
const asideComponent = spectator.query(DotEditContentAsideComponent);
expect(asideComponent).toBeDefined();
expect(asideComponent.contentlet).toEqual(mockData.contentlet);
expect(asideComponent.contentType).toEqual(mockData.contentType);
expect(asideComponent.$contentlet).toEqual(mockData.contentlet);
expect(asideComponent.$contentType).toEqual(mockData.contentType);
});

it('should fire workflow action', () => {
const spyStore = jest.spyOn(dotEditContentStore, 'fireWorkflowActionEffect');
spectator.detectChanges();
const toolbarComponent = spectator.query(DotEditContentToolbarComponent);
toolbarComponent.actionFired.emit(mockWorkflowsActions[0]);
toolbarComponent.$actionFired.emit(mockWorkflowsActions[0]);

expect(spyStore).toHaveBeenCalledWith({
actionId: mockWorkflowsActions[0].id,
Expand Down Expand Up @@ -162,14 +165,29 @@ describe('EditContentLayoutComponent', () => {
const betaTopbar = spectator.query(byTestId('topBar'));
expect(betaTopbar).not.toBeNull();
});

it('should toggle the sidebar when the toggle button is clicked', () => {
spectator.detectChanges();
const toggleBtn = spectator.query(byTestId('sidebar-toggle'));

expect(toggleBtn.classList).toContain('showSidebar');

spectator.click(toggleBtn);

expect(toggleBtn.classList).not.toContain('showSidebar');
spectator.component.toggleSidebar();
});
});

describe('New content', () => {
const mockData: EditContentPayload = {
actions: mockWorkflowsActions,
contentType: CONTENT_TYPE_MOCK,
contentlet: null,
loading: false
loading: false,
layout: {
showSidebar: true
}
};

beforeEach(async () => {
Expand Down Expand Up @@ -226,15 +244,15 @@ describe('EditContentLayoutComponent', () => {
spectator.detectChanges();
const toolbarComponent = spectator.query(DotEditContentToolbarComponent);
expect(toolbarComponent).toBeDefined();
expect(toolbarComponent.actions).toEqual(mockData.actions);
expect(toolbarComponent.$actions).toEqual(mockData.actions);
});

it('should pass the contentlet and contentType to the DotEditContentAside Component', () => {
spectator.detectChanges();
const asideComponent = spectator.query(DotEditContentAsideComponent);
expect(asideComponent).toBeDefined();
expect(asideComponent.contentlet).toEqual(mockData.contentlet);
expect(asideComponent.contentType).toEqual(mockData.contentType);
expect(asideComponent.$contentlet).toEqual(mockData.contentlet);
expect(asideComponent.$contentType).toEqual(mockData.contentType);
});
});
});
Loading

0 comments on commit 9909dff

Please sign in to comment.