Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(edit-content: Implement ux design for enhanced file field #30026

Merged
merged 25 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8269ffc
feat(editor-content): implement the new file field #29871
nicobytes Sep 13, 2024
796a528
feat(editor-content): implement the new file field #29871
nicobytes Sep 13, 2024
cfdc612
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 16, 2024
69f5886
feat(editor-content): init setup for image and file component #29871
nicobytes Sep 16, 2024
2c719b7
feat(editor-content): fix error with file naming #29871
nicobytes Sep 16, 2024
20d63f5
feat(editor-content): apply format #29871
nicobytes Sep 17, 2024
e8f5b48
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 17, 2024
6ec979d
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 17, 2024
89849b4
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 17, 2024
522a042
feat(editor-content): create const for actions #29871
nicobytes Sep 17, 2024
f6f161c
Merge branch '29871-implement-ux-design-for-enhanced-file-field' of g…
nicobytes Sep 17, 2024
12f4f03
feat(editor-content): apply format #29871
nicobytes Sep 17, 2024
8b35300
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 18, 2024
83eed79
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 18, 2024
69b4fea
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 18, 2024
7ac1bad
feat(editor-content): add storybook and unit tests #29871
nicobytes Sep 18, 2024
1fd3ddb
feat(editor-content): apply format #29871
nicobytes Sep 18, 2024
2f37be4
Merge branch '29871-implement-ux-design-for-enhanced-file-field' of g…
nicobytes Sep 18, 2024
0119b89
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 19, 2024
53bd13b
feat(editor-content): fix naming #29871
nicobytes Sep 19, 2024
cf858e8
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 19, 2024
7f394a4
Merge branch 'master' into 29871-implement-ux-design-for-enhanced-fil…
nicobytes Sep 19, 2024
360833a
feat(editor-content): fix error with empty scss file #29871
nicobytes Sep 19, 2024
b1f7481
Merge branch '29871-implement-ux-design-for-enhanced-file-field' of g…
nicobytes Sep 19, 2024
cb69f6d
feat(editor-content): fix error with duplicated code #29871
nicobytes Sep 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@
[contentlet]="contentlet"
[field]="field" />
}
@case (fieldTypes.FILE) {
<dot-edit-content-file-field
[formControlName]="field.variable"
[attr.data-testId]="'field-' + field.variable"
[field]="field" />
}
@case (fieldTypes.IMAGE) {
<dot-edit-content-file-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 @@ -25,6 +25,7 @@ import { DotEditContentCalendarFieldComponent } from '../../fields/dot-edit-cont
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';
Expand Down Expand Up @@ -69,6 +70,8 @@ declare module '@tiptap/core' {
const FIELD_TYPES_COMPONENTS: Record<FIELD_TYPES, Type<unknown> | DotEditFieldTestBed> = {
// We had to use unknown because components have different types.
[FIELD_TYPES.TEXT]: DotEditContentTextFieldComponent,
[FIELD_TYPES.FILE]: DotEditContentFileFieldComponent,
[FIELD_TYPES.IMAGE]: DotEditContentFileFieldComponent,
[FIELD_TYPES.TEXTAREA]: DotEditContentTextAreaComponent,
[FIELD_TYPES.SELECT]: DotEditContentSelectFieldComponent,
[FIELD_TYPES.RADIO]: DotEditContentRadioFieldComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DotFieldRequiredDirective } from '@dotcms/ui';

import { DotEditContentBinaryFieldComponent } from '../../fields/dot-edit-content-binary-field/dot-edit-content-binary-field.component';
import { DotEditContentFieldsModule } from '../../fields/dot-edit-content-fields.module';
import { DotEditContentFileFieldComponent } from '../../fields/dot-edit-content-file-field/dot-edit-content-file-field.component';
import { DotEditContentKeyValueComponent } from '../../fields/dot-edit-content-key-value/dot-edit-content-key-value.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';
Expand All @@ -31,7 +32,8 @@ import { FIELD_TYPES } from '../../models/dot-edit-content-field.enum';
BlockEditorModule,
DotEditContentBinaryFieldComponent,
DotEditContentKeyValueComponent,
DotEditContentWYSIWYGFieldComponent
DotEditContentWYSIWYGFieldComponent,
DotEditContentFileFieldComponent
]
})
export class DotEditContentFieldComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const defaultResolutionFn: FnResolutionValue = (contentlet, field) =>
*/
export const resolutionValue: Record<FIELD_TYPES, FnResolutionValue> = {
[FIELD_TYPES.BINARY]: defaultResolutionFn,
[FIELD_TYPES.FILE]: defaultResolutionFn,
[FIELD_TYPES.IMAGE]: defaultResolutionFn,
[FIELD_TYPES.BLOCK_EDITOR]: defaultResolutionFn,
[FIELD_TYPES.CHECKBOX]: defaultResolutionFn,
[FIELD_TYPES.CONSTANT]: defaultResolutionFn,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>Preview</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component } from '@angular/core';

@Component({
selector: 'dot-file-field-preview',
standalone: true,
imports: [],
providers: [],
templateUrl: './dot-file-field-preview.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class DotFileFieldPreviewComponent {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div
[ngClass]="$uiMessage().severity"
class="icon-container"
data-testId="ui-message-icon-container">
<i [ngClass]="$uiMessage().icon" data-testId="ui-message-icon" class="icon"></i>
</div>
<div class="text">
<span [innerHTML]="$uiMessage().message" data-testId="ui-message-span"></span>
<ng-content></ng-content>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@use "variables" as *;

:host {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: $spacing-3;
height: 100%;
padding: $spacing-3;
}

.icon-container {
border-radius: 50%;
padding: $spacing-3;

.icon {
font-size: $font-size-xxl;
width: auto;
}

&.info {
color: $color-palette-primary-500;
background: $color-palette-primary-200;
}

&.error {
color: $color-alert-yellow;
background: $color-alert-yellow-light;
}
}

.text {
text-align: center;
line-height: 140%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NgClass } from '@angular/common';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';

import { UIMessage } from '../../models';

@Component({
selector: 'dot-file-field-ui-message',
standalone: true,
imports: [NgClass],
templateUrl: './dot-file-field-ui-message.component.html',
styleUrls: ['./dot-file-field-ui-message.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DotFileFieldUiMessageComponent {
$uiMessage = input.required<UIMessage>({ alias: 'uiMessage' });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<div
class="file-field__container"
[class.file-field__container--empty]="store.isEmpty()"
[class.file-field__container--uploading]="store.isUploading()">
@switch (store.fileStatus()) {
@case ('init') {
<div
[class.file-field__drop-zone--active]="store.dropZoneActive()"
class="file-field__drop-zone">
<dot-drop-zone data-testId="dropzone">
@if (store.uiMessage()) {
<dot-file-field-ui-message [uiMessage]="store.uiMessage()">
<button
class="file-field__drop-zone-btn"
data-testId="choose-file-btn"
type="button">
{{ 'dot.file.field.action.choose.file' | dm }}
</button>
</dot-file-field-ui-message>
}
</dot-drop-zone>
<input #inputFile data-testId="file-field__file-input" type="file" />
</div>

<div class="file-field__actions">
@if (store.allowURLImport()) {
<p-button
[label]="'dot.file.field.action.import.from.url' | dm"
data-testId="action-import-from-url"
icon="pi pi-link"
styleClass="p-button-link p-button-sm" />
}
@if (store.allowExistingFile()) {
<p-button
[label]="'dot.file.field.action.select.existing.file' | dm"
data-testId="action-existing-file"
icon="pi pi-file"
styleClass="p-button-link p-button-sm" />
}
@if (store.allowCreateFile()) {
<p-button
[label]="'dot.file.field.action.create.new.file' | dm"
data-testId="action-new-file"
icon="pi pi-code"
styleClass="p-button-link p-button-sm" />
}
@if (store.allowGenerateImg()) {
<p-button
[disabled]="!store.isAIPluginInstalled()"
tooltipPosition="bottom"
data-testId="action-generate-with-ai"
styleClass="p-button-link p-button-sm pointer-events-auto">
<svg
fill="none"
height="22"
viewBox="0 0 18 22"
width="18"
xmlns="http://www.w3.org/2000/svg">
<path
d="M9.48043 13.2597L5.40457 14.5046C5.29885 14.5368 5.20602 14.6037 5.13999 14.6952C5.07396 14.7868 5.03828 14.8981 5.03828 15.0124C5.03828 15.1268 5.07396 15.238 5.13999 15.3296C5.20602 15.4211 5.29885 15.488 5.40457 15.5203L9.48043 16.7651L10.6799 20.9949C10.711 21.1046 10.7755 21.2009 10.8637 21.2695C10.9519 21.338 11.0591 21.375 11.1693 21.375C11.2795 21.375 11.3867 21.338 11.4749 21.2695C11.5631 21.2009 11.6276 21.1046 11.6586 20.9949L12.8586 16.7651L16.9345 15.5203C17.0402 15.488 17.133 15.4211 17.1991 15.3296C17.2651 15.238 17.3008 15.1268 17.3008 15.0124C17.3008 14.8981 17.2651 14.7868 17.1991 14.6952C17.133 14.6037 17.0402 14.5368 16.9345 14.5046L12.8586 13.2597L11.6586 9.02989C11.6276 8.92018 11.5631 8.82385 11.4749 8.75533C11.3867 8.6868 11.2795 8.64977 11.1693 8.64977C11.0591 8.64977 10.9519 8.6868 10.8637 8.75533C10.7754 8.82385 10.711 8.92018 10.6799 9.02989L9.48043 13.2597Z"
fill="#426BF0" />
<path
d="M14.4668 5.66732L16.6779 4.99138C16.7836 4.95914 16.8764 4.89224 16.9424 4.8007C17.0084 4.70916 17.0441 4.59789 17.0441 4.48355C17.0441 4.3692 17.0084 4.25794 16.9424 4.16639C16.8764 4.07485 16.7836 4.00795 16.6779 3.97571L14.4668 3.3003L13.8154 1.00513C13.7844 0.895414 13.7199 0.799084 13.6317 0.730559C13.5435 0.662034 13.4362 0.625 13.3261 0.625C13.2159 0.625 13.1086 0.662034 13.0204 0.730559C12.9322 0.799084 12.8677 0.895414 12.8367 1.00513L12.1859 3.3003L9.9743 3.97571C9.86858 4.00794 9.77575 4.07483 9.70972 4.16638C9.6437 4.25792 9.60801 4.3692 9.60801 4.48355C9.60801 4.5979 9.6437 4.70917 9.70972 4.80072C9.77575 4.89226 9.86858 4.95915 9.9743 4.99138L12.1859 5.66732L12.8367 7.96196C12.8677 8.07168 12.9322 8.16801 13.0204 8.23653C13.1086 8.30506 13.2159 8.34209 13.3261 8.34209C13.4362 8.34209 13.5435 8.30506 13.6317 8.23653C13.7199 8.16801 13.7844 8.07168 13.8154 7.96196L14.4668 5.66732Z"
fill="#426BF0" />
<path
d="M3.24925 6.62823L1.01825 7.57256C0.924385 7.61231 0.844063 7.68016 0.787521 7.76748C0.730978 7.8548 0.700781 7.95761 0.700781 8.06282C0.700781 8.16802 0.730978 8.27083 0.787521 8.35815C0.844063 8.44547 0.924385 8.51333 1.01825 8.55307L3.24925 9.4974L4.1592 11.8127C4.19751 11.9101 4.2629 11.9935 4.34704 12.0522C4.43118 12.1109 4.53026 12.1422 4.63163 12.1422C4.733 12.1422 4.83208 12.1109 4.91622 12.0522C5.00036 11.9935 5.06576 11.9101 5.10406 11.8127L6.01402 9.4974L8.24456 8.55307C8.33841 8.51332 8.41873 8.44546 8.47527 8.35815C8.53181 8.27083 8.56201 8.16801 8.56201 8.06282C8.56201 7.95762 8.53181 7.8548 8.47527 7.76749C8.41873 7.68017 8.33841 7.61231 8.24456 7.57256L6.01402 6.62823L5.10406 4.31342C5.06576 4.21602 5.00036 4.13266 4.91622 4.07399C4.83208 4.01531 4.733 3.98397 4.63163 3.98397C4.53026 3.98397 4.43118 4.01531 4.34704 4.07399C4.2629 4.13266 4.19751 4.21602 4.1592 4.31342L3.24925 6.62823Z"
fill="#426BF0" />
</svg>
<span class="label-ai">
{{ 'dot.file.field.action.generate.with.dotai' | dm }}
</span>
</p-button>
}
</div>
}
@case ('uploading') {
<dot-spinner data-testId="loading" />
}
@case ('preview') {
<dot-file-field-preview />
}
}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
@use "variables" as *;

:host {
display: block;
container-type: inline-size;
container-name: binaryField;
}

.file-field__container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
border-radius: $border-radius-md;
border: $field-border-size solid $color-palette-gray-400;
padding: $spacing-1;
height: 14.4rem;
min-width: 12.5rem;

&:has(.file-field__actions:empty) {
gap: 0;
}
}

.file-field__container--uploading {
border: $field-border-size dashed $color-palette-gray-400;
}

.file-field__actions {
display: flex;
flex-direction: column;
gap: $spacing-3;
justify-content: center;
align-items: flex-start;

&:empty {
display: none;
}

.label-ai {
text-transform: none;
font-size: $font-size-sm;
}

.p-button {
display: inline-flex;
user-select: none;
align-items: center;
vertical-align: bottom;
text-align: center;
}
}

.file-field__drop-zone {
border: $field-border-size dashed $input-border-color;
border-radius: $border-radius-md;
height: 100%;
flex: 1;
overflow: auto;
margin-right: $spacing-1;
}

.file-field__drop-zone-btn {
border: none;
background: none;
color: $color-palette-primary-500;
text-decoration: underline;
font-size: $font-size-md;
font-family: $font-default;
padding: revert;
cursor: pointer;
}

.file-field__drop-zone--active {
border-radius: $border-radius-md;
border-color: $color-palette-secondary-500;
background: $white;
box-shadow: $shadow-l;
}

input[type="file"] {
display: none;
}

@container fileField (max-width: 306px) {
.file-field__container--empty {
height: auto;
flex-direction: column;
justify-content: center;
align-items: flex-start;
}

.file-field__drop-zone {
width: 100%;
margin: 0;
margin-bottom: $spacing-1;
}
}
Loading