Skip to content

Commit

Permalink
feat(edit-content) add category field #28658
Browse files Browse the repository at this point in the history
  • Loading branch information
oidacra committed Jun 5, 2024
1 parent 4719303 commit 6cd8a77
Show file tree
Hide file tree
Showing 18 changed files with 380 additions and 41 deletions.
2 changes: 1 addition & 1 deletion core-web/libs/edit-content/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
"outputs": ["{options.outputFile}"]
}
},
"tags": []
"tags": ["type:feature", "scope:dotcms-ui", "portlet:edit-content"]
}
Original file line number Diff line number Diff line change
@@ -1,87 +1,92 @@
<label
[attr.data-testId]="'label-' + field.variable"
[for]="field.variable"
[checkIsRequiredControl]="field.variable"
dotFieldRequired
>{{ field.name }}</label
>
[for]="field.variable"
dotFieldRequired>
{{ field.name }}
</label>

<ng-container [ngSwitch]="field.fieldType">
<dot-edit-content-select-field
*ngSwitchCase="fieldTypes.SELECT"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-radio-field
*ngSwitchCase="fieldTypes.RADIO"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-text-field
*ngSwitchCase="fieldTypes.TEXT"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-text-area
*ngSwitchCase="fieldTypes.TEXTAREA"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-checkbox-field
*ngSwitchCase="fieldTypes.CHECKBOX"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-multi-select-field
*ngSwitchCase="fieldTypes.MULTI_SELECT"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-calendar-field
*ngSwitchCase="calendarTypes.includes(field.fieldType) ? field.fieldType : ''"
[field]="field"
[attr.data-testId]="'field-' + field.variable">
[attr.data-testId]="'field-' + field.variable"
[field]="field">
</dot-edit-content-calendar-field>

<dot-edit-content-tag-field
*ngSwitchCase="fieldTypes.TAG"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-json-field
*ngSwitchCase="fieldTypes.JSON"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-binary-field
*ngSwitchCase="fieldTypes.BINARY"
[formControlName]="field.variable"
[attr.data-testId]="'field-' + field.variable"
[contentlet]="contentlet"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[formControlName]="field.variable" />

<dot-edit-content-custom-field
*ngSwitchCase="fieldTypes.CUSTOM_FIELD"
[field]="field"
[attr.data-testId]="'field-' + field.variable"
[contentType]="contentType"
[attr.data-testId]="'field-' + field.variable" />
[field]="field" />

<dot-block-editor
*ngSwitchCase="fieldTypes.BLOCK_EDITOR"
[formControlName]="field.variable"
[attr.data-testId]="'field-' + field.variable"
[contentlet]="contentlet"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[formControlName]="field.variable" />

<dot-edit-content-key-value
*ngSwitchCase="fieldTypes.KEY_VALUE"
[formControlName]="field.variable"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[formControlName]="field.variable" />

<dot-edit-content-wysiwyg-field
*ngSwitchCase="fieldTypes.WYSIWYG"
[field]="field"
[attr.data-testId]="'field-' + field.variable" />
[attr.data-testId]="'field-' + field.variable"
[field]="field" />

<dot-edit-content-category-field
*ngSwitchCase="fieldTypes.CATEGORY"
[attr.data-testId]="'field-' + field.variable"
[field]="field" />
</ng-container>

<small *ngIf="field.hint" [attr.data-testId]="'hint-' + field.variable">{{ field.hint }}</small>
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
@use "variables" as *;

:host {
display: block;
height: fit-content;
margin-bottom: 0;

small {
margin-top: $spacing-1;
display: block;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { DotEditContentFieldComponent } from './dot-edit-content-field.component

import { DotEditContentBinaryFieldComponent } from '../../fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component';
import { DotEditContentCalendarFieldComponent } from '../../fields/dot-edit-content-calendar-field/dot-edit-content-calendar-field.component';
import { DotEditContentCategoryFieldComponent } from '../../fields/dot-edit-content-category-field/dot-edit-content-category-field.component';
import { DotEditContentCheckboxFieldComponent } from '../../fields/dot-edit-content-checkbox-field/dot-edit-content-checkbox-field.component';
import { DotEditContentCustomFieldComponent } from '../../fields/dot-edit-content-custom-field/dot-edit-content-custom-field.component';
import { DotEditContentJsonFieldComponent } from '../../fields/dot-edit-content-json-field/dot-edit-content-json-field.component';
Expand Down Expand Up @@ -128,6 +129,9 @@ const FIELD_TYPES_COMPONENTS: Record<FIELD_TYPES, Type<unknown> | DotEditFieldTe
[FIELD_TYPES.WYSIWYG]: {
component: DotEditContentWYSIWYGFieldComponent,
declarations: [MockComponent(EditorComponent)]
},
[FIELD_TYPES.CATEGORY]: {
component: DotEditContentCategoryFieldComponent
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { NgIf, NgSwitch, NgSwitchCase } from '@angular/common';
import { ChangeDetectionStrategy, Component, HostBinding, Input, inject } from '@angular/core';
import { ChangeDetectionStrategy, Component, HostBinding, inject, Input } from '@angular/core';
import { ControlContainer, ReactiveFormsModule } from '@angular/forms';

import { BlockEditorModule } from '@dotcms/block-editor';
import { DotCMSContentTypeField, DotCMSContentlet } from '@dotcms/dotcms-models';
import { DotCMSContentlet, DotCMSContentTypeField } from '@dotcms/dotcms-models';
import { DotFieldRequiredDirective } from '@dotcms/ui';

import { DotEditContentBinaryFieldComponent } from '../../fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<div class="column" *ngFor="let column of row.columns" data-testId="column">
<dot-edit-content-field
*ngFor="let field of column.fields"
[field]="field"
[contentlet]="formData.contentlet"
[contentType]="formData.contentType.variable"
[contentlet]="formData.contentlet"
[field]="field"
data-testId="field" />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<div class="category-field__dialog h-full w-full">
<div class="category-field__left-pane flex flex-column">Search & category tree</div>
<div class="category-field__right-pane flex flex-column">
<div class="category-field__selected-categories flex-1">Selected Categories</div>
<div class="category-field__actions flex justify-content-end">
<button
class="p-button p-button-link"
(click)="dialogRef.close()"
data-testId="cancel-btn"
pButton>
Cancel
{{ 'edit.content.category-field.cancel' | dm }}
</button>
<button class="p-button" data-testId="apply-btn">
{{ 'edit.content.category-field.apply' | dm }}
</button>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@use "variables" as *;

:host {
display: block;
height: 100%;

.category-field__dialog {
display: grid;
grid-template-columns: 2fr 1fr;
max-width: 1200px;
margin: auto;
}

.category-field__left-pane,
.category-field__right-pane {
padding: $spacing-3;
gap: $spacing-3;
}

.category-field__left-pane {
background-color: $color-palette-gray-300;
}

.category-field__selected-categories {
border: $field-border-size solid $color-palette-gray-400;
border-radius: $border-radius-sm;
padding: $spacing-3;
}

.category-field__actions {
gap: $spacing-1;
}
}

::ng-deep .category-field__dialog .p-dialog-content {
padding: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { expect, it } from '@jest/globals';
import { byTestId, createComponentFactory, Spectator } from '@ngneat/spectator';
import { mockProvider } from '@ngneat/spectator/jest';

import { DynamicDialogRef } from 'primeng/dynamicdialog';

import { DotMessageService } from '@dotcms/data-access';

import { DotEditContentCategoryFieldDialogComponent } from './dot-edit-content-category-field-dialog.component';

describe('DotEditContentCategoryFieldDialogComponent', () => {
let spectator: Spectator<DotEditContentCategoryFieldDialogComponent>;
let dialogRef: DynamicDialogRef;

const createComponent = createComponentFactory({
component: DotEditContentCategoryFieldDialogComponent,
providers: [
mockProvider(DynamicDialogRef, {
close: jest.fn()
}),
mockProvider(DotMessageService)
]
});

beforeEach(() => {
spectator = createComponent();
dialogRef = spectator.inject(DynamicDialogRef);
});

afterEach(() => {
jest.resetAllMocks();
});

it('should have a cancel button', () => {
expect(spectator.query(byTestId('cancel-btn'))).not.toBeNull();
});
it('should have a apply button', () => {
expect(spectator.query(byTestId('apply-btn'))).not.toBeNull();
});

it('should close the dialog when you click cancel', () => {
const cancelBtn = spectator.query(byTestId('cancel-btn'));
expect(cancelBtn).not.toBeNull();

expect(dialogRef.close).not.toHaveBeenCalled();

spectator.click(cancelBtn);
expect(dialogRef.close).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';

import { ButtonModule } from 'primeng/button';
import { DialogModule } from 'primeng/dialog';
import { DynamicDialogRef } from 'primeng/dynamicdialog';

import { DotMessagePipe } from '@dotcms/ui';

@Component({
selector: 'dot-edit-content-category-field-dialog',
standalone: true,
imports: [DialogModule, ButtonModule, DotMessagePipe],
templateUrl: './dot-edit-content-category-field-dialog.component.html',
styleUrl: './dot-edit-content-category-field-dialog.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DotEditContentCategoryFieldDialogComponent {
protected dialogRef: DynamicDialogRef = inject(DynamicDialogRef);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div class="dot-category-field__wrapper" [ngClass]="{ 'has-categories': values.length }">
@if (values.length) {
<div class="dot-category-field__categories" data-testId="category-chip-list">
@for (category of values; track category.id) {
<p-chip
[pTooltip]="category.value"
[removable]="true"
[label]="category.value"
tooltipPosition="top"
styleClass="p-chip-sm" />
}
</div>
}

<div class="dot-category-field__select">
<p-button
[label]="'edit.content.category-field.show-categories-dialog' | dm"
(onClick)="showCategories()"
data-testId="show-dialog-btn"
icon="pi pi-pencil"
styleClass="p-button-sm p-button-text p-button-secondary" />
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@use "variables" as *;

.dot-category-field__wrapper {
.dot-category-field__categories,
.dot-category-field__select {
border: $field-border-size solid $color-palette-gray-400;
display: flex;
flex-wrap: wrap;
align-items: center;
}

.dot-category-field__categories {
padding: $spacing-1;
gap: $spacing-1;
border-radius: $border-radius-md $border-radius-md 0 0;
}

.dot-category-field__select {
height: $field-height-md;
border-radius: $border-radius-md;
padding: 0 $spacing-0;
justify-content: flex-end;
}

&.has-categories {
.dot-category-field__select {
border-radius: 0 0 $border-radius-md $border-radius-md;
}

.dot-category-field__categories {
border-bottom: none;
}
}
}
Loading

0 comments on commit 6cd8a77

Please sign in to comment.