Skip to content

Commit

Permalink
chore(edit-content): UI with mock data #30515
Browse files Browse the repository at this point in the history
  • Loading branch information
nicobytes committed Nov 27, 2024
1 parent e9c8559 commit 79afd2f
Show file tree
Hide file tree
Showing 12 changed files with 464 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@
[field]="field" />
}
}
@case (fieldTypes.RELATIONSHIP) {
@defer (on immediate) {
<dot-edit-content-relationship-field
[formControlName]="field.variable"
[attr.data-testId]="'field-' + field.variable"
[field]="field" />
}
}
}
@if (field.hint) {
<small [attr.data-testId]="'hint-' + field.variable">{{ field.hint }}</small>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,25 @@ import { ControlContainer, ReactiveFormsModule } from '@angular/forms';

import { BlockEditorModule } from '@dotcms/block-editor';
import { DotCMSContentlet, DotCMSContentTypeField } from '@dotcms/dotcms-models';
import { DotEditContentBinaryFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component';
import { DotEditContentCalendarFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-calendar-field/dot-edit-content-calendar-field.component';
import { DotEditContentCategoryFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-category-field/dot-edit-content-category-field.component';
import { DotEditContentCheckboxFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-checkbox-field/dot-edit-content-checkbox-field.component';
import { DotEditContentCustomFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-custom-field/dot-edit-content-custom-field.component';
import { DotEditContentFileFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-file-field/dot-edit-content-file-field.component';
import { DotEditContentHostFolderFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-host-folder-field/dot-edit-content-host-folder-field.component';
import { DotEditContentJsonFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-json-field/dot-edit-content-json-field.component';
import { DotEditContentKeyValueComponent } from '@dotcms/edit-content/fields/dot-edit-content-key-value/dot-edit-content-key-value.component';
import { DotEditContentMultiSelectFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-multi-select-field/dot-edit-content-multi-select-field.component';
import { DotEditContentRadioFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-radio-field/dot-edit-content-radio-field.component';
import { DotEditContentRelationshipFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-relationship-field/dot-edit-content-relationship-field.component';
import { DotEditContentSelectFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-select-field/dot-edit-content-select-field.component';
import { DotEditContentTagFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-tag-field/dot-edit-content-tag-field.component';
import { DotEditContentTextAreaComponent } from '@dotcms/edit-content/fields/dot-edit-content-text-area/dot-edit-content-text-area.component';
import { DotEditContentTextFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-text-field/dot-edit-content-text-field.component';
import { DotEditContentWYSIWYGFieldComponent } from '@dotcms/edit-content/fields/dot-edit-content-wysiwyg-field/dot-edit-content-wysiwyg-field.component';
import { DotFieldRequiredDirective } from '@dotcms/ui';

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 { DotEditContentFileFieldComponent } from '../../fields/dot-edit-content-file-field/dot-edit-content-file-field.component';
import { DotEditContentHostFolderFieldComponent } from '../../fields/dot-edit-content-host-folder-field/dot-edit-content-host-folder-field.component';
import { DotEditContentJsonFieldComponent } from '../../fields/dot-edit-content-json-field/dot-edit-content-json-field.component';
import { DotEditContentKeyValueComponent } from '../../fields/dot-edit-content-key-value/dot-edit-content-key-value.component';
import { DotEditContentMultiSelectFieldComponent } from '../../fields/dot-edit-content-multi-select-field/dot-edit-content-multi-select-field.component';
import { DotEditContentRadioFieldComponent } from '../../fields/dot-edit-content-radio-field/dot-edit-content-radio-field.component';
import { DotEditContentSelectFieldComponent } from '../../fields/dot-edit-content-select-field/dot-edit-content-select-field.component';
import { DotEditContentTagFieldComponent } from '../../fields/dot-edit-content-tag-field/dot-edit-content-tag-field.component';
import { DotEditContentTextAreaComponent } from '../../fields/dot-edit-content-text-area/dot-edit-content-text-area.component';
import { DotEditContentTextFieldComponent } from '../../fields/dot-edit-content-text-field/dot-edit-content-text-field.component';
import { DotEditContentWYSIWYGFieldComponent } from '../../fields/dot-edit-content-wysiwyg-field/dot-edit-content-wysiwyg-field.component';
import { CALENDAR_FIELD_TYPES } from '../../models/dot-edit-content-field.constant';
import { FIELD_TYPES } from '../../models/dot-edit-content-field.enum';

Expand Down Expand Up @@ -54,10 +55,10 @@ import { FIELD_TYPES } from '../../models/dot-edit-content-field.enum';
DotEditContentCategoryFieldComponent,
DotFieldRequiredDirective,
BlockEditorModule,
DotEditContentBinaryFieldComponent,
DotEditContentKeyValueComponent,
DotEditContentWYSIWYGFieldComponent,
DotEditContentFileFieldComponent
DotEditContentFileFieldComponent,
DotEditContentRelationshipFieldComponent
]
})
export class DotEditContentFieldComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ export const resolutionValue: Record<FIELD_TYPES, FnResolutionValue> = {
}

return field.defaultValue ?? [];
}
},
[FIELD_TYPES.RELATIONSHIP]: defaultResolutionFn
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
@let rowsPerPage = 25;
@let data = store.data();

<p-dialog
[header]="'dot.file.field.dialog.import.from.url.header' | dm"
[modal]="true"

[(visible)]="$visible"
dataKey="id"
appendTo="body">
<p-table
#datatable
[value]="data"
selectionMode="multiple"
[(selection)]="$selectedItems"
[loading]="store.isLoading()"
[paginator]="false"
[rows]="rowsPerPage"
styleClass="p-datatable-sm">
<ng-template pTemplate="caption">
<div class="flex w-full">
<p-iconField iconPosition="left">
<p-inputIcon styleClass="pi pi-search" />
<input
#searchInput
pInputText
type="search"
[placeholder]="
'dot.file.field.dialog.select.existing.file.table.search' | dm
"
(input)="datatable.filterGlobal(searchInput.value, 'contains')" />
</p-iconField>
</div>
</ng-template>
<ng-template pTemplate="header" styleClass="relative">
<tr class="existing-content__table_header">
<th style="width: 4rem"><p-tableHeaderCheckbox /></th>
<th pSortableColumn="title">
Title
<p-sortIcon field="title" />
</th>
<th pSortableColumn="step">
Step
<p-sortIcon field="step" />
</th>
<th pSortableColumn="description">
Description
<p-sortIcon field="description" />
</th>
<th pSortableColumn="lastUpdate">
Last Update
<p-sortIcon field="lastUpdate" />
</th>
<th>Menu</th>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="6">
<div class="flex p-2 gap-2 justify-content-center">
<p class="text-500">Relate content by clicking on the Plus Button</p>
</div>
</td>
</tr>
</ng-template>
<ng-template pTemplate="body" let-item>
<tr>
<td>
<p-tableCheckbox [value]="item" />
</td>
<td class="max-w-12rem">
<p class="truncate-text">{{ item.title }}</p>
</td>
<td>{{ item.step }}</td>
<td class="max-w-12rem">
<p class="truncate-text">{{ item.description }}</p>
</td>
<td>{{ item.lastUpdate }}</td>
<td>
<i class="pi pi-ellipsis-v"></i>
</td>
</tr>
</ng-template>
</p-table>
<ng-template pTemplate="footer">
<p-button label="Cancel" (onClick)="closeDialog()" [text]="true" severity="secondary" />
<p-button label="Save" [outlined]="true" severity="secondary" />
</ng-template>
</p-dialog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@use "variables" as *;

::ng-deep {
p-table {
.p-datatable {
border: 1px solid $color-palette-gray-300;
border-radius: $border-radius-md;
.p-datatable-header {
background-color: $color-palette-gray-100;
}
}
}
}

.existing-content__table_header {
th {
font-weight: $font-weight-bold;
background-color: $color-palette-gray-100;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { ChangeDetectionStrategy, Component, inject, model } from '@angular/core';

import { ButtonModule } from 'primeng/button';
import { DialogModule } from 'primeng/dialog';
import { IconFieldModule } from 'primeng/iconfield';
import { InputIconModule } from 'primeng/inputicon';
import { InputTextModule } from 'primeng/inputtext';
import { MenuModule } from 'primeng/menu';
import { TableModule } from 'primeng/table';

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

import { Content, ExistingContentStore } from './store/existing-content.store';

@Component({
selector: 'dot-select-existing-content',
standalone: true,
imports: [
TableModule,
ButtonModule,
MenuModule,
DotMessagePipe,
DialogModule,
IconFieldModule,
InputIconModule,
InputTextModule
],
templateUrl: './dot-select-existing-content.component.html',
styleUrls: ['./dot-select-existing-content.component.scss'],
providers: [ExistingContentStore],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DotSelectExistingContentComponent {
/**
* A readonly instance of the ExistingContentStore injected into the component.
* This store is used to manage the state and actions related to the existing content.
*/
readonly store = inject(ExistingContentStore);

$visible = model(false, { alias: 'visible' });

$selectedItems = model<Content[]>([]);

closeDialog() {
this.$visible.set(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { faker } from '@faker-js/faker';
import {
patchState,
signalStore,
withComputed,
withHooks,
withMethods,
withState
} from '@ngrx/signals';

import { computed } from '@angular/core';

import { ComponentStatus } from '@dotcms/dotcms-models';

export interface Content {
id: string;
title: string;
step: string;
description: string;
lastUpdate: string;
}

export interface ExistingContentState {
data: Content[];
status: ComponentStatus;
}

const initialState: ExistingContentState = {
data: [],
status: ComponentStatus.INIT
};

export const ExistingContentStore = signalStore(
withState(initialState),
withComputed((state) => ({
isLoading: computed(() => state.status() === ComponentStatus.LOADING)
})),
withMethods((store) => ({
loadContent() {
const mockData = Array.from({ length: 100 }, () => ({
id: faker.string.uuid(),
title: faker.lorem.sentence(),
step: faker.helpers.arrayElement(['Draft', 'Published', 'Archived']),
description: faker.lorem.paragraph(),
lastUpdate: faker.date.recent().toISOString()
}));
patchState(store, {
data: mockData
});
}
})),
withHooks({
onInit: (store) => {
store.loadContent();
}
})
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<p-table [value]="store.data()" styleClass="p-datatable-lg">
<ng-template pTemplate="header" styleClass="relative">
<p-menu #menu [model]="$menuItems()" [popup]="true" appendTo="body" />
<p-button
(onClick)="menu.toggle($event)"
class="add-item-btn"
[size]="'small'"
icon="pi pi-plus"
[text]="true" />
<tr class="relationship-field__table_header">
<th>Title</th>
<th>Language</th>
<th>State</th>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="3">
<div class="flex p-2 gap-2 justify-content-center">
<i class="pi pi-folder-open"></i>
<p class="text-500">Relate content by clicking on the Plus Button</p>
</div>
</td>
</tr>
</ng-template>
<ng-template pTemplate="body" let-item>
<tr>
<td>{{ item.title }}</td>
<td>{{ item.language }}</td>
<td>{{ item.state }}</td>
</tr>
</ng-template>
</p-table>

<dot-select-existing-content [(visible)]="$showExistingContentDialog" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@use "variables" as *;

::ng-deep {
p-table {
.p-datatable {
border: 1px solid $color-palette-gray-300;
border-radius: $border-radius-md;
.p-datatable-header {
background-color: $color-palette-gray-100;
}
}
}
}
.add-item-btn {
position: absolute;
top: 0.4rem;
right: 0.4rem;
}
.relationship-field__table_header {
th {
font-weight: $font-weight-bold;
background-color: $color-palette-gray-100;
}
}
Loading

0 comments on commit 79afd2f

Please sign in to comment.