diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 45029b267..8832f9ca4 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -1,5 +1,5 @@ name: Dev -concurrency: dev +concurrency: build on: push: @@ -16,94 +16,59 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v3.1.0 - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v4.3.2 - - name: Calculate Version - env: - BUILD_NUMBER: ${{ github.run_number }} - run: | - echo "BUILD_NUMBER=$(($BUILD_NUMBER + 6000))" >> $GITHUB_ENV - - name: Set up QEMU uses: docker/setup-qemu-action@v2.1.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.2.1 - - name: Cache Docker layers - uses: actions/cache@v3.0.11 + - name: Login to Docker Hub + uses: docker/login-action@v2.1.0 with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - name: BUILD uses: docker/build-push-action@v3.2.0 with: - push: false - load: true - build-args: "SQUIDEX__VERSION=5.0.0-dev-${{ env.BUILD_NUMBER }}" - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new - tags: squidex-tmp - - - name: Export Image - run: docker save squidex-tmp | gzip > squidex-tmp.tar.gz - - - name: Save Image to Cache - uses: actions/cache@v3.0.11 - with: - path: squidex-tmp.tar.gz - key: squidex-dev-image-${{ github.sha }} - - - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache + push: true + build-args: "SQUIDEX__RUNTIME__VERSION=7.0.0-dev-${{ env.BUILD_NUMBER }}" + cache-from: type=gha + cache-to: type=gha,mode=max + tags: squidex/squidex-build test: needs: build runs-on: ubuntu-latest steps: - - name: Calculate Version - env: - BUILD_NUMBER: ${{ github.run_number }} - run: | - echo "BUILD_NUMBER=$(($BUILD_NUMBER + 6000))" >> $GITHUB_ENV - - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v3.1.0 - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v4.3.2 - - - name: Get Image From Cache - uses: actions/cache@v3.0.11 - with: - path: squidex-tmp.tar.gz - key: squidex-dev-image-${{ github.sha }} - - - name: Load Image - run: docker load < squidex-tmp.tar.gz + + - name: Pull from Cache + run: docker pull squidex/squidex-build - name: Replace Image Name1 uses: mikefarah/yq@v4.28.2 with: - cmd: yq e '.services.squidex1.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + cmd: yq e '.services.squidex1.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml - name: Replace Image Name2 uses: mikefarah/yq@v4.28.2 with: - cmd: yq e '.services.squidex2.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + cmd: yq e '.services.squidex2.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml - name: Replace Image Name3 uses: mikefarah/yq@v4.28.2 with: - cmd: yq e '.services.squidex3.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + cmd: yq e '.services.squidex3.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml - name: Start Test run: docker-compose up -d @@ -166,42 +131,39 @@ jobs: publish: needs: test runs-on: ubuntu-latest + if: github.event_name != 'pull_request' steps: + - name: Checkout + uses: actions/checkout@v3.1.0 + + - name: Inject slug/short variables + uses: rlespinasse/github-slug-action@v4.3.2 + - name: Calculate Version env: BUILD_NUMBER: ${{ github.run_number }} run: | echo "BUILD_NUMBER=$(($BUILD_NUMBER + 6000))" >> $GITHUB_ENV - - name: Inject slug/short variables - uses: rlespinasse/github-slug-action@v4.3.2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2.1.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2.2.1 - name: Login to Docker Hub uses: docker/login-action@v2.1.0 - if: github.event_name != 'pull_request' with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Get Image From Cache - if: github.event_name != 'pull_request' - uses: actions/cache@v3.0.11 + - name: BUILD + uses: docker/build-push-action@v3.2.0 with: - path: squidex-tmp.tar.gz - key: squidex-dev-image-${{ github.sha }} - - - name: Load Image - if: github.event_name != 'pull_request' - run: docker load < squidex-tmp.tar.gz - - - name: Rename Tags - if: github.event_name != 'pull_request' - run: | - docker tag squidex-tmp squidex/squidex:dev - docker tag squidex-tmp squidex/squidex:dev-${{ env.BUILD_NUMBER }} - - - name: Push Tags - if: github.event_name != 'pull_request' - run: | - docker push squidex/squidex:dev - docker push squidex/squidex:dev-${{ env.BUILD_NUMBER }} + push: true + build-args: "SQUIDEX__RUNTIME__VERSION=7.0.0-dev-${{ env.BUILD_NUMBER }}" + cache-from: type=gha + cache-to: type=gha,mode=max + tags: | + squidex/squidex:dev + squidex/squidex:dev-${{ env.BUILD_NUMBER }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5bee6fcc6..cb9ff8a6d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,5 @@ name: Release -concurrency: release +concurrency: build on: push: @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v3.1.0 - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v4.3.2 @@ -22,71 +22,48 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.2.1 - - name: Cache Docker layers - uses: actions/cache@v3.0.11 + - name: Login to Docker Hub + uses: docker/login-action@v2.1.0 with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - name: BUILD uses: docker/build-push-action@v3.2.0 with: - push: false - load: true - tags: squidex-tmp - build-args: "SQUIDEX__VERSION=${{ env.GITHUB_REF_SLUG }}" - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new - - - name: Export Image - run: docker save squidex-tmp | gzip > squidex-tmp.tar.gz - - - name: Save Image to Cache - uses: actions/cache@v3.0.11 - with: - path: squidex-tmp.tar.gz - key: squidex-release-image-${{ github.sha }} - - - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache + push: true + build-args: "SQUIDEX__BUILD__VERSION=${{ env.GITHUB_REF_SLUG }},SQUIDEX__RUNTIME__VERSION=${{ env.GITHUB_REF_SLUG }}" + cache-from: type=gha + cache-to: type=gha,mode=max + tags: squidex/squidex-build test: needs: build runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v3.1.0 - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v4.3.2 - - - name: Get Image From Cache - uses: actions/cache@v3.0.11 - with: - path: squidex-tmp.tar.gz - key: squidex-release-image-${{ github.sha }} - - - name: Load Image - run: docker load < squidex-tmp.tar.gz + + - name: Pull from Cache + run: docker pull squidex/squidex-build - name: Replace Image Name1 uses: mikefarah/yq@v4.28.2 with: - cmd: yq e '.services.squidex1.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + cmd: yq e '.services.squidex1.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml - name: Replace Image Name2 uses: mikefarah/yq@v4.28.2 with: - cmd: yq e '.services.squidex2.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + cmd: yq e '.services.squidex2.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml - name: Replace Image Name3 uses: mikefarah/yq@v4.28.2 with: - cmd: yq e '.services.squidex3.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + cmd: yq e '.services.squidex3.image = "squidex/squidex-build"' -i backend/tests/docker-compose.yml - name: Start Test run: docker-compose up -d @@ -150,18 +127,15 @@ jobs: needs: test runs-on: ubuntu-latest steps: + - name: Checkout + uses: actions/checkout@v3.1.0 + - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v4.3.2 - - name: Login to Docker Hub - uses: docker/login-action@v2.1.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Get Major Version id: version - uses: rishabhgupta/split-by@v1.0.1 + uses: rishabhgupta/split-by@v1 with: string: "${{ env.GITHUB_REF_SLUG }}" split-by: "." @@ -170,59 +144,64 @@ jobs: id: normal-version run: | if [[ ${{ env.GITHUB_REF_SLUG }} =~ ^[0-9]+\.[0-9]+$ ]]; then - echo ::set-output name=match::true + echo "STABLE_VERSION=true" >> $GITHUB_ENV fi - - name: Get Image From Cache - uses: actions/cache@v3.0.11 - with: - path: squidex-tmp.tar.gz - key: squidex-release-image-${{ github.sha }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2.1.0 - - name: Load Image - run: docker load < squidex-tmp.tar.gz + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2.2.1 - - name: Rename Tags - run: | - docker tag squidex-tmp squidex/squidex:latest - docker tag squidex-tmp squidex/squidex:${{ env.GITHUB_REF_SLUG }} - docker tag squidex-tmp squidex/squidex:${{ steps.version.outputs._0 }} + - name: Login to Docker Hub + uses: docker/login-action@v2.1.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - - name: Push Version - run: | - docker push squidex/squidex:latest - docker push squidex/squidex:${{ env.GITHUB_REF_SLUG }} - docker push squidex/squidex:${{ steps.version.outputs._0 }} + - name: BUILD + uses: docker/build-push-action@v3.2.0 + with: + push: true + build-args: "SQUIDEX__BUILD__VERSION=${{ env.GITHUB_REF_SLUG }},SQUIDEX__RUNTIME__VERSION=${{ env.GITHUB_REF_SLUG }}" + cache-from: type=gha + cache-to: type=gha,mode=max + tags: | + squidex/squidex:latest + squidex/squidex:${{ env.GITHUB_REF_SLUG }} + squidex/squidex:${{ steps.version.outputs._0 }} + if: env.STABLE_VERSION == 'true' - - name: Push Latest - run: | - docker push squidex/squidex:latest - if: steps.normal-version.outputs.match == 'true' + - name: BUILD + uses: docker/build-push-action@v3.2.0 + with: + push: true + build-args: "SQUIDEX__BUILD__VERSION=${{ env.GITHUB_REF_SLUG }},SQUIDEX__RUNTIME__VERSION=${{ env.GITHUB_REF_SLUG }}" + cache-from: type=gha + cache-to: type=gha,mode=max + tags: | + squidex/squidex:${{ env.GITHUB_REF_SLUG }} + squidex/squidex:${{ steps.version.outputs._0 }} + if: env.STABLE_VERSION != 'true' release: needs: publish runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v3.1.0 - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v4.3.2 - - - name: Get Image From Cache - uses: actions/cache@v3.0.11 - with: - path: squidex-tmp.tar.gz - key: squidex-release-image-${{ github.sha }} - - - name: Load Image - run: docker load < squidex-tmp.tar.gz + + - name: Pull from Cache + run: docker pull squidex/squidex-build - name: Make directories run: sudo mkdir /build /release - name: Create container - run: docker create --name squidex-container squidex-tmp:latest + run: docker create --name squidex-container squidex/squidex-build - name: Get binaries run: sudo docker cp squidex-container:/app/. /build diff --git a/Dockerfile b/Dockerfile index 7a3d1af0b..23d234f7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # FROM mcr.microsoft.com/dotnet/sdk:7.0 as backend -ARG SQUIDEX__VERSION=7.0.0 +ARG SQUIDEX__BUILD__VERSION=7.0.0 WORKDIR /src @@ -30,7 +30,7 @@ COPY backend . RUN dotnet test --no-restore --filter Category!=Dependencies # Publish -RUN dotnet publish --no-restore src/Squidex/Squidex.csproj --output /build/ --configuration Release -p:version=$SQUIDEX__VERSION +RUN dotnet publish --no-restore src/Squidex/Squidex.csproj --output /build/ --configuration Release -p:version=$SQUIDEX__BUILD__VERSION # Install tools RUN dotnet tool install --tool-path /tools dotnet-counters \ @@ -70,6 +70,8 @@ RUN cp -a build /build/ # FROM mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim +ARG SQUIDEX__RUNTIME__VERSION=7.0.0 + # Curl for debugging and libc-dev for protobuf RUN apt-get update \ && apt-get install -y curl libc-dev @@ -89,7 +91,6 @@ COPY --from=frontend /build/ wwwroot/build/ EXPOSE 80 EXPOSE 443 -EXPOSE 11111 ENV DIAGNOSTICS__COUNTERSTOOL=/tools/dotnet-counters ENV DIAGNOSTICS__DUMPTOOL=/tools/dotnet-dump @@ -97,3 +98,5 @@ ENV DIAGNOSTICS__GCDUMPTOOL=/tools/dotnet-gcdump ENV DIAGNOSTICS__TRACETOOL=/tools/dotnet-trace ENTRYPOINT ["dotnet", "Squidex.dll"] + +ENV EXPOSEDCONFIGURATION__VERSION=$SQUIDEX__RUNTIME__VERSION \ No newline at end of file diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs index 02ebebffc..caef13a8d 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs @@ -82,38 +82,40 @@ public class ContentQueryParser query.Filter = await GeoQueryTransformer.TransformAsync(query.Filter, context, schema, textIndex, ct); } - if (!string.IsNullOrWhiteSpace(query.FullText)) + if (string.IsNullOrWhiteSpace(query.FullText)) { - if (schema == null) - { - ThrowHelper.InvalidOperationException(); - return; - } + return; + } - var textQuery = new TextQuery(query.FullText, 1000) - { - PreferredSchemaId = schema.Id - }; + if (schema == null) + { + ThrowHelper.InvalidOperationException(); + return; + } - var fullTextIds = await textIndex.SearchAsync(context.App, textQuery, context.Scope(), ct); - var fullTextFilter = ClrFilter.Eq("id", "__notfound__"); + var textQuery = new TextQuery(query.FullText, 1000) + { + PreferredSchemaId = schema.Id + }; - if (fullTextIds?.Any() == true) - { - fullTextFilter = ClrFilter.In("id", fullTextIds.Select(x => x.ToString()).ToList()); - } + var fullTextIds = await textIndex.SearchAsync(context.App, textQuery, context.Scope(), ct); + var fullTextFilter = ClrFilter.Eq("id", "__notfound__"); - if (query.Filter != null) - { - query.Filter = ClrFilter.And(query.Filter, fullTextFilter); - } - else - { - query.Filter = fullTextFilter; - } + if (fullTextIds?.Any() == true) + { + fullTextFilter = ClrFilter.In("id", fullTextIds.Select(x => x.ToString()).ToList()); + } - query.FullText = null; + if (query.Filter != null) + { + query.Filter = ClrFilter.And(query.Filter, fullTextFilter); } + else + { + query.Filter = fullTextFilter; + } + + query.FullText = null; } private async Task ParseClrQueryAsync(Context context, Q q, ISchemaEntity? schema, diff --git a/frontend/src/app/features/administration/pages/users/user-page.component.html b/frontend/src/app/features/administration/pages/users/user-page.component.html index 770417c9c..a80fa5a58 100644 --- a/frontend/src/app/features/administration/pages/users/user-page.component.html +++ b/frontend/src/app/features/administration/pages/users/user-page.component.html @@ -2,7 +2,7 @@
- + diff --git a/frontend/src/app/features/content/pages/comments/comments-page.component.html b/frontend/src/app/features/content/pages/comments/comments-page.component.html index 1686fcc64..a412160a5 100644 --- a/frontend/src/app/features/content/pages/comments/comments-page.component.html +++ b/frontend/src/app/features/content/pages/comments/comments-page.component.html @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/frontend/src/app/features/content/pages/content/content-history-page.component.html b/frontend/src/app/features/content/pages/content/content-history-page.component.html index 25556315e..14c986205 100644 --- a/frontend/src/app/features/content/pages/content/content-history-page.component.html +++ b/frontend/src/app/features/content/pages/content/content-history-page.component.html @@ -1,4 +1,4 @@ - +
diff --git a/frontend/src/app/features/content/shared/list/content.component.scss b/frontend/src/app/features/content/shared/list/content.component.scss index a9615d8a6..95ef1f57f 100644 --- a/frontend/src/app/features/content/shared/list/content.component.scss +++ b/frontend/src/app/features/content/shared/list/content.component.scss @@ -19,7 +19,7 @@ tr { } td { - border-bottom: 1px solid $color-border; + border-bottom: .7px solid $color-border; border-left: 1px solid $color-white; border-top: 0 !important; position: relative; diff --git a/frontend/src/app/features/rules/pages/rules/rule.component.html b/frontend/src/app/features/rules/pages/rules/rule.component.html index 2771ba252..991650598 100644 --- a/frontend/src/app/features/rules/pages/rules/rule.component.html +++ b/frontend/src/app/features/rules/pages/rules/rule.component.html @@ -2,12 +2,13 @@
- +
diff --git a/frontend/src/app/features/settings/pages/clients/client.component.html b/frontend/src/app/features/settings/pages/clients/client.component.html index f9b98d175..a5afdae21 100644 --- a/frontend/src/app/features/settings/pages/clients/client.component.html +++ b/frontend/src/app/features/settings/pages/clients/client.component.html @@ -1,8 +1,12 @@
-
+
- +
@@ -10,7 +14,7 @@ {{ 'clients.connect' | sqxTranslate }}
-
+
- - + +
+
+
+ + +
- +
+ +
+
+ +
+
+ - -
-

- {{name || fallback}} + +
+
+

+ {{inputTitle || displayFallback}}

- -
- -
\ No newline at end of file +
+ +
+
+ +
+

+
\ No newline at end of file diff --git a/frontend/src/app/framework/angular/forms/editable-title.component.scss b/frontend/src/app/framework/angular/forms/editable-title.component.scss index 5579d5550..eb5b6f36c 100644 --- a/frontend/src/app/framework/angular/forms/editable-title.component.scss +++ b/frontend/src/app/framework/angular/forms/editable-title.component.scss @@ -1,34 +1,36 @@ @import 'mixins'; @import 'vars'; -.title { - @include hover-visible('.title-edit', inline); - position: relative; - - &-edit { - @include absolute(0, 0, null, null); - color: darken($color-border-dark, 20%); - cursor: pointer; - padding: .6rem .25rem; - } +:host { + display: block; +} - &-name { - display: inline; - font-size: 1.2rem; - font-weight: normal; - padding-right: 1.75rem; - } +.title-view { + @include hover-visible('.title-edit', block); - &-view { - @include truncate; - border-bottom: 1px solid transparent; - border-top: 0; - padding: .375rem 0; - position: absolute; + .col { + overflow: hidden; } } +.btn-placeholder { + padding-left: 0; + padding-right: 0; + width: 0; +} + +.row { + flex-wrap: nowrap; +} + h3 { + margin: 0; + + &.sm { + font-size: 1rem; + font-weight: normal; + } + &.fallback { color: $color-text-decent; } diff --git a/frontend/src/app/framework/angular/forms/editable-title.component.ts b/frontend/src/app/framework/angular/forms/editable-title.component.ts index 9c2a0a114..2d69fb0ab 100644 --- a/frontend/src/app/framework/angular/forms/editable-title.component.ts +++ b/frontend/src/app/framework/angular/forms/editable-title.component.ts @@ -6,42 +6,41 @@ */ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { UntypedFormControl, Validators } from '@angular/forms'; +import { FormControl, ValidatorFn, Validators } from '@angular/forms'; import { Keys } from '@app/framework/internal'; @Component({ - selector: 'sqx-editable-title[name]', + selector: 'sqx-editable-title[inputTitle]', styleUrls: ['./editable-title.component.scss'], templateUrl: './editable-title.component.html', }) export class EditableTitleComponent { @Output() - public nameChange = new EventEmitter(); + public inputTitleChange = new EventEmitter(); @Input() - public disabled?: boolean | null; + public inputTitle!: string; @Input() - public fallback = ''; + public inputTitleLength = 20; @Input() - public name!: string; + public inputTitleRequired = true; @Input() - public maxLength = 20; + public disabled?: boolean | null; @Input() - public set isRequired(value: boolean) { - const validator = - value ? - Validators.required : - Validators.nullValidator; + public closeButton = true; - this.renameForm.setValidators(validator); - } + @Input() + public size: 'sm' | 'md' | 'lg' = 'md'; + + @Input() + public displayFallback = ''; public renaming = false; - public renameForm = new UntypedFormControl(); + public renameForm = new FormControl(''); public onKeyDown(event: KeyboardEvent) { if (Keys.isEscape(event)) { @@ -54,7 +53,21 @@ export class EditableTitleComponent { return; } - this.renameForm.setValue(this.name || ''); + if (!this.renaming) { + let validators: ValidatorFn[] = []; + + if (this.inputTitleLength) { + validators.push(Validators.maxLength(this.inputTitleLength)); + } + + if (this.inputTitleRequired) { + validators.push(Validators.required); + } + + this.renameForm.setValidators(validators); + } + + this.renameForm.setValue(this.inputTitle || ''); this.renaming = !this.renaming; } @@ -64,10 +77,10 @@ export class EditableTitleComponent { } if (this.renameForm.valid) { - const name = this.renameForm.value; + const text = this.renameForm.value || ''; - this.nameChange.emit(name); - this.name = name; + this.inputTitleChange.emit(text); + this.inputTitle = text; this.renaming = false; } diff --git a/frontend/src/app/framework/angular/forms/editable-title.stories.ts b/frontend/src/app/framework/angular/forms/editable-title.stories.ts new file mode 100644 index 000000000..7f1ec2d0b --- /dev/null +++ b/frontend/src/app/framework/angular/forms/editable-title.stories.ts @@ -0,0 +1,134 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { moduleMetadata } from '@storybook/angular'; +import { Meta, Story } from '@storybook/angular/types-6-0'; +import { EditableTitleComponent, LocalizerService, SqxFrameworkModule } from '@app/framework'; + +export default { + title: 'Framework/EditableTitle', + component: EditableTitleComponent, + argTypes: { + inputTitle: { + control: 'inputTitle', + }, + closeButton: { + control: 'boolean', + }, + inputTitleRequired: { + control: 'boolean', + }, + inputTitleLength: { + control: 'number', + }, + size: { + control: 'select', + options: [ + 'sm', + 'md', + 'lg', + ], + }, + }, + args: { + closeButton: true, + inputTitleLength: 30, + inputTitleRequired: true, + }, + decorators: [ + moduleMetadata({ + imports: [ + BrowserAnimationsModule, + FormsModule, + ReactiveFormsModule, + SqxFrameworkModule, + SqxFrameworkModule.forRoot(), + ], + providers: [ + { provide: LocalizerService, useValue: new LocalizerService({}) }, + ], + }), + ], +} as Meta; + +const Template: Story = (args: EditableTitleComponent) => ({ + props: args, + template: ` +
+
+
+ + +
+
+ +
+
+
+ `, +}); + +export const Default = Template.bind({}); + +Default.args = { + inputTitle: 'My Title', + size: 'md', +}; + +export const DefaultNoCloseButton = Template.bind({}); + +DefaultNoCloseButton.args = { + inputTitle: 'My Title', + size: 'md', + closeButton: false, +}; + +export const Small = Template.bind({}); + +Small.args = { + inputTitle: 'My Title', + size: 'sm', +}; + +export const SmallNoCloseButton = Template.bind({}); + +SmallNoCloseButton.args = { + inputTitle: 'My Title', + size: 'sm', + closeButton: false, +}; + +export const Large = Template.bind({}); + +Large.args = { + inputTitle: 'My Title', + size: 'lg', +}; + +export const LargeNoCloseButton = Template.bind({}); + +LargeNoCloseButton.args = { + inputTitle: 'My Title', + size: 'lg', + closeButton: false, +}; + +export const LongTitle = Template.bind({}); + +LongTitle.args = { + inputTitle: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua', + size: 'md', +}; \ No newline at end of file diff --git a/frontend/src/app/framework/angular/language-selector.stories.tsx b/frontend/src/app/framework/angular/language-selector.stories.tsx index 37a2930e1..71e82b176 100644 --- a/frontend/src/app/framework/angular/language-selector.stories.tsx +++ b/frontend/src/app/framework/angular/language-selector.stories.tsx @@ -15,7 +15,7 @@ export default { component: LanguageSelectorComponent, argTypes: { size: { - control: 'enum', + control: 'select', options: [ 'sm', 'md', diff --git a/frontend/src/app/framework/angular/layout-container.directive.ts b/frontend/src/app/framework/angular/layout-container.directive.ts index 6f8a5138c..2639679c3 100644 --- a/frontend/src/app/framework/angular/layout-container.directive.ts +++ b/frontend/src/app/framework/angular/layout-container.directive.ts @@ -63,13 +63,14 @@ export class LayoutContainerDirective implements AfterViewInit { } let currentSize = 0; + let layoutWidth = this.containerWidth; let layoutsWidthSpread = 0; for (const layout of layouts) { - if (layout.desiredWidth > 0) { - const layoutWidth = layout.desiredWidth; + const desiredWidth = layout.computeDesiredWidth(layouts.length, layoutWidth); - layout.measure(`${layoutWidth}rem`); + if (desiredWidth >= 0) { + layout.measure(`${desiredWidth}rem`); currentSize += layout.renderWidth; } else { @@ -77,10 +78,12 @@ export class LayoutContainerDirective implements AfterViewInit { } } - const spreadWidth = (this.containerWidth - currentSize) / layoutsWidthSpread; + const spreadWidth = (layoutWidth - currentSize) / layoutsWidthSpread; for (const layout of layouts) { - if (layout.desiredWidth <= 0) { + const desiredWidth = layout.computeDesiredWidth(layouts.length, layoutWidth); + + if (desiredWidth < 0) { layout.measure(`${spreadWidth}px`); currentSize += layout.renderWidth; @@ -97,8 +100,10 @@ export class LayoutContainerDirective implements AfterViewInit { currentLayer -= 10; } - const diff = Math.max(0, currentPosition - this.containerWidth); + const diff = Math.max(0, currentPosition - layoutWidth); + this.renderer.setStyle(this.element.nativeElement, 'overflow-x', diff > 1 ? 'auto' : 'hidden'); + this.renderer.setStyle(this.element.nativeElement, 'overflow-y', 'hidden'); this.renderer.setProperty(this.element.nativeElement, 'scrollLeft', diff); } } diff --git a/frontend/src/app/framework/angular/layout.component.html b/frontend/src/app/framework/angular/layout.component.html index f52f59f27..1455e24c8 100644 --- a/frontend/src/app/framework/angular/layout.component.html +++ b/frontend/src/app/framework/angular/layout.component.html @@ -1,8 +1,8 @@ -
- -
-
-
+
+ +
+
+

{{ titleText | sqxTranslate }}

@@ -13,9 +13,21 @@
+ + + + + + + + + + + +
-
-
+
+
@@ -23,7 +35,7 @@ -
+

@@ -37,7 +49,7 @@

- @@ -75,7 +87,7 @@