Merge branch 'main' into v14/bugfix/hide-content-workspace-view-when-no-properties

This commit is contained in:
Mads Rasmussen
2024-07-04 15:17:29 +02:00
committed by GitHub
192 changed files with 23040 additions and 15118 deletions

View File

@@ -0,0 +1,18 @@
import { defineConfig } from '@hey-api/openapi-ts';
export default defineConfig({
client: 'fetch',
input: 'https://raw.githubusercontent.com/umbraco/Umbraco-CMS/v14/dev/src/Umbraco.Cms.Api.Management/OpenApi.json',
output: {
path: 'src/external/backend-api/src',
format: 'prettier',
lint: 'eslint',
},
schemas: false,
services: {
asClass: true,
},
types: {
enums: 'typescript',
},
});

View File

@@ -0,0 +1,19 @@
import { defineConfig } from '@hey-api/openapi-ts';
export default defineConfig({
client: 'fetch',
debug: true,
input: 'http://localhost:11000/umbraco/swagger/management/swagger.json',
output: {
path: 'src/external/backend-api/src',
format: 'prettier',
lint: 'eslint',
},
schemas: false,
services: {
asClass: true,
},
types: {
enums: 'typescript',
},
});

View File

@@ -0,0 +1,19 @@
import { defineConfig } from '@hey-api/openapi-ts';
export default defineConfig({
client: 'fetch',
debug: true,
input: '../Umbraco.Cms.Api.Management/OpenApi.json',
output: {
path: 'src/external/backend-api/src',
format: 'prettier',
lint: 'eslint',
},
schemas: false,
services: {
asClass: true,
},
types: {
enums: 'typescript',
},
});

View File

@@ -21,7 +21,9 @@
"./src/packages/webhook",
"./src/packages/health-check",
"./src/packages/tags",
"./src/packages/templating"
"./src/packages/templating",
"./src/packages/property-editors",
"./src/packages/media"
],
"dependencies": {
"@types/diff": "^5.2.1",
@@ -44,10 +46,10 @@
"devDependencies": {
"@babel/core": "^7.24.3",
"@eslint/js": "^9.6.0",
"@hey-api/openapi-ts": "^0.37.3",
"@hey-api/openapi-ts": "^0.48.1",
"@mdx-js/react": "^3.0.0",
"@open-wc/testing": "^4.0.0",
"@playwright/test": "^1.41.1",
"@playwright/test": "^1.45.1",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
@@ -144,9 +146,9 @@
}
},
"node_modules/@apidevtools/json-schema-ref-parser": {
"version": "11.5.4",
"resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.5.4.tgz",
"integrity": "sha512-o2fsypTGU0WxRxbax8zQoHiIB4dyrkwYfcm8TxZ+bx9pCzcWZbQtiMqpgBvWA/nJ2TrGjK5adCLfTH8wUeU/Wg==",
"version": "11.6.4",
"resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz",
"integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==",
"dev": true,
"dependencies": {
"@jsdevtools/ono": "^7.1.3",
@@ -2693,19 +2695,19 @@
"dev": true
},
"node_modules/@hey-api/openapi-ts": {
"version": "0.37.3",
"resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.37.3.tgz",
"integrity": "sha512-bqadMe9YpzwO9nkpCK+XEwbom9V/WNcUSOYKp8lBJbe/Rve/eSnTjANmll65SU/uoc/5kgrnkD0Eh4hcPqSYrA==",
"version": "0.48.1",
"resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.48.1.tgz",
"integrity": "sha512-iZBEmS12EWn4yl/nYMui+PA3hprjFR9z+9p+p+s3f0VRXPw+uZWO0yuIfCcsAw1n0isikw2uJEY4qxwlnI07AQ==",
"dev": true,
"dependencies": {
"@apidevtools/json-schema-ref-parser": "11.5.4",
"c12": "1.10.0",
"@apidevtools/json-schema-ref-parser": "11.6.4",
"c12": "1.11.1",
"camelcase": "8.0.0",
"commander": "12.0.0",
"commander": "12.1.0",
"handlebars": "4.7.8"
},
"bin": {
"openapi-ts": "bin/index.js"
"openapi-ts": "bin/index.cjs"
},
"engines": {
"node": "^18.0.0 || >=20.0.0"
@@ -3383,12 +3385,12 @@
}
},
"node_modules/@playwright/test": {
"version": "1.45.0",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.0.tgz",
"integrity": "sha512-TVYsfMlGAaxeUllNkywbwek67Ncf8FRGn8ZlRdO291OL3NjG9oMbfVhyP82HQF0CZLMrYsvesqoUekxdWuF9Qw==",
"version": "1.45.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.1.tgz",
"integrity": "sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==",
"dev": true,
"dependencies": {
"playwright": "1.45.0"
"playwright": "1.45.1"
},
"bin": {
"playwright": "cli.js"
@@ -5042,9 +5044,9 @@
]
},
"node_modules/@shikijs/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.0.tgz",
"integrity": "sha512-BZcr6FCmPfP6TXaekvujZcnkFmJHZ/Yglu97r/9VjzVndQA56/F4WjUKtJRQUnK59Wi7p/UTAOekMfCJv7jnYg==",
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.1.tgz",
"integrity": "sha512-qdiJS5a/QGCff7VUFIqd0hDdWly9rDp8lhVmXVrS11aazX8LOTRLHAXkkEeONNsS43EcCd7gax9LLoOz4vlFQA==",
"dev": true
},
"node_modules/@sinclair/typebox": {
@@ -7664,6 +7666,14 @@
"resolved": "src/packages/language",
"link": true
},
"node_modules/@umbraco-backoffice/media": {
"resolved": "src/packages/media",
"link": true
},
"node_modules/@umbraco-backoffice/property-editors": {
"resolved": "src/packages/property-editors",
"link": true
},
"node_modules/@umbraco-backoffice/tag": {
"resolved": "src/packages/tags",
"link": true
@@ -9315,9 +9325,9 @@
}
},
"node_modules/acorn": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
"integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
"version": "8.12.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -10334,23 +10344,31 @@
}
},
"node_modules/c12": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/c12/-/c12-1.10.0.tgz",
"integrity": "sha512-0SsG7UDhoRWcuSvKWHaXmu5uNjDCDN3nkQLRL4Q42IlFy+ze58FcCoI3uPwINXinkz7ZinbhEgyzYFw9u9ZV8g==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/c12/-/c12-1.11.1.tgz",
"integrity": "sha512-KDU0TvSvVdaYcQKQ6iPHATGz/7p/KiVjPg4vQrB6Jg/wX9R0yl5RZxWm9IoZqaIHD2+6PZd81+KMGwRr/lRIUg==",
"dev": true,
"dependencies": {
"chokidar": "^3.6.0",
"confbox": "^0.1.3",
"confbox": "^0.1.7",
"defu": "^6.1.4",
"dotenv": "^16.4.5",
"giget": "^1.2.1",
"jiti": "^1.21.0",
"mlly": "^1.6.1",
"giget": "^1.2.3",
"jiti": "^1.21.6",
"mlly": "^1.7.1",
"ohash": "^1.1.3",
"pathe": "^1.1.2",
"perfect-debounce": "^1.0.0",
"pkg-types": "^1.0.3",
"rc9": "^2.1.1"
"pkg-types": "^1.1.1",
"rc9": "^2.1.2"
},
"peerDependencies": {
"magicast": "^0.3.4"
},
"peerDependenciesMeta": {
"magicast": {
"optional": true
}
}
},
"node_modules/cache-content-type": {
@@ -10407,9 +10425,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001639",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz",
"integrity": "sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==",
"version": "1.0.30001640",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz",
"integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==",
"dev": true,
"funding": [
{
@@ -10879,9 +10897,9 @@
}
},
"node_modules/commander": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz",
"integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==",
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
"dev": true,
"engines": {
"node": ">=18"
@@ -17862,9 +17880,9 @@
}
},
"node_modules/pkg-types": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.2.tgz",
"integrity": "sha512-VEGf1he2DR5yowYRl0XJhWJq5ktm9gYIsH+y8sNJpHlxch7JPDaufgrsl4vYjd9hMUY8QVjoNncKbow9I7exyA==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.3.tgz",
"integrity": "sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==",
"dev": true,
"dependencies": {
"confbox": "^0.1.7",
@@ -17873,12 +17891,12 @@
}
},
"node_modules/playwright": {
"version": "1.45.0",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.0.tgz",
"integrity": "sha512-4z3ac3plDfYzGB6r0Q3LF8POPR20Z8D0aXcxbJvmfMgSSq1hkcgvFRXJk9rUq5H/MJ0Ktal869hhOdI/zUTeLA==",
"version": "1.45.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz",
"integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==",
"dev": true,
"dependencies": {
"playwright-core": "1.45.0"
"playwright-core": "1.45.1"
},
"bin": {
"playwright": "cli.js"
@@ -17891,9 +17909,9 @@
}
},
"node_modules/playwright-core": {
"version": "1.45.0",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.0.tgz",
"integrity": "sha512-lZmHlFQ0VYSpAs43dRq1/nJ9G/6SiTI7VPqidld9TDefL9tX87bTKExWZZUF5PeRyqtXqd8fQi2qmfIedkwsNQ==",
"version": "1.45.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz",
"integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
@@ -19333,12 +19351,12 @@
}
},
"node_modules/shiki": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.0.tgz",
"integrity": "sha512-YD2sXQ+TMD/F9BimV9Jn0wj35pqOvywvOG/3PB6hGHyGKlM7TJ9tyJ02jOb2kF8F0HfJwKNYrh3sW7jEcuRlXA==",
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.1.tgz",
"integrity": "sha512-uafV7WCgN4YYrccH6yxpnps6k38sSTlFRrwc4jycWmhWxJIm9dPrk+XkY1hZ2t0I7jmacMNb15Lf2fspa/Y3lg==",
"dev": true,
"dependencies": {
"@shikijs/core": "1.10.0"
"@shikijs/core": "1.10.1"
}
},
"node_modules/side-channel": {
@@ -21060,9 +21078,9 @@
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
"integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
"integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
"dev": true,
"funding": [
{
@@ -21297,13 +21315,13 @@
}
},
"node_modules/vite": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz",
"integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==",
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz",
"integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==",
"dev": true,
"dependencies": {
"esbuild": "^0.21.3",
"postcss": "^8.4.38",
"postcss": "^8.4.39",
"rollup": "^4.13.0"
},
"bin": {
@@ -22272,6 +22290,12 @@
"src/packages/language": {
"name": "@umbraco-backoffice/language"
},
"src/packages/media": {
"name": "@umbraco-backoffice/media"
},
"src/packages/property-editors": {
"name": "@umbraco-backoffice/property-editors"
},
"src/packages/tags": {
"name": "@umbraco-backoffice/tag"
},

View File

@@ -139,7 +139,9 @@
"./src/packages/webhook",
"./src/packages/health-check",
"./src/packages/tags",
"./src/packages/templating"
"./src/packages/templating",
"./src/packages/property-editors",
"./src/packages/media"
],
"scripts": {
"backoffice:test:e2e": "npx playwright test",
@@ -159,9 +161,9 @@
"example": "node ./devops/example-runner/index.js",
"format:fix": "npm run format -- --write",
"format": "prettier 'src/**/*.ts' --check",
"generate:server-api-local": "openapi-ts --input ../Umbraco.Cms.Api.Management/OpenApi.json --output src/external/backend-api/src --debug true --enums typescript --lint true --schemas false",
"generate:server-api-dev": "openapi-ts --input http://localhost:11000/umbraco/swagger/management/swagger.json --output src/external/backend-api/src --debug true --enums typescript --lint true --schemas false",
"generate:server-api": "openapi-ts --input https://raw.githubusercontent.com/umbraco/Umbraco-CMS/v14/dev/src/Umbraco.Cms.Api.Management/OpenApi.json --output src/external/backend-api/src --debug true --enums typescript --lint true --schemas false",
"generate:server-api-local": "openapi-ts --file devops/openapi-ts/openapi-ts.local.config.js",
"generate:server-api-dev": "openapi-ts --file devops/openapi-ts/openapi-ts.dev.config.js",
"generate:server-api": "openapi-ts --file devops/openapi-ts/openapi-ts.config.js",
"generate:icons": "node ./devops/icons/index.js",
"generate:overrides": "node ./devops/tsc/index.js",
"generate:jsonschema:dist": "typescript-json-schema --required --include \"./src/packages/core/extension-registry/umbraco-package.ts\" --out dist-cms/umbraco-package-schema.json tsconfig.json UmbracoPackage",
@@ -178,7 +180,7 @@
"test:dev": "web-test-runner --config ./web-test-runner.dev.config.mjs",
"test:dev-watch": "web-test-runner --watch --config ./web-test-runner.dev.config.mjs",
"test:watch": "web-test-runner --watch",
"test": "web-test-runner --coverage",
"test": "web-test-runner",
"wc-analyze:vscode": "wca **/*.element.ts --format vscode --outFile dist-cms/vscode-html-custom-data.json",
"wc-analyze": "wca **/*.element.ts --outFile dist-cms/custom-elements.json",
"generate:tsconfig": "node ./devops/tsconfig/index.js",
@@ -211,10 +213,10 @@
"devDependencies": {
"@babel/core": "^7.24.3",
"@eslint/js": "^9.6.0",
"@hey-api/openapi-ts": "^0.37.3",
"@hey-api/openapi-ts": "^0.48.1",
"@mdx-js/react": "^3.0.0",
"@open-wc/testing": "^4.0.0",
"@playwright/test": "^1.41.1",
"@playwright/test": "^1.45.1",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",

View File

@@ -1,4 +1,4 @@
export type ApiRequestOptions = {
export type ApiRequestOptions<T = unknown> = {
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
readonly url: string;
readonly path?: Record<string, unknown>;
@@ -9,5 +9,6 @@ export type ApiRequestOptions = {
readonly body?: any;
readonly mediaType?: string;
readonly responseHeader?: string;
readonly errors?: Record<number, string>;
readonly responseTransformer?: (data: unknown) => Promise<T>;
readonly errors?: Record<number | string, string>;
};

View File

@@ -2,7 +2,7 @@ import type { ApiRequestOptions } from './ApiRequestOptions';
type Headers = Record<string, string>;
type Middleware<T> = (value: T) => T | Promise<T>;
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>;
export class Interceptors<T> {
_fns: Middleware<T>[];
@@ -11,17 +11,14 @@ export class Interceptors<T> {
this._fns = [];
}
eject(fn: Middleware<T>) {
eject(fn: Middleware<T>): void {
const index = this._fns.indexOf(fn);
if (index !== -1) {
this._fns = [
...this._fns.slice(0, index),
...this._fns.slice(index + 1),
];
this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)];
}
}
use(fn: Middleware<T>) {
use(fn: Middleware<T>): void {
this._fns = [...this._fns, fn];
}
}
@@ -36,8 +33,10 @@ export type OpenAPIConfig = {
USERNAME?: string | Resolver<string> | undefined;
VERSION: string;
WITH_CREDENTIALS: boolean;
interceptors: {request: Interceptors<RequestInit>;
response: Interceptors<Response>;};
interceptors: {
request: Interceptors<RequestInit>;
response: Interceptors<Response>;
};
};
export const OpenAPI: OpenAPIConfig = {
@@ -50,6 +49,8 @@ export const OpenAPI: OpenAPIConfig = {
USERNAME: undefined,
VERSION: 'Latest',
WITH_CREDENTIALS: false,
interceptors: {request: new Interceptors(),response: new Interceptors(),
interceptors: {
request: new Interceptors(),
response: new Interceptors(),
},
};

View File

@@ -42,7 +42,9 @@ export const getQueryString = (params: Record<string, unknown>): string => {
return;
}
if (Array.isArray(value)) {
if (value instanceof Date) {
append(key, value.toISOString());
} else if (Array.isArray(value)) {
value.forEach(v => encodePair(key, v));
} else if (typeof value === 'object') {
Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v));
@@ -99,20 +101,24 @@ export const getFormData = (options: ApiRequestOptions): FormData | undefined =>
return undefined;
};
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>;
export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
export const resolve = async <T>(options: ApiRequestOptions<T>, resolver?: T | Resolver<T>): Promise<T | undefined> => {
if (typeof resolver === 'function') {
return (resolver as Resolver<T>)(options);
}
return resolver;
};
export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise<Headers> => {
export const getHeaders = async <T>(config: OpenAPIConfig, options: ApiRequestOptions<T>): Promise<Headers> => {
const [token, username, password, additionalHeaders] = await Promise.all([
// @ts-ignore
resolve(options, config.TOKEN),
// @ts-ignore
resolve(options, config.USERNAME),
// @ts-ignore
resolve(options, config.PASSWORD),
// @ts-ignore
resolve(options, config.HEADERS),
]);
@@ -154,7 +160,7 @@ export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptio
export const getRequestBody = (options: ApiRequestOptions): unknown => {
if (options.body !== undefined) {
if (options.mediaType?.includes('application/json') || options.mediaType?.includes('+json')) {
return JSON.stringify(options.body)
return JSON.stringify(options.body);
} else if (isString(options.body) || isBlob(options.body) || isFormData(options.body)) {
return options.body;
} else {
@@ -187,7 +193,7 @@ export const sendRequest = async (
}
for (const fn of config.interceptors.request._fns) {
request = await fn(request)
request = await fn(request);
}
onCancel(() => controller.abort());
@@ -302,7 +308,7 @@ export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult):
* @returns CancelablePromise<T>
* @throws ApiError
*/
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise<T> => {
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions<T>): CancelablePromise<T> => {
return new CancelablePromise(async (resolve, reject, onCancel) => {
try {
const url = getUrl(config, options);
@@ -314,18 +320,23 @@ export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions): C
let response = await sendRequest(config, options, url, body, formData, headers, onCancel);
for (const fn of config.interceptors.response._fns) {
response = await fn(response)
response = await fn(response);
}
const responseBody = await getResponseBody(response);
const responseHeader = getResponseHeader(response, options.responseHeader);
let transformedBody = responseBody;
if (options.responseTransformer && response.ok) {
transformedBody = await options.responseTransformer(responseBody)
}
const result: ApiResult = {
url,
ok: response.ok,
status: response.status,
statusText: response.statusText,
body: responseHeader ?? responseBody,
body: responseHeader ?? transformedBody,
};
catchErrorCodes(options, result);

View File

@@ -1,6 +1,6 @@
// This file is auto-generated by @hey-api/openapi-ts
export { ApiError } from './core/ApiError';
export { CancelablePromise, CancelError } from './core/CancelablePromise';
export { OpenAPI, type OpenAPIConfig } from './core/OpenAPI';
export * from './models';
export * from './services';
export * from './services.gen';
export * from './types.gen';

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
const { rest } = window.MockServiceWorker;
import { umbUserMockDb } from '../../data/user/user.db.js';
import { UMB_SLUG } from './slug.js';
import type { UserData } from '@umbraco-cms/backoffice/external/backend-api';
import type { GetUserCurrentLoginProvidersResponse } from '@umbraco-cms/backoffice/external/backend-api';
import { umbracoPath } from '@umbraco-cms/backoffice/utils';
export const handlers = [
@@ -9,12 +9,12 @@ export const handlers = [
const loggedInUser = umbUserMockDb.getCurrentUser();
return res(ctx.status(200), ctx.json(loggedInUser));
}),
rest.get<UserData['responses']['GetUserCurrentLoginProviders']>(
rest.get<GetUserCurrentLoginProvidersResponse>(
umbracoPath(`${UMB_SLUG}/current/login-providers`),
(_req, res, ctx) => {
return res(
ctx.status(200),
ctx.json<UserData['responses']['GetUserCurrentLoginProviders']>([
ctx.json<GetUserCurrentLoginProvidersResponse>([
{
hasManualLinkingEnabled: true,
isLinkedOnUser: true,

View File

@@ -12,7 +12,8 @@ import '../block-grid-entries/index.js';
@customElement('umb-block-grid-areas-container')
export class UmbBlockGridAreasContainerElement extends UmbLitElement {
//
#styleElement?: HTMLLinkElement;
@state()
_styleElement?: HTMLLinkElement;
@state()
_areas?: Array<UmbBlockGridTypeAreaType> = [];
@@ -44,9 +45,11 @@ export class UmbBlockGridAreasContainerElement extends UmbLitElement {
this.observe(
manager.layoutStylesheet,
(stylesheet) => {
this.#styleElement = document.createElement('link');
this.#styleElement.setAttribute('rel', 'stylesheet');
this.#styleElement.setAttribute('href', stylesheet);
// Do not re-render stylesheet if its the same href.
if (!stylesheet || this._styleElement?.href === stylesheet) return;
this._styleElement = document.createElement('link');
this._styleElement.rel = 'stylesheet';
this._styleElement.href = stylesheet;
},
'observeStylesheet',
);
@@ -55,7 +58,7 @@ export class UmbBlockGridAreasContainerElement extends UmbLitElement {
override render() {
return this._areas && this._areas.length > 0
? html` ${this.#styleElement}
? html` ${this._styleElement}
<div
class="umb-block-grid__area-container"
style="--umb-block-grid--area-grid-columns: ${this._areaGridColumns}">

View File

@@ -1,12 +1,9 @@
import { UmbBlockGridEntriesContext } from '../../context/block-grid-entries.context.js';
import type { UmbBlockGridEntryElement } from '../block-grid-entry/index.js';
import {
getAccumulatedValueOfIndex,
getInterpolatedIndexOfPositionInWeightMap,
isWithinRect,
} from '@umbraco-cms/backoffice/utils';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbBlockGridLayoutModel } from '@umbraco-cms/backoffice/block-grid';
import { html, customElement, state, repeat, css, property, nothing } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import '../block-grid-entry/index.js';
@@ -17,6 +14,9 @@ import {
type UmbFormControlValidatorConfig,
} from '@umbraco-cms/backoffice/validation';
import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models';
import { UmbBlockGridEntriesContext } from '../../context/block-grid-entries.context.js';
import type { UmbBlockGridEntryElement } from '../block-grid-entry/index.js';
import type { UmbBlockGridLayoutModel } from '@umbraco-cms/backoffice/block-grid';
/**
* Notice this utility method is not really shareable with others as it also takes areas into account. [NL]
@@ -209,10 +209,10 @@ export class UmbBlockGridEntriesElement extends UmbFormControlMixin(UmbLitElemen
this.observe(
manager.layoutStylesheet,
(stylesheet) => {
if (this._styleElement && this._styleElement.href === stylesheet) return;
if (!stylesheet || this._styleElement?.href === stylesheet) return;
this._styleElement = document.createElement('link');
this._styleElement.setAttribute('rel', 'stylesheet');
this._styleElement.setAttribute('href', stylesheet);
this._styleElement.rel = 'stylesheet';
this._styleElement.href = stylesheet;
},
'observeStylesheet',
);

View File

@@ -1,6 +1,10 @@
import type { UmbBlockGridLayoutModel, UmbBlockGridTypeModel } from '../types.js';
import type { UmbBlockGridWorkspaceData } from '../index.js';
import { UmbArrayState, appendToFrozenArray, pushAtToUniqueArray } from '@umbraco-cms/backoffice/observable-api';
import { removeInitialSlashFromPath, transformServerPathToClientPath } from '@umbraco-cms/backoffice/utils';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import { type UmbBlockDataType, UmbBlockManagerContext } from '@umbraco-cms/backoffice/block';
import type { UmbBlockTypeGroup } from '@umbraco-cms/backoffice/block-type';
@@ -13,17 +17,34 @@ export class UmbBlockGridManagerContext<
BlockLayoutType extends UmbBlockGridLayoutModel = UmbBlockGridLayoutModel,
> extends UmbBlockManagerContext<UmbBlockGridTypeModel, UmbBlockGridLayoutModel> {
//
#initAppUrl: Promise<void>;
#appUrl?: string;
#blockGroups = new UmbArrayState(<Array<UmbBlockTypeGroup>>[], (x) => x.key);
public readonly blockGroups = this.#blockGroups.asObservable();
layoutStylesheet = this._editorConfiguration.asObservablePart(
(x) => (x?.getValueByAlias('layoutStylesheet') as string) ?? UMB_BLOCK_GRID_DEFAULT_LAYOUT_STYLESHEET,
);
layoutStylesheet = this._editorConfiguration.asObservablePart((x) => {
if (!x) return undefined;
const layoutStylesheet = x.getValueByAlias<string>('layoutStylesheet');
if (!layoutStylesheet) return UMB_BLOCK_GRID_DEFAULT_LAYOUT_STYLESHEET;
if (layoutStylesheet) {
// Cause we await initAppUrl in setting the _editorConfiguration, we can trust the appUrl begin here.
return this.#appUrl! + removeInitialSlashFromPath(transformServerPathToClientPath(layoutStylesheet));
}
return undefined;
});
gridColumns = this._editorConfiguration.asObservablePart((x) => {
const value = x?.getValueByAlias('gridColumns') as string | undefined;
return parseInt(value && value !== '' ? value : '12');
});
override setEditorConfiguration(configs: UmbPropertyEditorConfigCollection) {
this.#initAppUrl.then(() => {
// we await initAppUrl, So the appUrl begin here is available when retrieving the layoutStylesheet.
this._editorConfiguration.setValue(configs);
});
}
setBlockGroups(blockGroups: Array<UmbBlockTypeGroup>) {
this.#blockGroups.setValue(blockGroups);
}
@@ -31,6 +52,14 @@ export class UmbBlockGridManagerContext<
return this.#blockGroups.value;
}
constructor(host: UmbControllerHost) {
super(host);
this.#initAppUrl = this.getContext(UMB_APP_CONTEXT).then((appContext) => {
this.#appUrl = appContext.getServerUrl() + appContext.getBackofficePath();
});
}
create(
contentElementTypeKey: string,
partialLayoutEntry?: Omit<BlockLayoutType, 'contentUdi'>,

View File

@@ -55,6 +55,12 @@ export const manifests: Array<ManifestTypes> = [
label: 'Layout Stylesheet',
description: 'Override default stylesheet for backoffice layout.',
propertyEditorUiAlias: 'Umb.PropertyEditorUi.BlockGridLayoutStylesheet',
config: [
{
alias: 'singleItemMode',
value: true,
},
],
},
],
},

View File

@@ -1,16 +1,16 @@
import { UmbBlockGridManagerContext } from '../../context/block-grid-manager.context.js';
import { UMB_BLOCK_GRID_PROPERTY_EDITOR_ALIAS } from './manifests.js';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { html, customElement, property, state, css, type PropertyValueMap } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import type { UmbBlockTypeGroup } from '@umbraco-cms/backoffice/block-type';
import type { UmbBlockGridTypeModel, UmbBlockGridValueModel } from '@umbraco-cms/backoffice/block-grid';
import '../../components/block-grid-entries/index.js';
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';
import { UmbBlockGridManagerContext } from '../../context/block-grid-manager.context.js';
import { UMB_BLOCK_GRID_PROPERTY_EDITOR_ALIAS } from './manifests.js';
import type { UmbBlockTypeGroup } from '@umbraco-cms/backoffice/block-type';
import type { UmbBlockGridTypeModel, UmbBlockGridValueModel } from '@umbraco-cms/backoffice/block-grid';
/**
* @element umb-property-editor-ui-block-grid

View File

@@ -3,7 +3,7 @@
import type { UmbInputStaticFileElement } from '@umbraco-cms/backoffice/static-file';
import '@umbraco-cms/backoffice/static-file';
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import {
@@ -11,29 +11,61 @@ import {
type UmbPropertyEditorConfigCollection,
} from '@umbraco-cms/backoffice/property-editor';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbServerFilePathUniqueSerializer } from '@umbraco-cms/backoffice/server-file-system';
import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models';
@customElement('umb-property-editor-ui-block-grid-layout-stylesheet')
export class UmbPropertyEditorUIBlockGridLayoutStylesheetElement
extends UmbLitElement
implements UmbPropertyEditorUiElement
{
private _value: Array<string> = [];
#pickableFilter = (item: any) => item.unique.endsWith('css');
#singleItemMode = false;
// TODO: get rid of UmbServerFilePathUniqueSerializer in v.15 [NL]
#serverFilePathUniqueSerializer = new UmbServerFilePathUniqueSerializer();
@property({ type: Array })
public set value(value: Array<string>) {
this._value = value || [];
}
public get value(): Array<string> {
return this._value;
}
private _pickableFilter = (item: any) => item.unique.endsWith('css');
@state()
private _value?: string | Array<string>;
@property({ attribute: false })
public config?: UmbPropertyEditorConfigCollection;
public set value(value: string | Array<string> | undefined) {
if (Array.isArray(value)) {
this._value = value.map((unique) => this.#serverFilePathUniqueSerializer.toUnique(unique));
} else if (value) {
this._value = this.#serverFilePathUniqueSerializer.toUnique(value);
} else {
this._value = undefined;
}
}
public get value(): string | Array<string> | undefined {
if (Array.isArray(this._value)) {
return this._value.map((unique) => this.#serverFilePathUniqueSerializer.toServerPath(unique) ?? '');
} else if (this._value) {
return this.#serverFilePathUniqueSerializer.toServerPath(this._value) ?? '';
} else {
return undefined;
}
}
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
this.#singleItemMode = config?.getValueByAlias<boolean>('singleItemMode') ?? false;
const validationLimit = config?.getValueByAlias<UmbNumberRangeValueType>('validationLimit');
this._limitMin = validationLimit?.min ?? 0;
this._limitMax = this.#singleItemMode ? 1 : validationLimit?.max ?? Infinity;
}
@state()
private _limitMin: number = 0;
@state()
private _limitMax: number = Infinity;
private _onChange(event: CustomEvent) {
this.value = (event.target as UmbInputStaticFileElement).selection;
if (this.#singleItemMode) {
this._value = (event.target as UmbInputStaticFileElement).selection[0];
} else {
this._value = (event.target as UmbInputStaticFileElement).selection;
}
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
@@ -42,10 +74,10 @@ export class UmbPropertyEditorUIBlockGridLayoutStylesheetElement
return html`
<umb-input-static-file
@change=${this._onChange}
.pickableFilter=${this._pickableFilter}
.selection=${this._value}
.min=${0}
.max=${1}></umb-input-static-file>
.pickableFilter=${this.#pickableFilter}
.selection=${this._value ? (Array.isArray(this._value) ? this._value : [this._value]) : []}
.min=${this._limitMin}
.max=${this._limitMax}></umb-input-static-file>
<br />
<a href="/umbraco/backoffice/assets/css/umbraco-blockgridlayout.css">Link to default layout stylesheet</a>
`;

View File

@@ -8,14 +8,6 @@ export class UmbBlockGridTypeWorkspaceViewAdvancedElement extends UmbLitElement
override render() {
return html`
<uui-box headline="Advanced">
<umb-property
label="Custom view"
alias="view"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"></umb-property>
<umb-property
label="Custom stylesheet"
alias="stylesheet"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"></umb-property>
<umb-property
label="Overlay size"
alias="editorSize"
@@ -41,7 +33,13 @@ export class UmbBlockGridTypeWorkspaceViewAdvancedElement extends UmbLitElement
<umb-property
label="Thumbnail"
alias="thumbnail"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"></umb-property>
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"
.config=${[
{
alias: 'singleItemMode',
value: true,
},
]}></umb-property>
</uui-box>
`;
}

View File

@@ -12,14 +12,6 @@ export class UmbBlockListTypeWorkspaceViewSettingsElement extends UmbLitElement
label="Label"
alias="label"
property-editor-ui-alias="Umb.PropertyEditorUi.TextBox"></umb-property>
<!--<umb-property
label="Custom view"
alias="view"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"></umb-property>
<umb-property
label="Custom stylesheet"
alias="stylesheet"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"></umb-property>-->
<umb-property
label="Overlay size"
alias="editorSize"
@@ -67,9 +59,15 @@ export class UmbBlockListTypeWorkspaceViewSettingsElement extends UmbLitElement
alias="iconColor"
property-editor-ui-alias="Umb.PropertyEditorUi.TextBox"></umb-property>
<umb-property
label="Custom stylesheet"
alias="stylesheet"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"></umb-property>
label="Thumbnail"
alias="thumbnail"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"
.config=${[
{
alias: 'singleItemMode',
value: true,
},
]}></umb-property>
</uui-box>
<uui-box headline="Advanced">
<umb-property

View File

@@ -63,9 +63,15 @@ export class UmbBlockRteTypeWorkspaceViewSettingsElement extends UmbLitElement i
alias="iconColor"
property-editor-ui-alias="Umb.PropertyEditorUi.TextBox"></umb-property>
<umb-property
label="Custom stylesheet"
alias="stylesheet"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"></umb-property>
label="Thumbnail"
alias="thumbnail"
property-editor-ui-alias="Umb.PropertyEditorUi.StaticFilePicker"
.config=${[
{
alias: 'singleItemMode',
value: true,
},
]}></umb-property>
</uui-box>
`;
}

View File

@@ -5,10 +5,15 @@ import {
import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
import { UmbRepositoryItemsManager } from '@umbraco-cms/backoffice/repository';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app';
import { removeInitialSlashFromPath, transformServerPathToClientPath } from '@umbraco-cms/backoffice/utils';
@customElement('umb-block-type-card')
export class UmbBlockTypeCardElement extends UmbLitElement {
//
#init: Promise<void>;
#appUrl?: string;
#itemManager = new UmbRepositoryItemsManager<UmbDocumentTypeItemModel>(
this,
UMB_DOCUMENT_TYPE_ITEM_REPOSITORY_ALIAS,
@@ -19,7 +24,22 @@ export class UmbBlockTypeCardElement extends UmbLitElement {
href?: string;
@property({ type: String, attribute: false })
iconFile?: string;
public set iconFile(value: string) {
value = transformServerPathToClientPath(value);
if (value) {
this.#init.then(() => {
this._iconFile = this.#appUrl + removeInitialSlashFromPath(value);
});
} else {
this._iconFile = undefined;
}
}
public get iconFile(): string | undefined {
return this._iconFile;
}
@state()
private _iconFile?: string | undefined;
@property({ type: String, attribute: false })
iconColor?: string;
@@ -55,6 +75,10 @@ export class UmbBlockTypeCardElement extends UmbLitElement {
constructor() {
super();
this.#init = this.getContext(UMB_APP_CONTEXT).then((appContext) => {
this.#appUrl = appContext.getServerUrl() + appContext.getBackofficePath();
});
this.observe(this.#itemManager.items, (items) => {
const item = items[0];
if (item) {
@@ -73,8 +97,8 @@ export class UmbBlockTypeCardElement extends UmbLitElement {
.name=${this._name ?? 'Unknown'}
.description=${this._description}
.background=${this.backgroundColor}>
${this.iconFile
? html`<img src=${this.iconFile} alt="" />`
${this._iconFile
? html`<img src=${this._iconFile} alt="" />`
: html`<umb-icon name=${this._fallbackIcon ?? ''} style="color:${this.iconColor}"></umb-icon>`}
<slot name="actions" slot="actions"> </slot>
</uui-card-block-type>

View File

@@ -145,8 +145,6 @@ export class UmbInputBlockTypeElement<
#renderItem = (block: BlockType) => {
return html`
<umb-block-type-card
.data-umb-content-element-key=${block.contentElementTypeKey}
.name=${block.label}
.iconFile=${block.thumbnail}
.iconColor=${block.iconColor}
.backgroundColor=${block.backgroundColor}

View File

@@ -124,6 +124,7 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
(block) => block.contentElementTypeKey,
(block) => html`
<umb-block-type-card
.iconFile=${block.thumbnail}
.iconColor=${block.iconColor}
.backgroundColor=${block.backgroundColor}
.contentElementTypeKey=${block.contentElementTypeKey}

View File

@@ -83,11 +83,14 @@ export class UmbInputEntityElement extends UmbFormControlMixin<string | undefine
}
@property({ attribute: false })
public set pickerContext(ctor: new (host: UmbControllerHost) => UmbPickerInputContext<any, any, any, any>) {
public set pickerContext(ctor: (new (host: UmbControllerHost) => UmbPickerInputContext) | undefined) {
if (this.#pickerContext) return;
this.#pickerContext = new ctor(this);
this.#pickerContext = ctor ? new ctor(this) : undefined;
this.#observePickerContext();
}
public get pickerContext(): UmbPickerInputContext | undefined {
return this.#pickerContext;
}
@state()
private _items?: Array<UmbUniqueItemModel>;

View File

@@ -1,6 +1,5 @@
import type { ManifestApi } from '../../../../libs/extension-api/types/index.js';
import type { UmbApi } from '../../../../libs/extension-api/models/api.interface.js';
import { createExtensionApiByAlias } from './create-extension-api-by-alias.function.js';
import type { ManifestApi, UmbApi } from '@umbraco-cms/backoffice/extension-api';
import { expect, fixture } from '@open-wc/testing';
import { customElement, html } from '@umbraco-cms/backoffice/external/lit';
import { UmbControllerHostElementMixin } from '@umbraco-cms/backoffice/controller-api';
@@ -54,15 +53,16 @@ describe('Create Extension Api By Alias Method', () => {
};
umbExtensionsRegistry.register(manifest);
createExtensionApiByAlias<UmbExtensionApiBoolTestClass>(hostElement, manifest.alias, []).then(() => {
umbExtensionsRegistry.unregister(manifest.alias);
done(new Error('Should not resolve'));
});
setTimeout(() => {
umbExtensionsRegistry.unregister(manifest.alias);
done();
}, 10);
createExtensionApiByAlias<UmbExtensionApiBoolTestClass>(hostElement, manifest.alias, []).then(
() => {
umbExtensionsRegistry.unregister(manifest.alias);
done(new Error('Should not resolve'));
},
() => {
umbExtensionsRegistry.unregister(manifest.alias);
done();
},
);
});
it('Handles when `api` property contains a class constructor', async () => {

View File

@@ -1,9 +1,15 @@
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbSectionSidebarContext } from './section-sidebar.context.js';
@customElement('umb-section-sidebar')
export class UmbSectionSidebarElement extends UmbLitElement {
constructor() {
super();
new UmbSectionSidebarContext(this);
}
override render() {
return html`
<umb-section-sidebar-context-menu>

View File

@@ -3,14 +3,14 @@ import { UMB_TREE_CONTEXT, type UmbDefaultTreeContext } from '../../default/inde
import type { UmbTreeItemModel, UmbTreeRootModel } from '../../types.js';
import { UmbRequestReloadTreeItemChildrenEvent } from '../../entity-actions/reload-tree-item-children/index.js';
import { map } from '@umbraco-cms/backoffice/external/rxjs';
import { UMB_SECTION_CONTEXT, UMB_SECTION_SIDEBAR_CONTEXT } from '@umbraco-cms/backoffice/section';
import type { UmbSectionContext, UmbSectionSidebarContext } from '@umbraco-cms/backoffice/section';
import type { ManifestTreeItem } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { UmbArrayState, UmbBooleanState, UmbObjectState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UMB_SECTION_CONTEXT, UMB_SECTION_SIDEBAR_CONTEXT } from '@umbraco-cms/backoffice/section';
import type { UmbSectionContext, UmbSectionSidebarContext } from '@umbraco-cms/backoffice/section';
import type { ManifestTreeItem } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { UMB_ACTION_EVENT_CONTEXT, type UmbActionEventContext } from '@umbraco-cms/backoffice/action';
import {
UmbRequestReloadChildrenOfEntityEvent,
@@ -407,6 +407,7 @@ export abstract class UmbTreeItemContextBase<
// TODO: use router context
constructPath(pathname: string, entityType: string, unique: string | null) {
// TODO: Encode uniques [NL]
return `section/${pathname}/workspace/${entityType}/edit/${unique}`;
}

View File

@@ -11,7 +11,9 @@ export * from './path/has-own-opener.function.js';
export * from './path/path-decode.function.js';
export * from './path/path-encode.function.js';
export * from './path/path-folder-name.function.js';
export * from './path/remove-initial-slash-from-path.function.js';
export * from './path/stored-path.function.js';
export * from './path/transform-server-path-to-client-path.function.js';
export * from './path/umbraco-path.function.js';
export * from './path/url-pattern-to-string.function.js';
export * from './selection-manager/selection.manager.js';

View File

@@ -1 +1,2 @@
export const decodeFilePath = (unique: string) => decodeURIComponent(unique.replace('-', '.'));
// Notice, no need to handle . or : specifically as decodeURIComponent does handle these. [NL]
export const decodeFilePath = (path: string) => decodeURIComponent(path);

View File

@@ -1,3 +1,3 @@
export const encodeFilePath = (path: string) => encodeURIComponent(path).replaceAll('.', '-');
export const encodeFilePath = (path: string) => encodeURIComponent(path).replaceAll('.', '%2E').replaceAll(':', '%3A');
export const aliasToPath = (path: string) => encodeFilePath(path);

View File

@@ -0,0 +1,3 @@
export function removeInitialSlashFromPath(path: string) {
return path.startsWith('/') ? path.slice(1) : path;
}

View File

@@ -0,0 +1,11 @@
type StringMaybeUndefined = string | undefined;
export function transformServerPathToClientPath<T extends StringMaybeUndefined>(path: T): T {
if (path?.indexOf('~/') === 0) {
path = path.slice(1) as T;
}
if (path?.indexOf('/wwwroot/') === 0) {
path = path.slice(8) as T;
}
return path;
}

View File

@@ -1,9 +1,9 @@
import { UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE } from '../../entity.js';
import { UMB_DOCUMENT_BLUEPRINT_OPTIONS_CREATE_MODAL } from './modal/index.js';
import type { UmbEntityActionArgs } from '@umbraco-cms/backoffice/entity-action';
import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE } from '../../entity.js';
import { UMB_DOCUMENT_BLUEPRINT_OPTIONS_CREATE_MODAL } from './modal/index.js';
export class UmbCreateDocumentBlueprintEntityAction extends UmbEntityActionBase<never> {
constructor(host: UmbControllerHost, args: UmbEntityActionArgs<never>) {

View File

@@ -0,0 +1 @@
export const UMB_IMAGING_REPOSITORY_ALIAS = 'Umb.Repository.Imaging';

View File

@@ -40,3 +40,5 @@ export class UmbImagingRepository extends UmbControllerBase implements UmbApi {
return await this.requestResizedItems(uniques, imagingModel);
}
}
export { UmbImagingRepository as api };

View File

@@ -1,2 +1,2 @@
export { UmbImagingRepository } from './imaging.repository.js';
export { UMB_IMAGING_REPOSITORY_ALIAS } from './manifests.js';
export { UMB_IMAGING_REPOSITORY_ALIAS } from './constants.js';

View File

@@ -1,13 +1,11 @@
import { UmbImagingRepository } from './imaging.repository.js';
import { UMB_IMAGING_REPOSITORY_ALIAS } from './constants.js';
import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const UMB_IMAGING_REPOSITORY_ALIAS = 'Umb.Repository.Imaging';
const repository: ManifestRepository = {
type: 'repository',
alias: UMB_IMAGING_REPOSITORY_ALIAS,
name: 'Imaging Repository',
api: UmbImagingRepository,
api: () => import('./imaging.repository.js'),
};
export const manifests: Array<ManifestTypes> = [repository];

View File

@@ -1,5 +1,5 @@
import { manifests as mediaManifests } from './media/manifests.js';
import { manifests as mediaSectionManifests } from './section.manifests.js';
import { manifests as mediaSectionManifests } from './media-section/manifests.js';
import { manifests as mediaTypesManifests } from './media-types/manifests.js';
import { manifests as imagingManifests } from './imaging/manifests.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';

View File

@@ -0,0 +1 @@
export const UMB_MEDIA_SECTION_ALIAS = 'Umb.Section.Media';

View File

@@ -1,4 +1,4 @@
import { UMB_MEDIA_ROOT_ENTITY_TYPE, UMB_MEDIA_MENU_ALIAS } from './media/index.js';
import { UMB_MEDIA_ROOT_ENTITY_TYPE, UMB_MEDIA_MENU_ALIAS } from '../media/index.js';
import type {
ManifestSection,
ManifestSectionSidebarApp,

View File

@@ -23,3 +23,5 @@ export class UmbCreateMediaTypeEntityAction extends UmbEntityActionBase<never> {
await modalContext.onSubmit();
}
}
export { UmbCreateMediaTypeEntityAction as api };

View File

@@ -3,7 +3,6 @@ import {
UMB_MEDIA_TYPE_FOLDER_ENTITY_TYPE,
UMB_MEDIA_TYPE_ROOT_ENTITY_TYPE,
} from '../../entity.js';
import { UmbCreateMediaTypeEntityAction } from './create.action.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
const entityActions: Array<ManifestTypes> = [
@@ -13,7 +12,7 @@ const entityActions: Array<ManifestTypes> = [
alias: 'Umb.EntityAction.MediaType.Create',
name: 'Create Media Type Entity Action',
weight: 1200,
api: UmbCreateMediaTypeEntityAction,
api: () => import('./create.action.js'),
forEntityTypes: [UMB_MEDIA_TYPE_ENTITY_TYPE, UMB_MEDIA_TYPE_ROOT_ENTITY_TYPE, UMB_MEDIA_TYPE_FOLDER_ENTITY_TYPE],
meta: {
icon: 'icon-add',

View File

@@ -1,12 +1,11 @@
import { UMB_DUPLICATE_MEDIA_TYPE_REPOSITORY_ALIAS } from './constants.js';
import { UmbDuplicateMediaTypeRepository } from './media-type-duplicate.repository.js';
import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
const duplicateRepository: ManifestRepository = {
type: 'repository',
alias: UMB_DUPLICATE_MEDIA_TYPE_REPOSITORY_ALIAS,
name: 'Duplicate Media Type Repository',
api: UmbDuplicateMediaTypeRepository,
api: () => import('./media-type-duplicate.repository.js'),
};
export const manifests: Array<ManifestTypes> = [duplicateRepository];

View File

@@ -18,3 +18,5 @@ export class UmbDuplicateMediaTypeRepository extends UmbRepositoryBase implement
return { error };
}
}
export { UmbDuplicateMediaTypeRepository as api };

View File

@@ -1,12 +1,11 @@
import { UMB_MOVE_MEDIA_TYPE_REPOSITORY_ALIAS } from './constants.js';
import { UmbMoveMediaTypeRepository } from './media-type-move.repository.js';
import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
const moveRepository: ManifestRepository = {
type: 'repository',
alias: UMB_MOVE_MEDIA_TYPE_REPOSITORY_ALIAS,
name: 'Move Media Type Repository',
api: UmbMoveMediaTypeRepository,
api: () => import('./media-type-move.repository.js'),
};
export const manifests: Array<ManifestTypes> = [moveRepository];

View File

@@ -18,3 +18,5 @@ export class UmbMoveMediaTypeRepository extends UmbRepositoryBase implements Umb
return { error };
}
}
export { UmbMoveMediaTypeRepository as api };

View File

@@ -0,0 +1,2 @@
export const UMB_MEDIA_TYPE_DETAIL_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Detail';
export const UMB_MEDIA_TYPE_DETAIL_STORE_ALIAS = 'Umb.Store.MediaType.Detail';

View File

@@ -1,3 +1,3 @@
export { UmbMediaTypeDetailRepository } from './media-type-detail.repository.js';
export { UMB_MEDIA_TYPE_DETAIL_REPOSITORY_ALIAS, UMB_MEDIA_TYPE_DETAIL_STORE_ALIAS } from './manifests.js';
export { UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT } from './media-type-detail.store.js';
export { UMB_MEDIA_TYPE_DETAIL_REPOSITORY_ALIAS, UMB_MEDIA_TYPE_DETAIL_STORE_ALIAS } from './constants.js';
export { UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT } from './media-type-detail.store.context-token.js';

View File

@@ -1,8 +1,6 @@
import { UMB_MEDIA_TYPE_DETAIL_REPOSITORY_ALIAS, UMB_MEDIA_TYPE_DETAIL_STORE_ALIAS } from './constants.js';
import type { ManifestRepository, ManifestStore, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const UMB_MEDIA_TYPE_DETAIL_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Detail';
export const UMB_MEDIA_TYPE_DETAIL_STORE_ALIAS = 'Umb.Store.MediaType.Detail';
const detailRepository: ManifestRepository = {
type: 'repository',
alias: UMB_MEDIA_TYPE_DETAIL_REPOSITORY_ALIAS,

View File

@@ -1,6 +1,6 @@
import type { UmbMediaTypeDetailModel } from '../../types.js';
import { UmbMediaTypeServerDataSource } from './media-type-detail.server.data-source.js';
import { UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT } from './media-type-detail.store.js';
import { UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT } from './media-type-detail.store.context-token.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbDetailRepositoryBase } from '@umbraco-cms/backoffice/repository';
export class UmbMediaTypeDetailRepository extends UmbDetailRepositoryBase<UmbMediaTypeDetailModel> {

View File

@@ -0,0 +1,6 @@
import type UmbMediaTypeDetailStore from './media-type-detail.store.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
export const UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT = new UmbContextToken<UmbMediaTypeDetailStore>(
'UmbMediaTypeDetailStore',
);

View File

@@ -1,5 +1,5 @@
import type { UmbMediaTypeDetailModel } from '../../types.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT } from './media-type-detail.store.context-token.js';
import { UmbDetailStoreBase } from '@umbraco-cms/backoffice/store';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@@ -21,7 +21,3 @@ export class UmbMediaTypeDetailStore extends UmbDetailStoreBase<UmbMediaTypeDeta
}
export default UmbMediaTypeDetailStore;
export const UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT = new UmbContextToken<UmbMediaTypeDetailStore>(
'UmbMediaTypeDetailStore',
);

View File

@@ -0,0 +1,2 @@
export const UMB_MEDIA_TYPE_ITEM_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Item';
export const UMB_MEDIA_TYPE_ITEM_STORE_ALIAS = 'Umb.Store.MediaType.Item';

View File

@@ -1,4 +1,4 @@
export { UmbMediaTypeItemRepository } from './media-type-item.repository.js';
export { UMB_MEDIA_TYPE_ITEM_REPOSITORY_ALIAS, UMB_MEDIA_TYPE_ITEM_STORE_ALIAS } from './manifests.js';
export { UMB_MEDIA_TYPE_ITEM_STORE_CONTEXT } from './media-type-item.store.js';
export { UMB_MEDIA_TYPE_ITEM_REPOSITORY_ALIAS, UMB_MEDIA_TYPE_ITEM_STORE_ALIAS } from './constants.js';
export { UMB_MEDIA_TYPE_ITEM_STORE_CONTEXT } from './media-type-item.store.context-token.js';
export type { UmbMediaTypeItemModel } from './types.js';

View File

@@ -1,8 +1,6 @@
import { UMB_MEDIA_TYPE_ITEM_REPOSITORY_ALIAS, UMB_MEDIA_TYPE_ITEM_STORE_ALIAS } from './constants.js';
import type { ManifestItemStore, ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const UMB_MEDIA_TYPE_ITEM_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Item';
export const UMB_MEDIA_TYPE_ITEM_STORE_ALIAS = 'Umb.Store.MediaType.Item';
const itemRepository: ManifestRepository = {
type: 'repository',
alias: UMB_MEDIA_TYPE_ITEM_REPOSITORY_ALIAS,

View File

@@ -1,6 +1,6 @@
import type { UmbMediaTypeItemModel } from './types.js';
import { UmbMediaTypeItemServerDataSource } from './media-type-item.server.data-source.js';
import { UMB_MEDIA_TYPE_ITEM_STORE_CONTEXT } from './media-type-item.store.js';
import { UMB_MEDIA_TYPE_ITEM_STORE_CONTEXT } from './media-type-item.store.context-token.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbItemRepositoryBase } from '@umbraco-cms/backoffice/repository';

View File

@@ -0,0 +1,4 @@
import type UmbMediaTypeItemStore from './media-type-item.store.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
export const UMB_MEDIA_TYPE_ITEM_STORE_CONTEXT = new UmbContextToken<UmbMediaTypeItemStore>('UmbMediaTypeItemStore');

View File

@@ -1,5 +1,5 @@
import { UMB_MEDIA_TYPE_ITEM_STORE_CONTEXT } from './media-type-item.store.context-token.js';
import type { UmbMediaTypeItemModel } from './index.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbItemStoreBase } from '@umbraco-cms/backoffice/store';
@@ -22,5 +22,3 @@ export class UmbMediaTypeItemStore extends UmbItemStoreBase<UmbMediaTypeItemMode
}
export default UmbMediaTypeItemStore;
export const UMB_MEDIA_TYPE_ITEM_STORE_CONTEXT = new UmbContextToken<UmbMediaTypeItemStore>('UmbMediaTypeItemStore');

View File

@@ -0,0 +1 @@
export const UMB_MEDIA_TYPE_STRUCTURE_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Structure';

View File

@@ -1,3 +1,3 @@
export { UmbMediaTypeStructureRepository } from './media-type-structure.repository.js';
export { UMB_MEDIA_TYPE_STRUCTURE_REPOSITORY_ALIAS } from './manifests.js';
export { UMB_MEDIA_TYPE_STRUCTURE_REPOSITORY_ALIAS } from './constants.js';
export * from './types.js';

View File

@@ -1,7 +1,6 @@
import { UMB_MEDIA_TYPE_STRUCTURE_REPOSITORY_ALIAS } from './constants.js';
import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const UMB_MEDIA_TYPE_STRUCTURE_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Structure';
const structureRepository: ManifestRepository = {
type: 'repository',
alias: UMB_MEDIA_TYPE_STRUCTURE_REPOSITORY_ALIAS,

View File

@@ -0,0 +1,3 @@
export const UMB_MEDIA_TYPE_TREE_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Tree';
export const UMB_MEDIA_TYPE_TREE_STORE_ALIAS = 'Umb.Store.MediaType.Tree';
export const UMB_MEDIA_TYPE_TREE_ALIAS = 'Umb.Tree.MediaType';

View File

@@ -0,0 +1 @@
export const UMB_MEDIA_TYPE_FOLDER_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Folder';

View File

@@ -1,2 +1,2 @@
export { UmbMediaTypeFolderRepository } from './media-type-folder.repository.js';
export { UMB_MEDIA_TYPE_FOLDER_REPOSITORY_ALIAS } from './manifests.js';
export { UMB_MEDIA_TYPE_FOLDER_REPOSITORY_ALIAS } from './constants.js';

View File

@@ -1,12 +1,11 @@
import { UMB_MEDIA_TYPE_FOLDER_ENTITY_TYPE } from '../../entity.js';
import { UMB_MEDIA_TYPE_FOLDER_REPOSITORY_ALIAS } from './constants.js';
import type {
ManifestEntityAction,
ManifestRepository,
ManifestTypes,
} from '@umbraco-cms/backoffice/extension-registry';
export const UMB_MEDIA_TYPE_FOLDER_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Folder';
const folderRepository: ManifestRepository = {
type: 'repository',
alias: UMB_MEDIA_TYPE_FOLDER_REPOSITORY_ALIAS,

View File

@@ -2,10 +2,10 @@ export {
UMB_MEDIA_TYPE_TREE_ALIAS,
UMB_MEDIA_TYPE_TREE_STORE_ALIAS,
UMB_MEDIA_TYPE_TREE_REPOSITORY_ALIAS,
} from './manifests.js';
} from './constants.js';
export * from './folder/index.js';
export { UmbMediaTypeTreeRepository } from './media-type-tree.repository.js';
export { UMB_MEDIA_TYPE_TREE_STORE_CONTEXT } from './media-type-tree.store.js';
export { UMB_MEDIA_TYPE_TREE_STORE_CONTEXT } from './media-type-tree.store.context-token.js';
export { UMB_MEDIA_TYPE_PICKER_MODAL } from './media-type-picker-modal.token.js';
export type { UmbMediaTypeTreeItemModel, UmbMediaTypeTreeRootModel } from './types.js';

View File

@@ -3,6 +3,11 @@ import {
UMB_MEDIA_TYPE_ROOT_ENTITY_TYPE,
UMB_MEDIA_TYPE_FOLDER_ENTITY_TYPE,
} from '../entity.js';
import {
UMB_MEDIA_TYPE_TREE_ALIAS,
UMB_MEDIA_TYPE_TREE_REPOSITORY_ALIAS,
UMB_MEDIA_TYPE_TREE_STORE_ALIAS,
} from './constants.js';
import { manifests as folderManifests } from './folder/manifests.js';
import { manifests as reloadTreeItemChildrenManifest } from './reload-tree-item-children/manifests.js';
import type {
@@ -13,10 +18,6 @@ import type {
ManifestTypes,
} from '@umbraco-cms/backoffice/extension-registry';
export const UMB_MEDIA_TYPE_TREE_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Tree';
export const UMB_MEDIA_TYPE_TREE_STORE_ALIAS = 'Umb.Store.MediaType.Tree';
export const UMB_MEDIA_TYPE_TREE_ALIAS = 'Umb.Tree.MediaType';
const treeRepository: ManifestRepository = {
type: 'repository',
alias: UMB_MEDIA_TYPE_TREE_REPOSITORY_ALIAS,

View File

@@ -1,6 +1,6 @@
import { UMB_MEDIA_TYPE_ROOT_ENTITY_TYPE } from '../entity.js';
import { UmbMediaTypeTreeServerDataSource } from './media-type-tree.server.data-source.js';
import { UMB_MEDIA_TYPE_TREE_STORE_CONTEXT } from './media-type-tree.store.js';
import { UMB_MEDIA_TYPE_TREE_STORE_CONTEXT } from './media-type-tree.store.context-token.js';
import type { UmbMediaTypeTreeItemModel, UmbMediaTypeTreeRootModel } from './types.js';
import { UmbTreeRepositoryBase } from '@umbraco-cms/backoffice/tree';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';

View File

@@ -0,0 +1,4 @@
import type UmbMediaTypeTreeStore from './media-type-tree.store.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
export const UMB_MEDIA_TYPE_TREE_STORE_CONTEXT = new UmbContextToken<UmbMediaTypeTreeStore>('UmbMediaTypeTreeStore');

View File

@@ -1,4 +1,4 @@
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UMB_MEDIA_TYPE_TREE_STORE_CONTEXT } from './media-type-tree.store.context-token.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbUniqueTreeStore } from '@umbraco-cms/backoffice/tree';
@@ -20,5 +20,3 @@ export class UmbMediaTypeTreeStore extends UmbUniqueTreeStore {
}
export default UmbMediaTypeTreeStore;
export const UMB_MEDIA_TYPE_TREE_STORE_CONTEXT = new UmbContextToken<UmbMediaTypeTreeStore>('UmbMediaTypeTreeStore');

View File

@@ -0,0 +1 @@
export const UMB_MEDIA_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.MediaType';

View File

@@ -1,3 +1,4 @@
import { UMB_MEDIA_TYPE_WORKSPACE_ALIAS } from './constants.js';
import type {
ManifestWorkspaces,
ManifestWorkspaceActions,
@@ -7,8 +8,6 @@ import type {
import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace';
export const UMB_MEDIA_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.MediaType';
const workspace: ManifestWorkspaces = {
type: 'workspace',
kind: 'routable',

View File

@@ -2,7 +2,6 @@ import { UMB_MEDIA_COLLECTION_REPOSITORY_ALIAS } from './repository/index.js';
import { manifests as collectionActionManifests } from './action/manifests.js';
import { manifests as collectionRepositoryManifests } from './repository/manifests.js';
import { manifests as collectionViewManifests } from './views/manifests.js';
import { UmbMediaCollectionContext } from './media-collection.context.js';
import { UMB_MEDIA_COLLECTION_ALIAS } from './index.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
@@ -10,7 +9,7 @@ const collectionManifest: ManifestTypes = {
type: 'collection',
alias: UMB_MEDIA_COLLECTION_ALIAS,
name: 'Media Collection',
api: UmbMediaCollectionContext,
api: () => import('./media-collection.context.js'),
element: () => import('./media-collection.element.js'),
meta: {
repositoryAlias: UMB_MEDIA_COLLECTION_REPOSITORY_ALIAS,

View File

@@ -36,3 +36,5 @@ export class UmbMediaCollectionContext extends UmbDefaultCollectionContext<
});
}
}
export { UmbMediaCollectionContext as api };

View File

@@ -1,6 +1,6 @@
import type { UmbImageCropperPropertyEditorValue } from './types.js';
import type { UmbInputImageCropperFieldElement } from './image-cropper-field.element.js';
import { html, customElement, property, query, state } from '@umbraco-cms/backoffice/external/lit';
import { html, customElement, property, query, state, css } from '@umbraco-cms/backoffice/external/lit';
import type { UUIFileDropzoneElement, UUIFileDropzoneEvent } from '@umbraco-cms/backoffice/external/uui';
import { UmbId } from '@umbraco-cms/backoffice/id';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
@@ -61,8 +61,9 @@ export class UmbInputImageCropperElement extends UmbLitElement {
this.dispatchEvent(new UmbChangeEvent());
}
#onBrowse() {
#onBrowse(e: Event) {
if (!this._dropzone) return;
e.stopImmediatePropagation();
this._dropzone.browse();
}
@@ -105,7 +106,7 @@ export class UmbInputImageCropperElement extends UmbLitElement {
#renderDropzone() {
return html`
<uui-file-dropzone id="dropzone" label="dropzone" @change="${this.#onUpload}">
<uui-file-dropzone id="dropzone" label="dropzone" @change="${this.#onUpload}" @click=${this.#onBrowse}>
<uui-button label=${this.localize.term('media_clickToUpload')} @click="${this.#onBrowse}"></uui-button>
</uui-file-dropzone>
`;
@@ -131,6 +132,22 @@ export class UmbInputImageCropperElement extends UmbLitElement {
</uui-button>
</umb-image-cropper-field> `;
}
static override styles = [
css`
uui-file-dropzone {
position: relative;
display: block;
}
uui-file-dropzone::after {
content: '';
position: absolute;
inset: 0;
cursor: pointer;
border: 1px dashed var(--uui-color-divider-emphasis);
}
`,
];
}
declare global {

View File

@@ -86,8 +86,9 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
}
}
#handleBrowse() {
#handleBrowse(e: Event) {
if (!this._dropzone) return;
e.stopImmediatePropagation();
this._dropzone.browse();
}
@@ -98,6 +99,7 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
#renderDropzone() {
return html`
<uui-file-dropzone
@click=${this.#handleBrowse}
id="dropzone"
label="dropzone"
@change="${this.#onUpload}"
@@ -195,8 +197,17 @@ export class UmbInputUploadFieldElement extends UmbLitElement {
}
uui-file-dropzone {
position: relative;
display: block;
padding: 3px; /** Dropzone background is blurry and covers slightly into other elements. Hack to avoid this */
}
uui-file-dropzone::after {
content: '';
position: absolute;
inset: 0;
cursor: pointer;
border: 1px dashed var(--uui-color-divider-emphasis);
}
`,
];
}

View File

@@ -33,3 +33,5 @@ export class UmbCreateMediaEntityAction extends UmbEntityActionBase<never> {
await modalContext.onSubmit();
}
}
export { UmbCreateMediaEntityAction as api };

View File

@@ -10,7 +10,7 @@ const entityActions: Array<ManifestTypes> = [
alias: 'Umb.EntityAction.Media.Create',
name: 'Create Media Entity Action',
weight: 1200,
api: UmbCreateMediaEntityAction,
api: () => import('./create.action.js'),
forEntityTypes: [UMB_MEDIA_ROOT_ENTITY_TYPE, UMB_MEDIA_ENTITY_TYPE],
meta: {
icon: 'icon-add',

View File

@@ -1,12 +1,11 @@
import { UMB_MOVE_MEDIA_REPOSITORY_ALIAS } from './constants.js';
import { UmbMoveMediaRepository } from './media-move.repository.js';
import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
const moveRepository: ManifestRepository = {
type: 'repository',
alias: UMB_MOVE_MEDIA_REPOSITORY_ALIAS,
name: 'Move Media Repository',
api: UmbMoveMediaRepository,
api: () => import('./media-move.repository.js'),
};
export const manifests: Array<ManifestTypes> = [moveRepository];

View File

@@ -18,3 +18,5 @@ export class UmbMoveMediaRepository extends UmbRepositoryBase implements UmbMove
return { error };
}
}
export { UmbMoveMediaRepository as api };

View File

@@ -31,3 +31,5 @@ export class UmbMediaDeleteEntityBulkAction extends UmbEntityBulkActionBase<obje
*/
}
}
export { UmbMediaDeleteEntityBulkAction as api };

View File

@@ -5,3 +5,5 @@ export class UmbDuplicateMediaEntityBulkAction extends UmbEntityBulkActionBase<o
console.log('execute bulk duplicate');
}
}
export { UmbDuplicateMediaEntityBulkAction as api };

View File

@@ -1,7 +1,4 @@
import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/index.js';
import { UmbMediaMoveEntityBulkAction } from './move/move.action.js';
import { UmbDuplicateMediaEntityBulkAction } from './duplicate/duplicate.action.js';
import { UmbMediaDeleteEntityBulkAction } from './delete/delete.action.js';
import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
import {
@@ -15,7 +12,7 @@ export const manifests: Array<ManifestTypes> = [
alias: 'Umb.EntityBulkAction.Media.Duplicate',
name: 'Duplicate Media Entity Bulk Action',
weight: 30,
api: UmbDuplicateMediaEntityBulkAction,
api: () => import('./duplicate/duplicate.action.js'),
meta: {
label: 'Duplicate',
},
@@ -35,7 +32,7 @@ export const manifests: Array<ManifestTypes> = [
alias: 'Umb.EntityBulkAction.Media.MoveTo',
name: 'Move Media Entity Bulk Action',
weight: 20,
api: UmbMediaMoveEntityBulkAction,
api: () => import('./move/move.action.js'),
meta: {
label: 'Move',
},
@@ -55,7 +52,7 @@ export const manifests: Array<ManifestTypes> = [
alias: 'Umb.EntityBulkAction.Media.Delete',
name: 'Delete Media Entity Bulk Action',
weight: 10,
api: UmbMediaDeleteEntityBulkAction,
api: () => import('./delete/delete.action.js'),
meta: {
label: 'Delete',
},

View File

@@ -21,3 +21,5 @@ export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase<object
}
}
}
export { UmbMediaMoveEntityBulkAction as api };

View File

@@ -9,7 +9,7 @@ export * from './utils/index.js';
export { UMB_MEDIA_TREE_ALIAS, UMB_MEDIA_TREE_PICKER_MODAL } from './tree/index.js';
export { UMB_MEDIA_COLLECTION_ALIAS } from './collection/index.js';
export { UMB_MEDIA_MENU_ALIAS } from './menu/manifests.js';
export { UMB_MEDIA_MENU_ALIAS } from './menu/index.js';
export { UMB_MEDIA_PICKER_MODAL } from './modals/media-picker/index.js';
export type { UmbMediaTreeItemModel } from './tree/index.js';

View File

@@ -0,0 +1 @@
export const UMB_MEDIA_MENU_ALIAS = 'Umb.Menu.Media';

View File

@@ -0,0 +1 @@
export * from './constants.js';

View File

@@ -1,8 +1,7 @@
import { UMB_MEDIA_TREE_ALIAS } from '../tree/index.js';
import { UMB_MEDIA_MENU_ALIAS } from './constants.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const UMB_MEDIA_MENU_ALIAS = 'Umb.Menu.Media';
export const manifests: Array<ManifestTypes> = [
{
type: 'menu',

View File

@@ -1,4 +1,4 @@
import { UMB_MEDIA_SECTION_PATHNAME } from '../paths.js';
import { UMB_MEDIA_SECTION_PATHNAME } from '../media-section/paths.js';
import { UMB_MEDIA_ENTITY_TYPE, type UmbMediaEntityTypeUnion } from './entity.js';
import { UMB_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/workspace';
import { UmbPathPattern } from '@umbraco-cms/backoffice/router';

View File

@@ -1,4 +1,4 @@
import { UMB_MEDIA_MENU_ALIAS } from '../../menu/manifests.js';
import { UMB_MEDIA_MENU_ALIAS } from '../../menu/index.js';
import { UMB_MEDIA_RECYCLE_BIN_TREE_ALIAS } from '../tree/index.js';
import type { ManifestMenuItemTreeKind, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';

View File

@@ -4,6 +4,6 @@ export {
UMB_MEDIA_RECYCLE_BIN_TREE_STORE_ALIAS,
UMB_MEDIA_RECYCLE_BIN_TREE_ALIAS,
} from './constants.js';
export { UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT } from './media-recycle-bin-tree.store.js';
export { UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT } from './media-recycle-bin-tree.store.context-token.js';
export { type UmbMediaRecycleBinTreeStore } from './media-recycle-bin-tree.store.js';
export * from './types.js';

View File

@@ -4,8 +4,6 @@ import {
UMB_MEDIA_RECYCLE_BIN_TREE_REPOSITORY_ALIAS,
UMB_MEDIA_RECYCLE_BIN_TREE_STORE_ALIAS,
} from './constants.js';
import { UmbMediaRecycleBinTreeRepository } from './media-recycle-bin-tree.repository.js';
import { UmbMediaRecycleBinTreeStore } from './media-recycle-bin-tree.store.js';
import { manifests as reloadTreeItemChildrenManifests } from './reload-tree-item-children/manifests.js';
import type {
ManifestRepository,
@@ -19,14 +17,14 @@ const treeRepository: ManifestRepository = {
type: 'repository',
alias: UMB_MEDIA_RECYCLE_BIN_TREE_REPOSITORY_ALIAS,
name: 'Media Recycle Bin Tree Repository',
api: UmbMediaRecycleBinTreeRepository,
api: () => import('./media-recycle-bin-tree.repository.js'),
};
const treeStore: ManifestTreeStore = {
type: 'treeStore',
alias: UMB_MEDIA_RECYCLE_BIN_TREE_STORE_ALIAS,
name: 'Media Recycle Bin Tree Store',
api: UmbMediaRecycleBinTreeStore,
api: () => import('./media-recycle-bin-tree.store.js'),
};
const tree: ManifestTree = {

View File

@@ -1,7 +1,7 @@
import { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE } from '../entity.js';
import { UmbMediaRecycleBinTreeServerDataSource } from './media-recycle-bin-tree.server.data-source.js';
import type { UmbMediaRecycleBinTreeItemModel, UmbMediaRecycleBinTreeRootModel } from './types.js';
import { UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT } from './media-recycle-bin-tree.store.js';
import { UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT } from './media-recycle-bin-tree.store.context-token.js';
import { UmbTreeRepositoryBase } from '@umbraco-cms/backoffice/tree';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
@@ -31,3 +31,5 @@ export class UmbMediaRecycleBinTreeRepository
return { data };
}
}
export { UmbMediaRecycleBinTreeRepository as api };

View File

@@ -0,0 +1,6 @@
import type { UmbMediaRecycleBinTreeStore } from './media-recycle-bin-tree.store.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
export const UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT = new UmbContextToken<UmbMediaRecycleBinTreeStore>(
'UmbMediaRecycleBinTreeStore',
);

View File

@@ -1,4 +1,4 @@
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT } from './media-recycle-bin-tree.store.context-token.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbUniqueTreeStore } from '@umbraco-cms/backoffice/tree';
@@ -19,6 +19,4 @@ export class UmbMediaRecycleBinTreeStore extends UmbUniqueTreeStore {
}
}
export const UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT = new UmbContextToken<UmbMediaRecycleBinTreeStore>(
'UmbMediaRecycleBinTreeStore',
);
export { UmbMediaRecycleBinTreeStore as api };

View File

@@ -0,0 +1 @@
export const UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS = 'Umb.Repository.Media.Reference';

Some files were not shown because too many files have changed in this diff Show More