Browse Source

Fix badges and etags.

pull/868/head
Sebastian 4 years ago
parent
commit
9d8dc0d998
  1. 2
      backend/src/Squidex.Infrastructure/Caching/IRequestCache.cs
  2. 33
      backend/src/Squidex.Web/Pipeline/CachingManager.cs
  3. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Queries/RuleEnricherTests.cs
  4. 52
      backend/tests/Squidex.Web.Tests/Pipeline/CachingKeysMiddlewareTests.cs
  5. 32
      frontend/src/app/_theme.html
  6. 2
      frontend/src/app/features/assets/pages/asset-tags.component.html
  7. 8
      frontend/src/app/features/content/shared/references/reference-item.component.html
  8. 4
      frontend/src/app/features/rules/pages/events/rule-event.component.html
  9. 4
      frontend/src/app/features/rules/pages/rules/rule.component.html
  10. 2
      frontend/src/app/features/rules/pages/simulator/simulated-rule-event.component.html
  11. 6
      frontend/src/app/features/schemas/pages/schema/fields/field.component.html
  12. 18
      frontend/src/app/features/settings/pages/clients/client-connect-form.component.html
  13. 4
      frontend/src/app/features/settings/pages/roles/role.component.html
  14. 2
      frontend/src/app/shared/components/schema-category.component.html
  15. 2
      frontend/src/app/shared/components/search/queries/query-path.component.html
  16. 2
      frontend/src/app/shell/pages/internal/apps-menu.component.html
  17. 2
      frontend/src/app/shell/pages/internal/search-menu.component.html

2
backend/src/Squidex.Infrastructure/Caching/IRequestCache.cs

@ -11,7 +11,7 @@ namespace Squidex.Infrastructure.Caching
{ {
void AddDependency(DomainId key, long version); void AddDependency(DomainId key, long version);
void AddDependency(object? value); void AddDependency<T>(T value);
void AddHeader(string header); void AddHeader(string header);
} }

33
backend/src/Squidex.Web/Pipeline/CachingManager.cs

@ -69,9 +69,9 @@ namespace Squidex.Web.Pipeline
} }
} }
public void AddDependency(object? value) public void AddDependency<T>(T value)
{ {
if (value != null) if (value is not null)
{ {
try try
{ {
@ -135,7 +135,7 @@ namespace Squidex.Web.Pipeline
if (stringBuilder.Length > 0) if (stringBuilder.Length > 0)
{ {
response.Headers.Add("Surrogate-Key", stringBuilder.ToString()); response.Headers["Surrogate-Key"] = stringBuilder.ToString();
} }
} }
finally finally
@ -150,7 +150,7 @@ namespace Squidex.Web.Pipeline
} }
} }
public void AddHeader(string header) public void AddHeader(string header, StringValues values)
{ {
if (!string.IsNullOrWhiteSpace(header)) if (!string.IsNullOrWhiteSpace(header))
{ {
@ -164,6 +164,11 @@ namespace Squidex.Web.Pipeline
{ {
slimLock.ExitWriteLock(); slimLock.ExitWriteLock();
} }
foreach (var value in values)
{
AddDependency(value);
}
} }
} }
} }
@ -208,7 +213,7 @@ namespace Squidex.Web.Pipeline
cacheContext?.AddDependency(key.ToString(), version); cacheContext?.AddDependency(key.ToString(), version);
} }
public void AddDependency(object? value) public void AddDependency<T>(T value)
{ {
var cacheContext = httpContextAccessor.HttpContext?.Features.Get<CacheContext>(); var cacheContext = httpContextAccessor.HttpContext?.Features.Get<CacheContext>();
@ -217,9 +222,23 @@ namespace Squidex.Web.Pipeline
public void AddHeader(string header) public void AddHeader(string header)
{ {
var cacheContext = httpContextAccessor.HttpContext?.Features.Get<CacheContext>(); var httpContext = httpContextAccessor.HttpContext;
if (httpContext == null)
{
return;
}
var cacheContext = httpContext.Features.Get<CacheContext>();
if (cacheContext == null)
{
return;
}
httpContext.Request.Headers.TryGetValue(header, out var value);
cacheContext?.AddHeader(header); cacheContext?.AddHeader(header, value);
} }
public void Finish(HttpContext httpContext) public void Finish(HttpContext httpContext)

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Queries/RuleEnricherTests.cs

@ -49,7 +49,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Queries
A.CallTo(() => requestCache.AddDependency(source.UniqueId, source.Version)) A.CallTo(() => requestCache.AddDependency(source.UniqueId, source.Version))
.MustHaveHappened(); .MustHaveHappened();
A.CallTo(() => requestCache.AddDependency(null)) A.CallTo(() => requestCache.AddDependency<Instant?>(null))
.MustNotHaveHappened(); .MustNotHaveHappened();
} }

52
backend/tests/Squidex.Web.Tests/Pipeline/CachingKeysMiddlewareTests.cs

@ -293,6 +293,58 @@ namespace Squidex.Web.Pipeline
Assert.Equal(StringValues.Empty, httpContext.Response.Headers["Surrogate-Key"]); Assert.Equal(StringValues.Empty, httpContext.Response.Headers["Surrogate-Key"]);
} }
[Fact]
public async Task Should_add_header_to_etag()
{
var id1 = DomainId.NewGuid();
await MakeRequestAsync(() =>
{
cachingManager.AddDependency(id1, 12);
});
var etag1 = httpContext.Response.Headers[HeaderNames.ETag].ToString();
httpContext.Response.Headers.Remove(HeaderNames.ETag);
httpContext.Request.Headers["X-Custom"] = "123";
await MakeRequestAsync(() =>
{
cachingManager.AddDependency(id1, 12);
cachingManager.AddHeader("X-Custom");
});
var etag2 = httpContext.Response.Headers[HeaderNames.ETag].ToString();
Assert.NotEqual(etag1, etag2);
}
[Fact]
public async Task Should_not_add_header_to_etag_if_not_found()
{
var id1 = DomainId.NewGuid();
await MakeRequestAsync(() =>
{
cachingManager.AddDependency(id1, 12);
});
var etag1 = httpContext.Response.Headers[HeaderNames.ETag].ToString();
httpContext.Response.Headers.Remove(HeaderNames.ETag);
httpContext.Request.Headers["X-Other"] = "123";
await MakeRequestAsync(() =>
{
cachingManager.AddDependency(id1, 12);
cachingManager.AddHeader("X-Custom");
});
var etag2 = httpContext.Response.Headers[HeaderNames.ETag].ToString();
Assert.Equal(etag1, etag2);
}
[Fact] [Fact]
public async Task Should_generate_etag_from_ids_and_versions() public async Task Should_generate_etag_from_ids_and_versions()
{ {

32
frontend/src/app/_theme.html

@ -1161,25 +1161,25 @@
<h2>Badges</h2> <h2>Badges</h2>
<div class="bs-component" style="margin-bottom: 40px;"> <div class="bs-component" style="margin-bottom: 40px;">
<span class="badge badge-primary">Primary</span> <span class="badge bg-primary">Primary</span>
<span class="badge badge-secondary">Secondary</span> <span class="badge bg-secondary">Secondary</span>
<span class="badge badge-success">Success</span> <span class="badge bg-success">Success</span>
<span class="badge badge-danger">Danger</span> <span class="badge bg-danger">Danger</span>
<span class="badge badge-warning">Warning</span> <span class="badge bg-warning">Warning</span>
<span class="badge badge-info">Info</span> <span class="badge bg-info">Info</span>
<span class="badge badge-light">Light</span> <span class="badge bg-light">Light</span>
<span class="badge badge-dark">Dark</span> <span class="badge bg-dark">Dark</span>
</div> </div>
<div class="bs-component"> <div class="bs-component">
<span class="badge rounded-pill badge-primary">Primary</span> <span class="badge rounded-pill bg-primary">Primary</span>
<span class="badge rounded-pill badge-secondary">Secondary</span> <span class="badge rounded-pill bg-secondary">Secondary</span>
<span class="badge rounded-pill badge-success">Success</span> <span class="badge rounded-pill bg-success">Success</span>
<span class="badge rounded-pill badge-danger">Danger</span> <span class="badge rounded-pill bg-danger">Danger</span>
<span class="badge rounded-pill badge-warning">Warning</span> <span class="badge rounded-pill bg-warning">Warning</span>
<span class="badge rounded-pill badge-info">Info</span> <span class="badge rounded-pill bg-info">Info</span>
<span class="badge rounded-pill badge-light">Light</span> <span class="badge rounded-pill bg-light">Light</span>
<span class="badge rounded-pill badge-dark">Dark</span> <span class="badge rounded-pill bg-dark">Dark</span>
</div> </div>
</div> </div>
</div> </div>

2
frontend/src/app/features/assets/pages/asset-tags.component.html

@ -12,7 +12,7 @@
<span class="truncate">{{tag.name}}</span> <span class="truncate">{{tag.name}}</span>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<div class="badge badge-secondary rounded-pill">{{tag.count}}</div> <div class="badge bg-secondary rounded-pill">{{tag.count}}</div>
<a class="btn-sm btn-text-secondary btn-rename" (click)="renameTag(tag)" *ngIf="canRename" sqxStopClick> <a class="btn-sm btn-text-secondary btn-rename" (click)="renameTag(tag)" *ngIf="canRename" sqxStopClick>
<i class="icon-pencil"></i> <i class="icon-pencil"></i>

8
frontend/src/app/features/content/shared/references/reference-item.component.html

@ -12,8 +12,8 @@
</td> </td>
<td class="cell-valid" *ngIf="validityVisible"> <td class="cell-valid" *ngIf="validityVisible">
<span class="badge rounded-pill badge-success" *ngIf="valid === true">VALID</span> <span class="badge rounded-pill bg-success" *ngIf="valid === true">VALID</span>
<span class="badge rounded-pill badge-danger" *ngIf="valid === false">INVALID</span> <span class="badge rounded-pill bg-danger" *ngIf="valid === false">INVALID</span>
</td> </td>
<td sqxContentListCell="meta.status.color"> <td sqxContentListCell="meta.status.color">
@ -21,8 +21,8 @@
</td> </td>
<td class="cell-label" *ngIf="!isCompact"> <td class="cell-label" *ngIf="!isCompact">
<div class="badge-container d-flex align-items-center"> <div class="bg-container d-flex align-items-center">
<span class="badge badge-primary rounded-pill truncate-inline">{{content.schemaDisplayName}}</span> <span class="badge bg-primary rounded-pill truncate-inline">{{content.schemaDisplayName}}</span>
</div> </div>
</td> </td>

4
frontend/src/app/features/rules/pages/events/rule-event.component.html

@ -1,6 +1,6 @@
<tr [class.expanded]="expanded" class="table-items-row"> <tr [class.expanded]="expanded" class="table-items-row">
<td class="cell-label"> <td class="cell-label">
<span class="badge rounded-pill badge-{{jobResultClass}}">{{event.jobResult}}</span> <span class="badge rounded-pill bg-{{jobResultClass}}">{{event.jobResult}}</span>
</td> </td>
<td class="cell-40"> <td class="cell-40">
<span class="truncate">{{event.eventName}}</span> <span class="truncate">{{event.eventName}}</span>
@ -25,7 +25,7 @@
<div class="row g-0 event-stats align-items-center"> <div class="row g-0 event-stats align-items-center">
<div class="col-3"> <div class="col-3">
<span class="badge rounded-pill badge-{{resultClass}}">{{event.result}}</span> <span class="badge rounded-pill bg-{{resultClass}}">{{event.result}}</span>
</div> </div>
<div class="col-2"> <div class="col-2">
{{ 'rules.ruleEvents.numAttemptsLabel' | sqxTranslate }}: {{event.numCalls}} {{ 'rules.ruleEvents.numAttemptsLabel' | sqxTranslate }}: {{event.numCalls}}

4
frontend/src/app/features/rules/pages/rules/rule.component.html

@ -99,12 +99,12 @@
<div class="col-3"> <div class="col-3">
{{ 'common.succeeded' | sqxTranslate }} {{ 'common.succeeded' | sqxTranslate }}
<span class="badge badge-success rounded-pill" *ngIf="rule.numSucceeded > 0">{{rule.numSucceeded}}</span> <span class="badge bg-success rounded-pill" *ngIf="rule.numSucceeded > 0">{{rule.numSucceeded}}</span>
</div> </div>
<div class="col-3"> <div class="col-3">
{{ 'common.failed' | sqxTranslate }} {{ 'common.failed' | sqxTranslate }}
<span class="badge badge-danger rounded-pill" *ngIf="rule.numFailed > 0">{{rule.numFailed}}</span> <span class="badge bg-danger rounded-pill" *ngIf="rule.numFailed > 0">{{rule.numFailed}}</span>
</div> </div>
<div class="col"> <div class="col">
{{ 'common.lastExecuted' | sqxTranslate }}: <span>{{rule.lastExecuted | sqxFromNow:'-'}}</span> {{ 'common.lastExecuted' | sqxTranslate }}: <span>{{rule.lastExecuted | sqxFromNow:'-'}}</span>

2
frontend/src/app/features/rules/pages/simulator/simulated-rule-event.component.html

@ -1,6 +1,6 @@
<tr [class.expanded]="expanded" class="table-items-row"> <tr [class.expanded]="expanded" class="table-items-row">
<td class="cell-label"> <td class="cell-label">
<span class="badge rounded-pill badge-{{statusClass}}">{{status}}</span> <span class="badge rounded-pill bg-{{statusClass}}">{{status}}</span>
</td> </td>
<td class="cell-40"> <td class="cell-40">
<span class="truncate">{{event.eventName}}</span> <span class="truncate">{{event.eventName}}</span>

6
frontend/src/app/features/schemas/pages/schema/fields/field.component.html

@ -22,15 +22,15 @@
</div> </div>
<div class="col col-tags flex-nowrap"> <div class="col col-tags flex-nowrap">
<div class="float-end"> <div class="float-end">
<span class="ms-1 badge rounded-pill badge-danger" *ngIf="field.isLocked"> <span class="ms-1 badge rounded-pill bg-danger" *ngIf="field.isLocked">
{{ 'schemas.field.lockedMarker' | sqxTranslate }} {{ 'schemas.field.lockedMarker' | sqxTranslate }}
</span> </span>
<span class="ms-1 badge rounded-pill badge-success" *ngIf="!field.isDisabled"> <span class="ms-1 badge rounded-pill bg-success" *ngIf="!field.isDisabled">
{{ 'schemas.field.enabledMarker' | sqxTranslate }} {{ 'schemas.field.enabledMarker' | sqxTranslate }}
</span> </span>
<span class="ms-1 badge rounded-pill badge-danger" *ngIf="field.isDisabled"> <span class="ms-1 badge rounded-pill bg-danger" *ngIf="field.isDisabled">
{{ 'schemas.field.disabledMarker' | sqxTranslate }} {{ 'schemas.field.disabledMarker' | sqxTranslate }}
</span> </span>
</div> </div>

18
frontend/src/app/features/settings/pages/clients/client-connect-form.component.html

@ -66,7 +66,7 @@
<ng-container *ngSwitchCase="'HTTP'"> <ng-container *ngSwitchCase="'HTTP'">
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">1</span> {{ 'clients.connectWizard.manuallyStep1' | sqxTranslate }}</h5> <h5><span class="badge rounded-pill bg-dark">1</span> {{ 'clients.connectWizard.manuallyStep1' | sqxTranslate }}</h5>
<p> <p>
<sqx-code>{{connectHttpText}}</sqx-code> <sqx-code>{{connectHttpText}}</sqx-code>
@ -74,7 +74,7 @@
</div> </div>
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">2</span> {{ 'clients.connectWizard.manuallyStep2' | sqxTranslate }}</h5> <h5><span class="badge rounded-pill bg-dark">2</span> {{ 'clients.connectWizard.manuallyStep2' | sqxTranslate }}</h5>
<p> <p>
<sqx-code>{{connectToken?.accessToken}}</sqx-code> <sqx-code>{{connectToken?.accessToken}}</sqx-code>
@ -82,7 +82,7 @@
</div> </div>
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">3</span> {{ 'clients.connectWizard.manuallyStep3' | sqxTranslate }}</h5> <h5><span class="badge rounded-pill bg-dark">3</span> {{ 'clients.connectWizard.manuallyStep3' | sqxTranslate }}</h5>
<p> <p>
<sqx-code>Authorization: Bearer [YOUR_TOKEN]</sqx-code> <sqx-code>Authorization: Bearer [YOUR_TOKEN]</sqx-code>
@ -95,7 +95,7 @@
</ng-container> </ng-container>
<ng-container *ngSwitchCase="'CLI'"> <ng-container *ngSwitchCase="'CLI'">
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">1</span> {{ 'clients.connectWizard.cliStep1' | sqxTranslate }}</h5> <h5><span class="badge rounded-pill bg-dark">1</span> {{ 'clients.connectWizard.cliStep1' | sqxTranslate }}</h5>
<div [innerHTML]="'clients.connectWizard.cliStep1Download' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div> <div [innerHTML]="'clients.connectWizard.cliStep1Download' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
@ -105,11 +105,11 @@
</div> </div>
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">2</span> <span [innerHTML]="'clients.connectWizard.cliStep2' | sqxTranslate | sqxMarkdownInline | sqxSafeHtml"></span></h5> <h5><span class="badge rounded-pill bg-dark">2</span> <span [innerHTML]="'clients.connectWizard.cliStep2' | sqxTranslate | sqxMarkdownInline | sqxSafeHtml"></span></h5>
</div> </div>
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">3</span> {{ 'clients.connectWizard.cliStep3' | sqxTranslate }}</h5> <h5><span class="badge rounded-pill bg-dark">3</span> {{ 'clients.connectWizard.cliStep3' | sqxTranslate }}</h5>
<p> <p>
<sqx-code>sq config add {{appName}} {{appName}}:{{client.id}} {{client.secret}} -u {{apiUrl.value}} --use</sqx-code> <sqx-code>sq config add {{appName}} {{appName}}:{{client.id}} {{client.secret}} -u {{apiUrl.value}} --use</sqx-code>
@ -121,7 +121,7 @@
</div> </div>
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">4</span> {{ 'clients.connectWizard.cliStep4' | sqxTranslate }}</h5> <h5><span class="badge rounded-pill bg-dark">4</span> {{ 'clients.connectWizard.cliStep4' | sqxTranslate }}</h5>
<p> <p>
<sqx-code>sq config use {{appName}}</sqx-code> <sqx-code>sq config use {{appName}}</sqx-code>
@ -130,7 +130,7 @@
</ng-container> </ng-container>
<ng-container *ngSwitchCase="'SDK'"> <ng-container *ngSwitchCase="'SDK'">
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">1</span> {{ 'clients.connectWizard.sdkStep1' | sqxTranslate }}</h5> <h5><span class="badge rounded-pill bg-dark">1</span> {{ 'clients.connectWizard.sdkStep1' | sqxTranslate }}</h5>
<div [innerHTML]="'clients.connectWizard.sdkStep1Download' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div> <div [innerHTML]="'clients.connectWizard.sdkStep1Download' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
@ -140,7 +140,7 @@
</div> </div>
<div class="section step"> <div class="section step">
<h5><span class="badge rounded-pill badge-dark">2</span> {{ 'clients.connectWizard.sdkStep2' | sqxTranslate }}</h5> <h5><span class="badge rounded-pill bg-dark">2</span> {{ 'clients.connectWizard.sdkStep2' | sqxTranslate }}</h5>
<p> <p>
<sqx-code>{{connectLibraryText}}</sqx-code> <sqx-code>{{connectLibraryText}}</sqx-code>

4
frontend/src/app/features/settings/pages/roles/role.component.html

@ -6,12 +6,12 @@
<div class="col text-decent"> <div class="col text-decent">
{{ 'common.clients' | sqxTranslate }} {{ 'common.clients' | sqxTranslate }}
<span class="badge badge-secondary rounded-pill" [class.text-muted]="role.numClients <= 0">{{role.numClients}}</span> <span class="badge bg-secondary rounded-pill" [class.text-muted]="role.numClients <= 0">{{role.numClients}}</span>
</div> </div>
<div class="col text-decent"> <div class="col text-decent">
{{ 'common.users' | sqxTranslate }} {{ 'common.users' | sqxTranslate }}
<span class="badge badge-secondary rounded-pill" [class.text-muted]="role.numContributors <= 0">{{role.numContributors}}</span> <span class="badge bg-secondary rounded-pill" [class.text-muted]="role.numContributors <= 0">{{role.numContributors}}</span>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<div class="float-end"> <div class="float-end">

2
frontend/src/app/shared/components/schema-category.component.html

@ -19,7 +19,7 @@
</div> </div>
<div class="col-auto"> <div class="col-auto">
<ng-container *ngIf="schemaCategory.countSchemasInSubtree > 0; else noSchemas"> <ng-container *ngIf="schemaCategory.countSchemasInSubtree > 0; else noSchemas">
<span class="badge rounded-pill badge-secondary">{{schemaCategory.countSchemasInSubtreeFiltered}}</span> <span class="badge rounded-pill bg-secondary">{{schemaCategory.countSchemasInSubtreeFiltered}}</span>
</ng-container> </ng-container>
<ng-template #noSchemas> <ng-template #noSchemas>
<button type="button" class="btn btn-sm btn-text-secondary btn-remove" (click)="remove.emit(schemaCategory.name)" *ngIf="schemaCategory.name"> <button type="button" class="btn btn-sm btn-text-secondary btn-remove" (click)="remove.emit(schemaCategory.name)" *ngIf="schemaCategory.name">

2
frontend/src/app/shared/components/search/queries/query-path.component.html

@ -9,7 +9,7 @@
<ng-template let-field="$implicit"> <ng-template let-field="$implicit">
<div class="row"> <div class="row">
<div class="col-auto"> <div class="col-auto">
<div class="badge rounded-pill badge-primary">{{field.path}}</div> <div class="badge rounded-pill bg-primary">{{field.path}}</div>
</div> </div>
<div class="col text-end"> <div class="col text-end">
<sqx-form-hint>{{field.description}}</sqx-form-hint> <sqx-form-hint>{{field.description}}</sqx-form-hint>

2
frontend/src/app/shell/pages/internal/apps-menu.component.html

@ -19,7 +19,7 @@
<h3>{{ 'apps.allApps' | sqxTranslate }}</h3> <h3>{{ 'apps.allApps' | sqxTranslate }}</h3>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<span class="badge badge-primary rounded-pill">{{apps.length}}</span> <span class="badge bg-primary rounded-pill">{{apps.length}}</span>
</div> </div>
</div> </div>
</a> </a>

2
frontend/src/app/shell/pages/internal/search-menu.component.html

@ -20,7 +20,7 @@
{{result.name}} {{result.name}}
</div> </div>
<div class="col-auto text-end" *ngIf="result.label"> <div class="col-auto text-end" *ngIf="result.label">
<div class="badge rounded-pill badge-primary ms-2">{{result.label}}</div> <div class="badge rounded-pill bg-primary ms-2">{{result.label}}</div>
</div> </div>
</div> </div>
</ng-template> </ng-template>

Loading…
Cancel
Save