diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Text/IndexState.cs b/src/Squidex.Domain.Apps.Entities/Contents/Text/IndexState.cs index b181b9e12..8322a6a8a 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Text/IndexState.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/Text/IndexState.cs @@ -34,7 +34,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text document.AddBinaryDocValuesField(MetaFor, GetValue(forDraft, forPublished)); } - public void Index(Term term, Guid id, byte draft, byte forDraft, byte forPublished) + public void Index(Term term, byte forDraft, byte forPublished) { indexWriter.UpdateBinaryDocValue(term, MetaFor, GetValue(forDraft, forPublished)); } diff --git a/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs b/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs index 9e4453fcf..010498515 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs @@ -139,16 +139,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text } } - Document document = null; + var document = new Document(); - if (languages.Count > 0) + foreach (var field in languages) { - document = new Document(); - - foreach (var field in languages) - { - document.AddTextField(field.Key, field.Value.ToString(), Field.Store.NO); - } + document.AddTextField(field.Key, field.Value.ToString(), Field.Store.NO); } return document; @@ -158,7 +153,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text { var term = new Term(MetaKey, BuildKey(draft)); - indexState.Index(term, id, draft, forDraft, forPublished); + indexState.Index(term, forDraft, forPublished); } private int GetPublishedDocument() diff --git a/src/Squidex/Config/Domain/StoreServices.cs b/src/Squidex/Config/Domain/StoreServices.cs index c1fa6c662..9b7f5e8de 100644 --- a/src/Squidex/Config/Domain/StoreServices.cs +++ b/src/Squidex/Config/Domain/StoreServices.cs @@ -76,6 +76,9 @@ namespace Squidex.Config.Domain services.AddTransientAs() .As(); + services.AddTransientAs() + .As(); + services.AddHealthChecks() .AddCheck("MongoDB", tags: new[] { "node" }); diff --git a/src/Squidex/app/framework/angular/modals/modal-dialog.component.html b/src/Squidex/app/framework/angular/modals/modal-dialog.component.html index 86afe1fc3..b3586529f 100644 --- a/src/Squidex/app/framework/angular/modals/modal-dialog.component.html +++ b/src/Squidex/app/framework/angular/modals/modal-dialog.component.html @@ -8,7 +8,7 @@ - diff --git a/src/Squidex/app/shared/components/asset-dialog.component.html b/src/Squidex/app/shared/components/asset-dialog.component.html index 4f436aafc..a66b80f3e 100644 --- a/src/Squidex/app/shared/components/asset-dialog.component.html +++ b/src/Squidex/app/shared/components/asset-dialog.component.html @@ -20,7 +20,11 @@ - + + +
diff --git a/src/Squidex/app/shared/components/asset-dialog.component.scss b/src/Squidex/app/shared/components/asset-dialog.component.scss index fbb752506..7e649ca02 100644 --- a/src/Squidex/app/shared/components/asset-dialog.component.scss +++ b/src/Squidex/app/shared/components/asset-dialog.component.scss @@ -1,2 +1,20 @@ @import '_vars'; -@import '_mixins'; \ No newline at end of file +@import '_mixins'; + +.form-group { + position: relative; +} + +.slug { + padding-right: 6rem; +} + +.btn-generate { + & { + @include absolute(auto, 10px, 3px, auto); + } + + &:focus { + @include box-shadow-none; + } +} \ No newline at end of file diff --git a/src/Squidex/app/shared/components/asset-dialog.component.ts b/src/Squidex/app/shared/components/asset-dialog.component.ts index 19a8f33a7..f16eeafde 100644 --- a/src/Squidex/app/shared/components/asset-dialog.component.ts +++ b/src/Squidex/app/shared/components/asset-dialog.component.ts @@ -55,6 +55,10 @@ export class AssetDialogComponent extends StatefulComponent implements OnInit { this.annotateForm.load(this.asset); } + public generateSlug() { + this.annotateForm.generateSlug(this.asset); + } + public emitCancel() { this.cancel.emit(); } diff --git a/src/Squidex/app/shared/components/asset.component.html b/src/Squidex/app/shared/components/asset.component.html index c37b4b26c..bb466fb5c 100644 --- a/src/Squidex/app/shared/components/asset.component.html +++ b/src/Squidex/app/shared/components/asset.component.html @@ -63,7 +63,7 @@
- +
{{asset.pixelWidth}}x{{asset.pixelHeight}}px, {{asset.fileSize | sqxFileSize}} diff --git a/src/Squidex/app/shared/state/assets.forms.ts b/src/Squidex/app/shared/state/assets.forms.ts index dec393dd7..324bd7258 100644 --- a/src/Squidex/app/shared/state/assets.forms.ts +++ b/src/Squidex/app/shared/state/assets.forms.ts @@ -7,6 +7,8 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import slugify from 'slugify'; + import { Form, Types } from '@app/framework'; import { AssetDto } from './../services/assets.service'; @@ -62,6 +64,22 @@ export class AnnotateAssetForm extends Form { return result; } + public generateSlug(asset: AssetDto) { + const fileName = this.form.get('fileName')!.value; + + if (fileName) { + let slug = slugify(fileName, { lower: true }); + + let index = asset.fileName.lastIndexOf('.'); + + if (index > 0) { + slug += asset.fileName.substr(index); + } + + this.form.get('slug')!.setValue(slug); + } + } + public load(asset: AssetDto) { let fileName = asset.fileName; diff --git a/tools/Migrate_01/MigrationPath.cs b/tools/Migrate_01/MigrationPath.cs index 3d62e722f..90ecb63d9 100644 --- a/tools/Migrate_01/MigrationPath.cs +++ b/tools/Migrate_01/MigrationPath.cs @@ -17,7 +17,7 @@ namespace Migrate_01 { public sealed class MigrationPath : IMigrationPath { - private const int CurrentVersion = 16; + private const int CurrentVersion = 17; private readonly IServiceProvider serviceProvider; public MigrationPath(IServiceProvider serviceProvider) @@ -100,13 +100,19 @@ namespace Migrate_01 // Version 15: Introduce custom full text search actors. if (version < 15) { - yield return serviceProvider.GetService(); + yield return serviceProvider.GetRequiredService(); } // Version 16: Introduce file name slugs for assets. if (version < 16) { - yield return serviceProvider.GetService(); + yield return serviceProvider.GetRequiredService(); + } + + // Version 17: Rename slug field. + if (version < 17) + { + yield return serviceProvider.GetService(); } yield return serviceProvider.GetRequiredService(); diff --git a/tools/Migrate_01/Migrations/MongoDb/RenameSlugField.cs b/tools/Migrate_01/Migrations/MongoDb/RenameSlugField.cs new file mode 100644 index 000000000..20de74c1f --- /dev/null +++ b/tools/Migrate_01/Migrations/MongoDb/RenameSlugField.cs @@ -0,0 +1,43 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using MongoDB.Bson; +using MongoDB.Driver; +using Squidex.Infrastructure.Migrations; +using Squidex.Infrastructure.MongoDb; +using Squidex.Infrastructure.Tasks; + +namespace Migrate_01.Migrations.MongoDb +{ + public sealed class RenameSlugField : IMigration + { + private readonly IMongoDatabase database; + private readonly MongoDbOptions options; + + public RenameSlugField(IMongoDatabase database, IOptions options) + { + this.database = database; + this.options = options.Value; + } + + public Task UpdateAsync() + { + if (options.IsCosmosDb) + { + return TaskHelper.Done; + } + + var collection = database.GetCollection("States_Assets"); + + var update = Builders.Update.Rename("FileNameSlug", "Slug"); + + return collection.UpdateManyAsync(new BsonDocument(), update); + } + } +}