Browse Source

Merge branch 'master' of github.com:Squidex/squidex

pull/866/head
Sebastian 4 years ago
parent
commit
4dcebd7f1e
  1. 2
      backend/i18n/frontend_en.json
  2. 2
      backend/i18n/source/frontend_en.json
  3. 22
      frontend/.storybook/main.js
  4. 21
      frontend/.storybook/preview.js
  5. 21
      frontend/.storybook/tsconfig.json
  6. 11
      frontend/.storybook/typings.d.ts
  7. 58010
      frontend/package-lock.json
  8. 13
      frontend/package.json
  9. 59
      frontend/src/app/framework/angular/forms/editors/date-time-editor.component.html
  10. 87
      frontend/src/app/framework/angular/forms/editors/date-time-editor.component.scss
  11. 16
      frontend/src/app/framework/angular/forms/editors/date-time-editor.component.ts
  12. 71
      frontend/src/app/framework/angular/forms/editors/date-time-editor.stories.ts
  13. 4
      frontend/tsconfig.app.json

2
backend/i18n/frontend_en.json

@ -497,7 +497,7 @@
"contents.unsavedChangesText": "You have unsaved changes. Do you want to load them now?", "contents.unsavedChangesText": "You have unsaved changes. Do you want to load them now?",
"contents.unsavedChangesTitle": "Unsaved changes", "contents.unsavedChangesTitle": "Unsaved changes",
"contents.unsetValue": "Unset value", "contents.unsetValue": "Unset value",
"contents.unsetValueConfirmText": "If you unset the value you might loose your changes.\n\nDo you really want to do it?", "contents.unsetValueConfirmText": "If you unset the value you might lose your changes.\n\nDo you really want to do it?",
"contents.unsetValueConfirmTitle": "Do you want to unset the value?", "contents.unsetValueConfirmTitle": "Do you want to unset the value?",
"contents.updated": "Content updated successfully.", "contents.updated": "Content updated successfully.",
"contents.updateFailed": "Failed to update content. Please reload.", "contents.updateFailed": "Failed to update content. Please reload.",

2
backend/i18n/source/frontend_en.json

@ -497,7 +497,7 @@
"contents.unsavedChangesText": "You have unsaved changes. Do you want to load them now?", "contents.unsavedChangesText": "You have unsaved changes. Do you want to load them now?",
"contents.unsavedChangesTitle": "Unsaved changes", "contents.unsavedChangesTitle": "Unsaved changes",
"contents.unsetValue": "Unset value", "contents.unsetValue": "Unset value",
"contents.unsetValueConfirmText": "If you unset the value you might loose your changes.\n\nDo you really want to do it?", "contents.unsetValueConfirmText": "If you unset the value you might lose your changes.\n\nDo you really want to do it?",
"contents.unsetValueConfirmTitle": "Do you want to unset the value?", "contents.unsetValueConfirmTitle": "Do you want to unset the value?",
"contents.updated": "Content updated successfully.", "contents.updated": "Content updated successfully.",
"contents.updateFailed": "Failed to update content. Please reload.", "contents.updateFailed": "Failed to update content. Please reload.",

22
frontend/.storybook/main.js

@ -0,0 +1,22 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions"
],
"framework": "@storybook/angular",
"core": {
"builder": "@storybook/builder-webpack5"
}
}

21
frontend/.storybook/preview.js

@ -0,0 +1,21 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
export const parameters = {
actions: {
argTypesRegex: "^on[A-Z].*"
},
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
inlineStories: true
},
}

21
frontend/.storybook/tsconfig.json

@ -0,0 +1,21 @@
{
"extends": "../tsconfig.app.json",
"compilerOptions": {
"types": [
"node"
],
"allowSyntheticDefaultImports": true
},
"exclude": [
"../src/test.ts",
"../src/**/*.spec.ts",
"../projects/**/*.spec.ts"
],
"include": [
"../src/**/*",
"../projects/**/*"
],
"files": [
"./typings.d.ts"
]
}

11
frontend/.storybook/typings.d.ts

@ -0,0 +1,11 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
declare module '*.md' {
const content: string;
export default content;
}

58010
frontend/package-lock.json

File diff suppressed because it is too large

13
frontend/package.json

@ -10,7 +10,9 @@
"start": "ng serve", "start": "ng serve",
"test": "ng test", "test": "ng test",
"test:coverage": "ng test --no-watch --code-coverage --browsers=ChromeHeadlessNoSandbox", "test:coverage": "ng test --no-watch --code-coverage --browsers=ChromeHeadlessNoSandbox",
"watch": "ng build --watch --configuration development" "watch": "ng build --watch --configuration development",
"storybook": "start-storybook -p 6006",
"storybook-build": "build-storybook"
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
@ -78,6 +80,15 @@
"@angular/compiler-cli": "~13.1.0", "@angular/compiler-cli": "~13.1.0",
"@angular/elements": "^13.1.1", "@angular/elements": "^13.1.1",
"@babel/core": "^7.16.7", "@babel/core": "^7.16.7",
"@compodoc/compodoc": "^1.1.19",
"@storybook/addon-actions": "^6.4.20",
"@storybook/addon-essentials": "^6.4.20",
"@storybook/addon-interactions": "^6.4.20",
"@storybook/addon-links": "^6.4.20",
"@storybook/angular": "^6.4.20",
"@storybook/builder-webpack5": "^6.4.20",
"@storybook/manager-webpack5": "^6.4.20",
"@storybook/testing-library": "^0.0.9",
"@types/codemirror": "0.0.108", "@types/codemirror": "0.0.108",
"@types/core-js": "2.5.5", "@types/core-js": "2.5.5",
"@types/jasmine": "3.10.2", "@types/jasmine": "3.10.2",

59
frontend/src/app/framework/angular/forms/editors/date-time-editor.component.html

@ -1,37 +1,34 @@
<div class="d-flex" (sqxResizeCondition)="setCompact($event)" [sqxResizeMinWidth]="500" [sqxResizeMaxWidth]="0"> <div class="d-flex root" (sqxResized)="setSize($event)" [class.mini]="size === 'Mini'" [class.compact]="size === 'Compact'">
<div class="d-flex"> <div class="form-group flex-grow me-1">
<div class="form-group me-1"> <div *ngIf="isDateTimeMode && shouldShowDateTimeModeButton">
<div *ngIf="!isCompact && isDateTimeMode && shouldShowDateTimeModeButton"> <button type="button" class="btn btn-text-secondary btn-sm btn-time-mode" (click)="setLocalMode(false)" *ngIf="snapshot.isLocal">
<button type="button" class="btn btn-text-secondary btn-sm btn-time-mode" (click)="setLocalMode(false)" *ngIf="snapshot.isLocal"> {{ 'common.dateTimeEditor.local' | sqxTranslate }}
{{ 'common.dateTimeEditor.local' | sqxTranslate }}
</button>
<button type="button" class="btn btn-text-secondary btn-sm btn-time-mode" (click)="setLocalMode(true)" *ngIf="!snapshot.isLocal">
{{ 'common.dateTimeEditor.utc' | sqxTranslate }}
</button>
</div>
<div class="input-group">
<input type="text" class="form-control form-date" [formControl]="dateControl" placeholder="{{ 'common.date' | sqxTranslate }}"
[class.form-date-only]="!isDateTimeMode"
[class.form-date-time-only]="!isCompact && isDateTimeMode && shouldShowDateTimeModeButton"
(blur)="callTouched()" maxlength="10" #dateInput>
<input type="text" class="form-control form-time" [formControl]="timeControl" placeholder="{{ 'common.time' | sqxTranslate }}" (blur)="callTouched()" *ngIf="isDateTimeMode">
</div>
<button type="button" class="btn btn-text-secondary btn-sm btn-clear" [class.hidden]="!hasValue"
[disabled]="snapshot.isDisabled" (click)="reset()" *ngIf="!hideClear">
<i class="icon-close"></i>
</button> </button>
</div> <button type="button" class="btn btn-text-secondary btn-sm btn-time-mode" (click)="setLocalMode(true)" *ngIf="!snapshot.isLocal">
<div class="form-group" *ngIf="isDateTimeMode && shouldShowDateButtons"> {{ 'common.dateTimeEditor.utc' | sqxTranslate }}
<button type="button" class="btn btn-text-secondary" [disabled]="snapshot.isDisabled" (click)="writeNow()" title="i18n:common.dateTimeEditor.nowTooltip">
{{ 'common.dateTimeEditor.now' | sqxTranslate }}
</button> </button>
</div> </div>
<div class="form-group" *ngIf="!isDateTimeMode && shouldShowDateButtons"> <div class="input-group flex-grow">
<button type="button" class="btn btn-text-secondary" [disabled]="snapshot.isDisabled" (click)="writeToday()" title="i18n:common.dateTimeEditor.todayTooltip"> <input type="text" class="form-control form-date" [formControl]="dateControl" placeholder="{{ 'common.date' | sqxTranslate }}"
{{ 'common.dateTimeEditor.today' | sqxTranslate }} [class.with-buttons]="isDateTimeMode && shouldShowDateTimeModeButton"
</button> (blur)="callTouched()" maxlength="10" #dateInput>
<input type="text" class="form-control form-time" [formControl]="timeControl" placeholder="{{ 'common.time' | sqxTranslate }}" (blur)="callTouched()" *ngIf="isDateTimeMode">
</div> </div>
<button type="button" class="btn btn-text-secondary btn-sm btn-clear" [class.hidden]="!hasValue"
[disabled]="snapshot.isDisabled" (click)="reset()" *ngIf="!hideClear">
<i class="icon-close"></i>
</button>
</div>
<div class="form-group" *ngIf="isDateTimeMode && shouldShowDateButtons">
<button type="button" class="btn btn-text-secondary btn-quick" [disabled]="snapshot.isDisabled" (click)="writeNow()" title="i18n:common.dateTimeEditor.nowTooltip">
{{ 'common.dateTimeEditor.now' | sqxTranslate }}
</button>
</div>
<div class="form-group" *ngIf="!isDateTimeMode && shouldShowDateButtons">
<button type="button" class="btn btn-text-secondary btn-quick" [disabled]="snapshot.isDisabled" (click)="writeToday()" title="i18n:common.dateTimeEditor.todayTooltip">
{{ 'common.dateTimeEditor.today' | sqxTranslate }}
</button>
</div> </div>
</div> </div>

87
frontend/src/app/framework/angular/forms/editors/date-time-editor.component.scss

@ -1,35 +1,75 @@
@import 'mixins'; @import 'mixins';
@import 'vars'; @import 'vars';
.root {
max-width: 400px;
}
.flex-grow {
flex-grow: 1;
}
.form-group { .form-group {
position: relative; position: relative;
} }
.input-group { .form-time {
.form-control { width: 45%;
&:last-child { }
padding-left: .75rem;
padding-right: 2rem; .form-date {
position: relative; width: 55%;
}
&.with-buttons {
padding-left: 3.3rem;
}
}
.form-control {
&:last-child {
padding-left: .75rem;
padding-right: 2rem;
position: relative;
}
}
.btn {
&-clear {
@include absolute(auto, 4px, 3px, auto);
z-index: 100;
}
&-time-mode {
@include absolute(1px, auto, -1px, auto);
z-index: 100;
}
&:focus {
box-shadow: none;
}
}
.compact {
.btn-time-mode {
display: none;
} }
.form-date { .form-date {
width: 8.5rem; padding-left: .75rem;
} }
}
.form-date-only { .mini {
width: 8.5rem; .btn-time-mode {
display: none;
} }
.form-date-time-only { .btn-quick {
padding-left: 3.3rem; display: none;
padding-right: .75rem;
width: 11rem;
} }
.form-time { .form-date {
width: 7rem; padding-left: .75rem;
} }
} }
@ -44,19 +84,4 @@
} }
} }
} }
}
.btn {
&-clear {
@include absolute(auto, 4px, 3px, auto);
}
&-time-mode {
@include absolute(1px, auto, -1px, auto);
z-index: 1000;
}
&:focus {
box-shadow: none;
}
} }

16
frontend/src/app/framework/angular/forms/editors/date-time-editor.component.ts

@ -59,7 +59,7 @@ export class DateTimeEditorComponent extends StatefulControlComponent<State, str
public hideDateTimeModeButton?: boolean | null; public hideDateTimeModeButton?: boolean | null;
@Input() @Input()
public isCompact?: boolean | null; public size: 'Normal' | 'Compact' | 'Mini' = 'Normal';
@Input() @Input()
public set disabled(value: boolean | undefined | null) { public set disabled(value: boolean | undefined | null) {
@ -69,8 +69,8 @@ export class DateTimeEditorComponent extends StatefulControlComponent<State, str
@ViewChild('dateInput', { static: false }) @ViewChild('dateInput', { static: false })
public dateInput!: ElementRef<HTMLInputElement>; public dateInput!: ElementRef<HTMLInputElement>;
public timeControl = new FormControl(); public readonly timeControl = new FormControl();
public dateControl = new FormControl(); public readonly dateControl = new FormControl();
public get shouldShowDateButtons() { public get shouldShowDateButtons() {
return !this.hideDateButtonsSettings && !this.hideDateButtons; return !this.hideDateButtonsSettings && !this.hideDateButtons;
@ -252,8 +252,14 @@ export class DateTimeEditorComponent extends StatefulControlComponent<State, str
this.updateControls(); this.updateControls();
} }
public setCompact(isCompact: boolean) { public setSize(size: DOMRect) {
this.isCompact = isCompact; if (size.width < 300) {
this.size = 'Mini';
} else if (size.width < 350) {
this.size = 'Compact';
} else {
this.size = 'Normal';
}
} }
} }

71
frontend/src/app/framework/angular/forms/editors/date-time-editor.stories.ts

@ -0,0 +1,71 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { moduleMetadata } from '@storybook/angular';
import { Meta, Story } from '@storybook/angular/types-6-0';
import { LocalizerService, SqxFrameworkModule, UIOptions } from '@app/framework';
import { DateTimeEditorComponent } from './date-time-editor.component';
const translations = {
'common.date': 'Date',
'common.dateTimeEditor.local': 'Local',
'common.dateTimeEditor.now': 'Now',
'common.dateTimeEditor.today': 'Today',
'common.dateTimeEditor.utc': 'UTC',
'common.time': 'Time',
};
export default {
title: 'Framework/DateTimeEditor',
component: DateTimeEditorComponent,
argTypes: {
hideClear: {
control: 'boolean',
},
hideDateButtons: {
control: 'boolean',
},
hideDateTimeModeButton: {
control: 'boolean',
},
mode: {
control: 'radio',
options: [
'Date',
'DateTime',
],
},
},
decorators: [
moduleMetadata({
imports: [
SqxFrameworkModule,
SqxFrameworkModule.forRoot(),
],
providers: [
{ provide: LocalizerService, useFactory: () => new LocalizerService(translations) },
{ provide: UIOptions, useFactory: () => new UIOptions({}) },
],
}),
],
} as Meta;
const Template: Story<DateTimeEditorComponent> = (args: DateTimeEditorComponent) => ({
props: args,
});
export const Date = Template.bind({});
Date.args = {
mode: 'Date',
};
export const DateTime = Template.bind({});
DateTime.args = {
mode: 'DateTime',
};

4
frontend/tsconfig.app.json

@ -1,4 +1,3 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
@ -11,5 +10,8 @@
], ],
"include": [ "include": [
"src/**/*.d.ts" "src/**/*.d.ts"
],
"exclude": [
"**/*.stories.*"
] ]
} }

Loading…
Cancel
Save