-
-
+
+
+
+
+
+
+
+ {{suggestionsEmptyText | sqxTranslate}}
+
+
+
\ No newline at end of file
diff --git a/frontend/src/app/framework/angular/forms/editors/tag-editor.component.scss b/frontend/src/app/framework/angular/forms/editors/tag-editor.component.scss
index fd812c330..d2f36d84f 100644
--- a/frontend/src/app/framework/angular/forms/editors/tag-editor.component.scss
+++ b/frontend/src/app/framework/angular/forms/editors/tag-editor.component.scss
@@ -185,5 +185,11 @@ div {
.suggestions-dropdown {
@include force-width(450px);
+ max-height: none;
+ min-height: 4rem;
padding: 1rem;
+}
+
+sqx-loader {
+ margin-top: .25rem;
}
\ No newline at end of file
diff --git a/frontend/src/app/framework/angular/forms/editors/tag-editor.component.ts b/frontend/src/app/framework/angular/forms/editors/tag-editor.component.ts
index 195b413f2..da96c29cb 100644
--- a/frontend/src/app/framework/angular/forms/editors/tag-editor.component.ts
+++ b/frontend/src/app/framework/angular/forms/editors/tag-editor.component.ts
@@ -68,14 +68,11 @@ export class TagEditorComponent extends StatefulControlComponent
+
+
+
+ `,
+})
+class TestComponent {
+ public suggestions: string[] = [];
+ public suggestionsLoading = false;
+
+ public load() {
+ this.suggestions = [];
+ this.suggestionsLoading = true;
+
+ setTimeout(() => {
+ this.suggestions = ['A', 'B'];
+ this.suggestionsLoading = false;
+ }, 1000);
+ }
+}
+
+export default {
+ title: 'Framework/TagEditor',
+ component: TagEditorComponent,
+ argTypes: {
+ dashed: {
+ control: 'boolean',
+ },
+ disabled: {
+ control: 'boolean',
+ },
+ },
+ decorators: [
+ moduleMetadata({
+ declarations: [
+ TestComponent,
+ ],
+ imports: [
+ SqxFrameworkModule,
+ SqxFrameworkModule.forRoot(),
+ ],
+ providers: [
+ { provide: LocalizerService, useFactory: () => new LocalizerService(TRANSLATIONS) },
+ ],
+ }),
+ ],
+} as Meta;
+
+const Template: Story = (args: TagEditorComponent) => ({
+ props: args,
+ template: `
+
+
+
+
+ `,
+});
+
+const Template2: Story = (args: TagEditorComponent) => ({
+ props: args,
+ template: `
+
+ `,
+});
+
+export const Default = Template.bind({});
+
+export const Suggestions = Template.bind({});
+
+Suggestions.args = {
+ suggestions: ['A', 'B', 'C'],
+ allowOpen: true,
+};
+
+export const SuggestionsEmpty = Template.bind({});
+
+SuggestionsEmpty.args = {
+ suggestions: [],
+ allowOpen: true,
+};
+
+export const SuggestionsLoading = Template.bind({});
+
+SuggestionsLoading.args = {
+ suggestionsLoading: true,
+ allowOpen: true,
+};
+
+export const Values = Template.bind({});
+
+Values.args = {
+ suggestions: [],
+ ngModel: ['A', 'A', 'B'],
+};
+
+export const StyleDashed = Template.bind({});
+
+StyleDashed.args = {
+ styleDashed: true,
+ ngModel: [],
+};
+
+export const StyleDashedValues = Template.bind({});
+
+StyleDashedValues.args = {
+ styleDashed: true,
+ ngModel: ['A', 'B', 'C'],
+};
+
+export const StyleBlank = Template.bind({});
+
+StyleBlank.args = {
+ styleBlank: true,
+ ngModel: [],
+};
+
+export const StyleBlankValues = Template.bind({});
+
+StyleBlankValues.args = {
+ styleBlank: true,
+ ngModel: ['A', 'B', 'C'],
+};
+
+export const Multiline = Template.bind({});
+
+Multiline.args = {
+ singleLine: false,
+ ngModel: ['Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua'],
+};
+
+export const SingleLine = Template.bind({});
+
+SingleLine.args = {
+ singleLine: true,
+ ngModel: ['Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua'],
+};
+
+export const Lazy = Template2.bind({});
\ No newline at end of file
diff --git a/frontend/src/app/framework/angular/layout.component.ts b/frontend/src/app/framework/angular/layout.component.ts
index 015894e79..dadbeb411 100644
--- a/frontend/src/app/framework/angular/layout.component.ts
+++ b/frontend/src/app/framework/angular/layout.component.ts
@@ -9,7 +9,7 @@
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
import { ActivatedRoute, NavigationEnd, QueryParamsHandling, Router } from '@angular/router';
-import { filter, map, startWith } from 'rxjs';
+import { concat, defer, filter, map, of } from 'rxjs';
import { LayoutContainerDirective } from './layout-container.directive';
@Component({
@@ -87,13 +87,14 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
}
public firstChild =
- this.router.events.pipe(
- filter(event => event instanceof NavigationEnd),
- map(() => {
- return !!this.route.firstChild;
- }),
- startWith(!!this.route.firstChild),
- );
+ concat(
+ defer(() => of(!!this.route.firstChild)),
+ this.router.events.pipe(
+ filter(event => event instanceof NavigationEnd),
+ map(() => {
+ return !!this.route.firstChild;
+ }),
+ ));
constructor(
private readonly container: LayoutContainerDirective,
diff --git a/frontend/src/app/framework/angular/list-view.component.html b/frontend/src/app/framework/angular/list-view.component.html
index 36de1a668..2f29f4efa 100644
--- a/frontend/src/app/framework/angular/list-view.component.html
+++ b/frontend/src/app/framework/angular/list-view.component.html
@@ -37,7 +37,7 @@