Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Published Document Pending Changes #17812

Merged
merged 83 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 82 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
9a3cd86
implement validation for media and prepare for member
nielslyngsoe Nov 20, 2024
c72568c
Merge branch 'v15/dev' into v15/feature/media-server-validation
nielslyngsoe Nov 20, 2024
54bba71
Merge branch 'v15/dev' into v15/feature/media-server-validation
nielslyngsoe Nov 25, 2024
c48c82b
remove import
nielslyngsoe Nov 25, 2024
699ddec
Merge branch 'v15/dev' into v15/feature/media-server-validation
nielslyngsoe Nov 29, 2024
ed45a2b
port code from backoffice repo
madsrasmussen Dec 3, 2024
e35327f
move repo into publishing module
madsrasmussen Dec 3, 2024
9a3b554
port get published methods
madsrasmussen Dec 3, 2024
3528875
cleanup
madsrasmussen Dec 3, 2024
cb6ca57
wip render state
madsrasmussen Dec 3, 2024
c748398
align state UI
madsrasmussen Dec 3, 2024
1bbfbe2
Merge branch 'v15/dev' into v15/feature/published-pending-changes
madsrasmussen Dec 9, 2024
b48e5c5
post merge clean up
madsrasmussen Dec 9, 2024
7ed08f3
move publish modal
madsrasmussen Dec 9, 2024
c4c99fb
move schedule modal
madsrasmussen Dec 9, 2024
0657507
move unpublish modal
madsrasmussen Dec 9, 2024
c6e7b7a
move publish action and bulk action
madsrasmussen Dec 9, 2024
503755f
move unpublish action + bulk action
madsrasmussen Dec 9, 2024
abfd6f5
lint fix
madsrasmussen Dec 9, 2024
27c368f
Update document-workspace.context.ts
madsrasmussen Dec 9, 2024
e6f5158
wip move publishing methods to publishing context
madsrasmussen Dec 9, 2024
3f8407e
move publish with descendants
madsrasmussen Dec 9, 2024
d6ff2b6
fix more references
madsrasmussen Dec 9, 2024
c5f319e
Update document-publishing.workspace-context.ts
madsrasmussen Dec 9, 2024
cf680fe
export entity action
madsrasmussen Dec 9, 2024
830b354
add return type
madsrasmussen Dec 9, 2024
0ac74fd
temp internal methods
madsrasmussen Dec 9, 2024
ddc89da
Merge branch 'v15/dev' into v15/feature/media-server-validation
madsrasmussen Dec 9, 2024
937de3a
use repository response type
madsrasmussen Dec 9, 2024
8520151
Merge branch 'v15/feature/media-server-validation' into v15/feature/p…
madsrasmussen Dec 10, 2024
133292b
expose methods for other contexts to use
madsrasmussen Dec 10, 2024
ccbcd4d
use public methods
madsrasmussen Dec 10, 2024
c2b25b6
call publishing context methods
madsrasmussen Dec 10, 2024
a5e5466
fix import
madsrasmussen Dec 10, 2024
da39771
move manager into folder
madsrasmussen Dec 10, 2024
7dbd93f
organise in folders
madsrasmussen Dec 10, 2024
875fd9b
add get method to get variants with changes
madsrasmussen Dec 10, 2024
eb07110
preselect variants with pending changes
madsrasmussen Dec 10, 2024
7e731dc
observe data changes
madsrasmussen Dec 10, 2024
1991609
render pending changes client state
madsrasmussen Dec 10, 2024
95d8649
observe unique
madsrasmussen Dec 10, 2024
622255a
Update document-publishing.server.data-source.ts
madsrasmussen Dec 10, 2024
fc309f6
use correct key
madsrasmussen Dec 10, 2024
318dc1d
clean up
madsrasmussen Dec 10, 2024
e1d93b8
expose persisted data
madsrasmussen Dec 10, 2024
4b09170
rename arg
madsrasmussen Dec 10, 2024
011dceb
use persisted data instead of current
madsrasmussen Dec 10, 2024
261138a
add reload method
madsrasmussen Dec 10, 2024
ffcba32
reload data after publish
madsrasmussen Dec 10, 2024
78066c0
remove headline
madsrasmussen Dec 10, 2024
66fd1ce
handle all publish actions the same
madsrasmussen Dec 10, 2024
0b968d0
reset state as the first thing when creating + loading
madsrasmussen Dec 10, 2024
bf1e359
add method to get variants
madsrasmussen Dec 10, 2024
f84f2a3
only load published if document has a published variant
madsrasmussen Dec 10, 2024
067c0f2
remove variants from observer
madsrasmussen Dec 11, 2024
6ca3c79
add public method to get the changed variants
madsrasmussen Dec 11, 2024
0098218
align preselection with current logic
madsrasmussen Dec 11, 2024
a178a6b
add deprecation util
madsrasmussen Dec 11, 2024
f721aea
add method deprecation warnings
madsrasmussen Dec 11, 2024
f8bfb41
remove unused publish method
madsrasmussen Dec 11, 2024
e77a0e3
move publishing workspace actions into publishing module
madsrasmussen Dec 11, 2024
e402c2b
use publishing context
madsrasmussen Dec 11, 2024
31bbb7f
Merge branch 'v15/dev' into v15/feature/media-server-validation
madsrasmussen Dec 11, 2024
6bfc9ff
Merge branch 'v15/feature/media-server-validation' into v15/feature/p…
madsrasmussen Dec 11, 2024
fa89f4b
clean up
madsrasmussen Dec 11, 2024
3ae8bfa
add tests for published pending changes manager
madsrasmussen Dec 11, 2024
4e88102
handle server the same way
madsrasmussen Dec 11, 2024
d05c865
Merge branch 'v15/dev' into v15/feature/published-pending-changes
madsrasmussen Dec 13, 2024
f1b16a5
process pending changes when persisted data changes
madsrasmussen Dec 13, 2024
f9a6651
remove buggy updateDate
madsrasmussen Dec 13, 2024
327c5e3
Merge branch 'v15/dev' into v15/feature/published-pending-changes
madsrasmussen Dec 13, 2024
026dcbd
remove unused
madsrasmussen Dec 13, 2024
de946a9
lint fix
madsrasmussen Dec 13, 2024
bd3bf27
Merge branch 'v15/dev' into v15/feature/published-pending-changes
madsrasmussen Dec 13, 2024
e8409b3
Merge branch 'v15/dev' into v15/feature/published-pending-changes
madsrasmussen Dec 13, 2024
ca3486a
add publish method back to avoid a breaking change
madsrasmussen Dec 13, 2024
540fa8a
Merge branch 'v15/dev' into v15/feature/published-pending-changes
madsrasmussen Dec 16, 2024
6c3d515
Merge branch 'v15/dev' into v15/feature/published-pending-changes
iOvergaard Dec 16, 2024
567816a
throw error if we try to compare two different documents
madsrasmussen Dec 18, 2024
1770f80
clear states if a new document is loaded
madsrasmussen Dec 18, 2024
344c1fc
ensure we can only show the pending changes state if variant is publi…
madsrasmussen Dec 18, 2024
60490a1
Merge branch 'v15/dev' into v15/feature/published-pending-changes
madsrasmussen Dec 18, 2024
545b3c9
remove client test thats doesn't do anything but trouble
madsrasmussen Dec 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ export default {
indexCannotRebuild: 'This index cannot be rebuilt because it has no assigned',
iIndexPopulator: 'IIndexPopulator',
corruptStatus: 'Possible corrupt index detected',
corruptErrorDescription: 'Error received when evaluating the index:'
corruptErrorDescription: 'Error received when evaluating the index:',
},
placeholders: {
username: 'Enter your username',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ export interface UmbContentDetailWorkspaceContextArgs<
saveModalToken?: UmbModalToken<UmbContentVariantPickerData<VariantOptionModelType>, UmbContentVariantPickerValue>;
}

/**
* The base class for a content detail workspace context.
* @exports
* @abstract
* @class UmbContentDetailWorkspaceContextBase
* @augments {UmbEntityDetailWorkspaceContextBase<DetailModelType, DetailRepositoryType, CreateArgsType>}
* @implements {UmbContentWorkspaceContext<DetailModelType, ContentTypeDetailModelType, VariantModelType>}
* @template DetailModelType
* @template DetailRepositoryType
* @template ContentTypeDetailModelType
* @template VariantModelType
* @template VariantOptionModelType
* @template CreateArgsType
*/
export abstract class UmbContentDetailWorkspaceContextBase<
DetailModelType extends UmbContentDetailModel<VariantModelType>,
DetailRepositoryType extends UmbDetailRepository<DetailModelType> = UmbDetailRepository<DetailModelType>,
Expand All @@ -83,8 +97,11 @@ export abstract class UmbContentDetailWorkspaceContextBase<

/* Content Data */
protected override readonly _data = new UmbContentWorkspaceDataManager<DetailModelType, VariantModelType>(this);

public override readonly data = this._data.current;
public readonly values = this._data.createObservablePartOfCurrent((data) => data?.values);
public readonly variants = this._data.createObservablePartOfCurrent((data) => data?.variants ?? []);
public override readonly persistedData = this._data.persisted;

/* Content Type (Structure) Data */
public readonly structure;
Expand Down Expand Up @@ -332,6 +349,10 @@ export abstract class UmbContentDetailWorkspaceContextBase<
return this._data.getCurrent()?.variants?.find((x) => variantId.compare(x));
}

public getVariants(): Array<VariantModelType> | undefined {
return this._data.getCurrent()?.variants;
}

/**
* Observe the property type
* @param {string} propertyId - The id of the property
Expand Down Expand Up @@ -440,7 +461,19 @@ export abstract class UmbContentDetailWorkspaceContextBase<
this._data.finishPropertyValueChange();
};

protected async _determineVariantOptions() {
/**
* Gets the changed variant ids
* @returns {Array<UmbVariantId>} - The changed variant ids
* @memberof UmbContentDetailWorkspaceContextBase
*/
public getChangedVariants(): Array<UmbVariantId> {
return this._data.getChangedVariants();
}

protected async _determineVariantOptions(): Promise<{
options: VariantOptionModelType[];
selected: string[];
}> {
const options = await firstValueFrom(this.variantOptions);

const activeVariants = this.splitView.getActiveVariants();
Expand All @@ -465,7 +498,23 @@ export abstract class UmbContentDetailWorkspaceContextBase<
};

/* validation */
/**
* Run the mandatory validation for the save data
* @deprecated Use the public runMandatoryValidationForSaveData instead. Will be removed in v. 17.
* @protected
* @param {DetailModelType} saveData - The data to validate
* @memberof UmbContentDetailWorkspaceContextBase
*/
protected async _runMandatoryValidationForSaveData(saveData: DetailModelType) {
this.runMandatoryValidationForSaveData(saveData);
}

/**
* Run the mandatory validation for the save data
* @param {DetailModelType} saveData - The data to validate
* @memberof UmbContentDetailWorkspaceContextBase
*/
public async runMandatoryValidationForSaveData(saveData: DetailModelType) {
// Check that the data is valid before we save it.
// Check variants have a name:
const variantsWithoutAName = saveData.variants.filter((x) => !x.name);
Expand All @@ -482,7 +531,13 @@ export abstract class UmbContentDetailWorkspaceContextBase<
}
}

protected async _askServerToValidate(saveData: DetailModelType, variantIds: Array<UmbVariantId>) {
/**
* Ask the server to validate the save data
* @param {DetailModelType} saveData - The data to validate
* @param {Array<UmbVariantId>} variantIds - The variant ids to validate
* @memberof UmbContentDetailWorkspaceContextBase
*/
public async askServerToValidate(saveData: DetailModelType, variantIds: Array<UmbVariantId>) {
if (this.#validationRepositoryClass) {
// Create the validation repository if it does not exist. (we first create this here when we need it) [NL]
this.#validationRepository ??= new this.#validationRepositoryClass(this);
Expand Down Expand Up @@ -516,6 +571,16 @@ export abstract class UmbContentDetailWorkspaceContextBase<
return this._handleSubmit();
}

/**
* Get the data to save
* @param {Array<UmbVariantId>} variantIds - The variant ids to save
* @returns {Promise<DetailModelType>} {Promise<DetailModelType>}
* @memberof UmbContentDetailWorkspaceContextBase
*/
public constructSaveData(variantIds: Array<UmbVariantId>): Promise<DetailModelType> {
return this._data.constructData(variantIds);
}

protected async _handleSubmit() {
const data = this.getData();
if (!data) {
Expand Down Expand Up @@ -553,24 +618,42 @@ export abstract class UmbContentDetailWorkspaceContextBase<
throw new Error('No variant picker modal token is set. There are multiple variants to save. Cannot proceed.');
}

const saveData = await this._data.constructData(variantIds);
await this._runMandatoryValidationForSaveData(saveData);
const saveData = await this.constructSaveData(variantIds);
await this.runMandatoryValidationForSaveData(saveData);
if (this.#validateOnSubmit) {
await this._askServerToValidate(saveData, variantIds);
await this.askServerToValidate(saveData, variantIds);
return this.validateAndSubmit(
async () => {
return this._performCreateOrUpdate(variantIds, saveData);
return this.performCreateOrUpdate(variantIds, saveData);
},
async () => {
return this.invalidSubmit();
},
);
} else {
await this._performCreateOrUpdate(variantIds, saveData);
await this.performCreateOrUpdate(variantIds, saveData);
}
}

/**
* Perform the create or update of the content
* @deprecated Use the public performCreateOrUpdate instead. Will be removed in v. 17.
* @protected
* @param {Array<UmbVariantId>} variantIds
* @param {DetailModelType} saveData
* @memberof UmbContentDetailWorkspaceContextBase
*/
protected async _performCreateOrUpdate(variantIds: Array<UmbVariantId>, saveData: DetailModelType) {
await this.performCreateOrUpdate(variantIds, saveData);
}

/**
* Perform the create or update of the content
* @param {Array<UmbVariantId>} variantIds - The variant ids to save
* @param {DetailModelType} saveData - The data to save
* @memberof UmbContentDetailWorkspaceContextBase
*/
public async performCreateOrUpdate(variantIds: Array<UmbVariantId>, saveData: DetailModelType) {
if (this.getIsNew()) {
await this.#create(variantIds, saveData);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { UmbDeprecationArgs } from './types.js';

/**
* Helper class for deprecation warnings.
* @exports
* @class UmbDeprecation
*/
export class UmbDeprecation {
#messagePrefix: string = 'Umbraco Backoffice:';
#deprecated: string;
#removeInVersion: string;
#solution: string;

constructor(args: UmbDeprecationArgs) {
this.#deprecated = args.deprecated;
this.#removeInVersion = args.removeInVersion;
this.#solution = args.solution;
}

/**
* Logs a warning message to the console.
* @memberof UmbDeprecation
*/
warn() {
console.warn(
`${this.#messagePrefix} ${this.#deprecated} The feature will be removed in version ${this.#removeInVersion}. ${this.#solution}`,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './deprecation.js';

export type * from './types.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface UmbDeprecationArgs {
deprecated: string;
removeInVersion: string;
solution: string;
}
1 change: 1 addition & 0 deletions src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ export * from './sanitize/sanitize-html.function.js';
export * from './selection-manager/selection.manager.js';
export * from './state-manager/index.js';
export * from './string/index.js';
export * from './deprecation/index.js';
export type * from './type/index.js';
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
public readonly unique = this.#entityContext.unique;

public readonly data = this._data.current;
public readonly persistedData = this._data.persisted;
public readonly loading = new UmbStateManager(this);

protected _getDataPromise?: Promise<any>;
Expand Down Expand Up @@ -85,6 +86,14 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
return this._data.getCurrent();
}

/**
* Get the persisted data
* @returns { DetailModelType | undefined } The persisted data
*/
public getPersistedData(): DetailModelType | undefined {
return this._data.getPersisted();
}

/**
* Get the unique
* @returns { string | undefined } The unique identifier
Expand Down Expand Up @@ -122,10 +131,10 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
}

async load(unique: string) {
this.resetState();
this.#entityContext.setUnique(unique);
this.loading.addState({ unique: LOADING_STATE_UNIQUE, message: `Loading ${this.getEntityType()} Details` });
await this.#init;
this.resetState();
this._getDataPromise = this._detailRepository!.requestByUnique(unique);
type GetDataType = Awaited<ReturnType<UmbDetailRepository<DetailModelType>['requestByUnique']>>;
const response = (await this._getDataPromise) as GetDataType;
Expand All @@ -147,6 +156,21 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
return response;
}

/**
* Reload the workspace data
* @returns { Promise<void> } The promise of the reload
*/
public async reload(): Promise<void> {
const unique = this.getUnique();
if (!unique) throw new Error('Unique is not set');
const { data } = await this._detailRepository!.requestByUnique(unique);

if (data) {
this._data.setPersisted(data);
this._data.setCurrent(data);
}
}

/**
* Method to check if the workspace data is loaded.
* @returns { Promise<any> | undefined } true if the workspace data is loaded.
Expand All @@ -166,9 +190,9 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
* @returns { Promise<any> | undefined } The data of the scaffold.
*/
public async createScaffold(args: CreateArgsType) {
this.resetState();
this.loading.addState({ unique: LOADING_STATE_UNIQUE, message: `Creating ${this.getEntityType()} scaffold` });
await this.#init;
this.resetState();
this.setParent(args.parent);

const request = this._detailRepository!.createScaffold(args.preset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export abstract class UmbSubmittableWorkspaceContextBase<WorkspaceDataModelType>
this.#isNew.setValue(undefined);
}

getIsNew() {
public getIsNew() {
return this.#isNew.getValue();
}

Expand All @@ -75,19 +75,19 @@ export abstract class UmbSubmittableWorkspaceContextBase<WorkspaceDataModelType>
* If a Workspace has multiple validation contexts, then this method can be overwritten to return the correct one.
* @returns Promise that resolves to void when the validation is complete.
*/
async validate(): Promise<Array<void>> {
public async validate(): Promise<Array<void>> {
//return this.validation.validate();
return Promise.all(this.#validationContexts.map((context) => context.validate()));
}

async requestSubmit(): Promise<void> {
public async requestSubmit(): Promise<void> {
return this.validateAndSubmit(
() => this.submit(),
() => this.invalidSubmit(),
);
}

protected async validateAndSubmit(onValid: () => Promise<void>, onInvalid: () => Promise<void>): Promise<void> {
public async validateAndSubmit(onValid: () => Promise<void>, onInvalid: () => Promise<void>): Promise<void> {
if (this.#submitPromise) {
return this.#submitPromise;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
export { UMB_DOCUMENT_ENTITY_TYPE, UMB_DOCUMENT_ROOT_ENTITY_TYPE } from './entity.js';

export * from './paths.js';
export * from './collection/constants.js';
export * from './entity-actions/constants.js';
export * from './entity-bulk-actions/constants.js';
export * from './property-dataset-context/constants.js';
export * from './modals/constants.js';
export * from './paths.js';
export * from './property-dataset-context/constants.js';
export * from './publishing/constants.js';
export * from './recycle-bin/constants.js';
export * from './reference/constants.js';
export * from './repository/constants.js';
export * from './rollback/constants.js';
export * from './search/constants.js';
export * from './workspace/constants.js';
export * from './user-permissions/constants.js';
export * from './workspace/constants.js';
Loading
Loading