init
This commit is contained in:
@@ -1,15 +1,155 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import { css, html, LitElement, nothing } from 'lit';
|
||||
import { state, customElement } from 'lit/decorators.js';
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
|
||||
import { UUIButtonState } from '@umbraco-ui/uui';
|
||||
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
|
||||
import { UmbNotificationService, UmbNotificationDefaultData } from '@umbraco-cms/services';
|
||||
import {
|
||||
ApiError,
|
||||
CreatedResult,
|
||||
ModelsBuilder,
|
||||
ModelsBuilderResource,
|
||||
ProblemDetails,
|
||||
} from '@umbraco-cms/backend-api';
|
||||
|
||||
import 'src/core/utils/errorbox';
|
||||
|
||||
@customElement('umb-dashboard-models-builder')
|
||||
export class UmbDashboardModelsBuilderElement extends LitElement {
|
||||
static styles = [UUITextStyles, css``];
|
||||
export class UmbDashboardModelsBuilderElement extends UmbContextConsumerMixin(LitElement) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
.headline {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-block-start: 0;
|
||||
margin-block-end: var(--uui-size-space-4);
|
||||
}
|
||||
|
||||
.models-description p {
|
||||
padding-bottom: var(--uui-size-space-1);
|
||||
margin-bottom: var(--uui-size-space-1);
|
||||
}
|
||||
|
||||
.models-description ul {
|
||||
list-style-type: square;
|
||||
margin: 0;
|
||||
padding-left: var(--uui-size-layout-1);
|
||||
}
|
||||
|
||||
.error {
|
||||
padding-top: var(--uui-size-space-5);
|
||||
font-weight: bold;
|
||||
color: var(--uui-color-danger);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
private _notificationService?: UmbNotificationService;
|
||||
|
||||
@state()
|
||||
private _modelsBuilder?: ModelsBuilder;
|
||||
|
||||
@state()
|
||||
private _createdResult?: CreatedResult;
|
||||
|
||||
@state()
|
||||
private _buttonStateBuild: UUIButtonState = undefined;
|
||||
|
||||
@state()
|
||||
private _buttonStateReload: UUIButtonState = undefined;
|
||||
|
||||
private async _getDashboardData() {
|
||||
try {
|
||||
const modelsBuilder = await ModelsBuilderResource.getModelsBuilderDashboard();
|
||||
this._modelsBuilder = modelsBuilder;
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e instanceof ApiError) {
|
||||
const error = e as ProblemDetails;
|
||||
const data: UmbNotificationDefaultData = {
|
||||
message: error.message ?? 'Something went wrong',
|
||||
};
|
||||
this._notificationService?.peek('danger', { data });
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async _onGenerateModels() {
|
||||
this._buttonStateBuild = 'waiting';
|
||||
const status = await this._postGenerateModels();
|
||||
this._buttonStateBuild = status ? 'success' : 'failed';
|
||||
}
|
||||
|
||||
private async _postGenerateModels() {
|
||||
try {
|
||||
const createdResult = await ModelsBuilderResource.postModelsBuilderBuild();
|
||||
this._createdResult = createdResult;
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e instanceof ApiError) {
|
||||
const error = e as ProblemDetails;
|
||||
const data: UmbNotificationDefaultData = {
|
||||
message: error.message ?? 'Model generation failed',
|
||||
};
|
||||
this._notificationService?.peek('danger', { data });
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._getDashboardData();
|
||||
this.consumeAllContexts(['umbNotificationService'], (instances) => {
|
||||
this._notificationService = instances['umbNotificationService'];
|
||||
});
|
||||
}
|
||||
|
||||
private async _onDashboardReload() {
|
||||
this._buttonStateReload = 'waiting';
|
||||
const status = await this._getDashboardData();
|
||||
this._buttonStateReload = status ? 'success' : 'failed';
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-box>
|
||||
<h1>Models Builder</h1>
|
||||
<div class="headline" slot="headline">
|
||||
<strong>Models Builder</strong>
|
||||
<uui-button .state="${this._buttonStateReload}" look="secondary" @click="${this._onDashboardReload}">
|
||||
Reload
|
||||
</uui-button>
|
||||
</div>
|
||||
<p>Version: ${this._modelsBuilder?.version}</p>
|
||||
|
||||
<div class="models-description">
|
||||
<p>${unsafeHTML(this._modelsBuilder?.modelsNamespace)}</p>
|
||||
</div>
|
||||
|
||||
${this._modelsBuilder?.outOfDateModels === true
|
||||
? html`<p>Models are <strong>out of date</strong></p>`
|
||||
: nothing}
|
||||
${this._modelsBuilder?.canGenerate === true
|
||||
? html` <uui-button
|
||||
.state="${this._buttonStateBuild}"
|
||||
look="primary"
|
||||
label="Generate models"
|
||||
@click="${this._onGenerateModels}">
|
||||
Generate models
|
||||
</uui-button>`
|
||||
: nothing}
|
||||
${this._modelsBuilder?.lastError
|
||||
? html`<p class="error">Last generation failed with the following error:</p>
|
||||
<uui-error-box>${this._modelsBuilder.lastError}</uui-error-box>`
|
||||
: nothing}
|
||||
</uui-box>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { handlers as telemetryHandlers } from './domains/telemetry.handlers';
|
||||
import { handlers as usersHandlers } from './domains/users.handlers';
|
||||
import { handlers as userGroupsHandlers } from './domains/user-groups.handlers';
|
||||
import { handlers as examineManagementHandlers } from './domains/examine-management.handlers';
|
||||
import { handlers as modelsBuilderHandlers } from './domains/modelsbuilder.handlers';
|
||||
|
||||
const handlers = [
|
||||
serverHandlers.serverVersionHandler,
|
||||
@@ -28,6 +29,7 @@ const handlers = [
|
||||
...usersHandlers,
|
||||
...userGroupsHandlers,
|
||||
...examineManagementHandlers,
|
||||
...modelsBuilderHandlers,
|
||||
];
|
||||
|
||||
switch (import.meta.env.VITE_UMBRACO_INSTALL_STATUS) {
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { rest } from 'msw';
|
||||
|
||||
import { umbracoPath } from '@umbraco-cms/utils';
|
||||
import { CreatedResult, ModelsBuilder, OutOfDateStatus } from '@umbraco-cms/backend-api';
|
||||
|
||||
export const handlers = [
|
||||
rest.post(umbracoPath('/models-builder/build'), async (_req, res, ctx) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, (Math.random() + 1) * 1000)); // simulate a delay of 1-2 seconds
|
||||
return res(
|
||||
// Respond with a 200 status code
|
||||
ctx.status(200),
|
||||
ctx.json<CreatedResult>({})
|
||||
);
|
||||
}),
|
||||
|
||||
rest.get(umbracoPath('/models-builder/dashboard'), async (_req, res, ctx) => {
|
||||
return res(
|
||||
ctx.status(200),
|
||||
ctx.json<ModelsBuilder>({
|
||||
mode: undefined,
|
||||
canGenerate: true,
|
||||
outOfDateModels: true,
|
||||
lastError: `[plugin:vite:import-analysis] Missing "./directives/unsafe-htl.js" export in "lit" package
|
||||
C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/src/backoffice/dashboards/models-builder/dashboard-models-builder.element.ts
|
||||
at bail (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:32675:8)
|
||||
at resolve (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:32752:10)
|
||||
at resolveExports (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:34128:12)
|
||||
at resolveDeepImport (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:34146:31)
|
||||
at tryNodeResolve (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:33838:20)
|
||||
at Context.resolveId (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:33598:28)
|
||||
at async Object.resolveId (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:40156:32)
|
||||
at async TransformContext.resolve (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:39921:23)
|
||||
at async normalizeUrl (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vite/dist/node/chunks/dep-67e7f8ab.js:36831:34)
|
||||
at async TransformContext.transform (file:///C:/Users/Umbraco/Documents/Umbraco.CMS.Backoffice/node_modules/vit`,
|
||||
version: '13.0.0',
|
||||
modelsNamespace:
|
||||
"<p>ModelsBuilder is enabled, with the following configuration:</p><ul><li>The <strong>models mode</strong> is 'InMemoryAuto'. Strongly typed models are re-generated on startup and anytime schema changes (i.e. Content Type) are made. No recompilation necessary but the generated models are not available to code outside of Razor.</li><li>Models namespace is Umbraco.Cms.Web.Common.PublishedModels.</li><li>Tracking of <strong>out-of-date models</strong> is not enabled.</li></ul>",
|
||||
trackingOutOfDateModels: true,
|
||||
})
|
||||
);
|
||||
}),
|
||||
|
||||
rest.get(umbracoPath('/models-builder/status'), async (_req, res, ctx) => {
|
||||
return res(
|
||||
// Respond with a 200 status code
|
||||
ctx.status(200),
|
||||
ctx.json<OutOfDateStatus>({})
|
||||
);
|
||||
}),
|
||||
];
|
||||
@@ -11,6 +11,7 @@ import { handlers as telemetryHandlers } from './domains/telemetry.handlers';
|
||||
import { handlers as treeHandlers } from './domains/entity.handlers';
|
||||
|
||||
import { handlers as examineManagementHandlers } from './domains/examine-management.handlers';
|
||||
import { handlers as modelsBuilderHandlers } from './domains/modelsbuilder.handlers';
|
||||
|
||||
export const handlers = [
|
||||
serverHandlers.serverRunningHandler,
|
||||
@@ -27,4 +28,5 @@ export const handlers = [
|
||||
...publishedStatusHandlers,
|
||||
...treeHandlers,
|
||||
...examineManagementHandlers,
|
||||
...modelsBuilderHandlers,
|
||||
];
|
||||
|
||||
60
src/Umbraco.Web.UI.Client/src/core/utils/errorbox.ts
Normal file
60
src/Umbraco.Web.UI.Client/src/core/utils/errorbox.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
|
||||
/**
|
||||
* A simple styled box for showing code-based error messages.
|
||||
* max-height is 500px
|
||||
*
|
||||
* @slot the message
|
||||
*
|
||||
*/
|
||||
@customElement('uui-error-box')
|
||||
export class UUIErrorBox extends LitElement {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#container {
|
||||
border: 2px solid var(--uui-color-divider-emphasis);
|
||||
color: var(--uui-color-text-alt);
|
||||
background-color: var(--uui-color-divider-standalone);
|
||||
padding: var(--uui-size-space-2);
|
||||
border-radius: var(--uui-border-radius);
|
||||
line-height: var(--uui-size-10);
|
||||
}
|
||||
:host uui-scroll-container {
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: inline-block;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
line-break: strict;
|
||||
hyphens: none;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
render() {
|
||||
return html`<div id="container">
|
||||
<uui-scroll-container>
|
||||
<pre><slot></slot></pre>
|
||||
</uui-scroll-container>
|
||||
</div> `;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'uui-error-box': UUIErrorBox;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user