Skip to content

Commit

Permalink
Archive opens with console errors #1457 (#1459)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmi authored Jan 22, 2025
1 parent 87b042a commit 5afcc43
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 172 deletions.
44 changes: 6 additions & 38 deletions src/main/resources/assets/js/ArchiveItemPreviewPanel.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,23 @@
import {ArchiveItemPreviewToolbar} from './ArchiveItemPreviewToolbar';
import {IsRenderableRequest} from 'lib-contentstudio/app/resource/IsRenderableRequest';
import {DefaultErrorHandler} from '@enonic/lib-admin-ui/DefaultErrorHandler';
import {ContentPath} from 'lib-contentstudio/app/content/ContentPath';
import {ArchiveContentViewItem} from './ArchiveContentViewItem';
import {ContentItemPreviewPanel} from 'lib-contentstudio/app/view/ContentItemPreviewPanel';
import {ContentSummaryAndCompareStatus} from 'lib-contentstudio/app/content/ContentSummaryAndCompareStatus';
import {StatusCode} from '@enonic/lib-admin-ui/rest/StatusCode';
import {PreviewActionHelper} from 'lib-contentstudio/app/action/PreviewActionHelper';

export class ArchiveItemPreviewPanel
extends ContentItemPreviewPanel {

protected item: ArchiveContentViewItem;

private renderableItems: Map<string, boolean> = new Map<string, boolean>();

constructor() {
super(ContentPath.ARCHIVE_ROOT);
}

createToolbar(): ArchiveItemPreviewToolbar {
return new ArchiveItemPreviewToolbar();
}

setItem(item: ArchiveContentViewItem): void {
if (this.renderableItems.has(item.getId())) {
this.debouncedSetItem(item);
} else {
new IsRenderableRequest(item.getContentSummary())
.sendAndParse()
.then((statusCode: number) => {
const isRenderable = statusCode === StatusCode.OK;
item.setRenderable(isRenderable);
this.renderableItems.set(item.getId(), isRenderable);
this.debouncedSetItem(item);
}).catch(DefaultErrorHandler.handle);
}
this.addClass('archive-item-preview-panel');
}

doRender(): Q.Promise<boolean> {
return super.doRender().then((rendered: boolean) => {
this.addClass('archive-item-preview-panel');

return rendered;
});
}

protected viewItemToContent(item: ArchiveContentViewItem): ContentSummaryAndCompareStatus {
return item;
}

protected isNonBinaryItemRenderable(item: ContentSummaryAndCompareStatus): boolean {
return false;
createToolbar(): ArchiveItemPreviewToolbar {
return new ArchiveItemPreviewToolbar(new PreviewActionHelper({
archive: "true"
}));
}
}
82 changes: 9 additions & 73 deletions src/main/resources/assets/js/ArchiveItemPreviewToolbar.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,18 @@
import * as Q from 'q';
import {SpanEl} from '@enonic/lib-admin-ui/dom/SpanEl';
import {i18n} from '@enonic/lib-admin-ui/util/Messages';
import {DivEl} from '@enonic/lib-admin-ui/dom/DivEl';
import {ContentSummary} from 'lib-contentstudio/app/content/ContentSummary';
import {ItemPreviewToolbar} from '@enonic/lib-admin-ui/app/view/ItemPreviewToolbar';
import {ArchiveContentViewItem} from './ArchiveContentViewItem';
import {PrincipalKey} from '@enonic/lib-admin-ui/security/PrincipalKey';
import {Principal} from '@enonic/lib-admin-ui/security/Principal';
import {GetPrincipalByKeyRequest} from 'lib-contentstudio/app/resource/GetPrincipalByKeyRequest';
import {GetContentVersionsRequest} from 'lib-contentstudio/app/resource/GetContentVersionsRequest';
import {ContentVersions} from 'lib-contentstudio/app/ContentVersions';
import {DefaultErrorHandler} from '@enonic/lib-admin-ui/DefaultErrorHandler';
import {DateTimeFormatter} from '@enonic/lib-admin-ui/ui/treegrid/DateTimeFormatter';
import {ContentItemPreviewToolbar} from 'lib-contentstudio/app/view/ContentItemPreviewToolbar';
import {ContentSummaryAndCompareStatus} from 'lib-contentstudio/app/content/ContentSummaryAndCompareStatus';
import {PreviewActionHelper} from 'lib-contentstudio/app/action/PreviewActionHelper';

export class ArchiveItemPreviewToolbar
extends ItemPreviewToolbar<ArchiveContentViewItem> {
extends ContentItemPreviewToolbar {

private readonly archivedEl: DivEl;
constructor(previewHelper: PreviewActionHelper) {
super(previewHelper);

private readonly originalPathEl: SpanEl;

constructor() {
super({className: 'archive-status-toolbar'});

this.archivedEl = new DivEl('archived');

const originalPathWrapper = new DivEl('original-path');
this.originalPathEl = new SpanEl('original-path-value');
originalPathWrapper.appendChildren(new SpanEl().setHtml(i18n('preview.originalPath')), this.originalPathEl);

this.appendChild(originalPathWrapper);
}

setItem(item: ArchiveContentViewItem): void {
super.setItem(item);

if (item) {
const summary: ContentSummary = item.getContentSummary();
this.updatedArchivedBlock(summary);
this.updateOriginalPathBlock(item);
}
}

clearItem(): void {
this.setItem(null);

this.archivedEl.setHtml('');
}

doRender(): Q.Promise<boolean> {
return super.doRender().then((rendered: boolean) => {
this.insertChild(this.archivedEl, 1);

return rendered;
});
}

protected foldOrExpand(): void {
return;
}

private updatedArchivedBlock(summary: ContentSummary): void {
const status: string = i18n('status.archived');
const archivedBy: PrincipalKey = summary.getArchivedBy();

const versionsPromise: Q.Promise<ContentVersions> = new GetContentVersionsRequest(summary.getContentId()).sendAndParse();
const principalPromise: Q.Promise<Principal> = archivedBy != null ? new GetPrincipalByKeyRequest(archivedBy).sendAndParse() : Q(
null);

Q.all([versionsPromise, principalPromise]).spread((versions: ContentVersions, principal: Principal) => {
const when: string = DateTimeFormatter.createHtml(summary.getArchivedTime());
const displayName: string = i18n('field.preview.toolbar.status',
principal ? principal.getDisplayName() : PrincipalKey.ofAnonymous().getId());
this.archivedEl.setHtml(`${status} ${when} ${displayName}`);
}).catch(DefaultErrorHandler.handle);
this.addClass('archive-item-preview-toolbar');
}

private updateOriginalPathBlock(item: ArchiveContentViewItem): void {
this.originalPathEl.setHtml(item.getOriginalFullPath());
protected updateStatus(content: ContentSummaryAndCompareStatus): void {
this.status.setHtml(i18n('status.archived')); // for now just archived
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,10 @@
.archive-item-preview-panel {
.item-preview-toolbar.archive-status-toolbar {
.item-preview-toolbar.archive-item-preview-toolbar {
background-color: #e1c4ce !important;
height: 80px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
flex-shrink: 0;

.archived {
padding-left: 0;
font-size: 14px;
line-height: 18px;
}

.original-path {
margin: 5px 10px 0 10px;
line-height: 18px;
color: @admin-font-gray3;
display: flex;
flex-wrap: wrap;
justify-content: center;

&-value {
margin-left: 5px;
}
}
}

&.image-preview {
iframe.image,
.wrapper:has(> iframe.image) {
background-color: @admin-dark-gray;
}

Expand Down
6 changes: 4 additions & 2 deletions src/main/resources/lib/config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*global app, require*/

const portal = require('/lib/xp/portal');
const admin = require('/lib/xp/admin');

const portal = require('/lib/xp/portal');
const contextLib = require('/lib/xp/context');
const i18n = require('/lib/xp/i18n');

const getPhrases = function () {
Expand All @@ -23,12 +23,14 @@ const getPhrases = function () {
const getConfig = () => {
const csAppName = 'com.enonic.app.contentstudio';
const csToolUri = admin.getToolUrl(csAppName, 'main');
const context = contextLib.get();

return {
adminUrl: admin.getBaseUri(),
assetsUri: portal.assetUrl({
path: ''
}),
branch: context.branch,
appId: app.name,
services: {
contentUrl: portal.apiUrl({
Expand Down
6 changes: 6 additions & 0 deletions testing/libs/app_const.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,4 +395,10 @@ module.exports = Object.freeze({
ARIA_LABEL: 'aria-label',
ARIA_HAS_POPUP: 'aria-haspopup',
},
PREVIEW_WIDGET: {
AUTOMATIC: 'Automatic',
SITE_ENGINE: 'Site engine',
MEDIA: 'Media',
JSON: 'JSON'
},
});
90 changes: 70 additions & 20 deletions testing/page_objects/archive/archive.item.statistics.panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,94 @@ const appConst = require('../../libs/app_const');

const XPATH = {
container: "//div[contains(@id,'ArchiveItemStatisticsPanel')]",
archiveToolbar: "//div[contains(@id,'ArchiveItemPreviewToolbar')]",
archiveStatus: "//div[@class='archived']",
originalPath: "//span[contains(@class,'original-path-value')]",
archiveItemPreviewToolbar: "//div[contains(@id,'ArchiveItemPreviewToolbar')]",
contentStatus: "//span[@class='status']",
divEmulatorDropdown: "//div[contains(@id,'EmulatorDropdown')]",
divPreviewWidgetDropdown: "//div[contains(@id,'PreviewWidgetDropdown')]",
};

class ArchiveItemStatisticsPanel extends Page {

get archiveStatus() {
return XPATH.container + XPATH.archiveToolbar + XPATH.archiveStatus;
get contentStatus() {
return XPATH.container + XPATH.archiveItemPreviewToolbar + XPATH.contentStatus;
}

get originalPath() {
return XPATH.container + XPATH.archiveToolbar + XPATH.originalPath;
get emulatorDropdown() {
return XPATH.archiveItemPreviewToolbar + XPATH.divEmulatorDropdown;
}

async getPath() {
get previewWidgetDropdown() {
return XPATH.archiveItemPreviewToolbar + XPATH.divPreviewWidgetDropdown;
}

async getStatus() {
try {
await this.waitForElementDisplayed(this.originalPath, appConst.mediumTimeout);
return await this.getText(this.originalPath);
await this.waitForElementDisplayed(this.contentStatus, appConst.mediumTimeout);
return await this.getText(this.contentStatus);
} catch (err) {
await this.saveScreenshot('err_get_archive_path');
throw new Error('error when getting archive path' + err);
let screenshot = await this.saveScreenshot('err_get_content_status');
throw new Error(`error when getting archive status, screenshot:${screenshot} ` + err);
}
}

async getStatus() {
async waitForContentStatusNotDisplayed() {
return await this.waitForElementNotDisplayed(this.contentStatus, appConst.mediumTimeout);
}

async getSelectedOptionInEmulatorDropdown() {
try {
await this.waitForElementDisplayed(this.archiveStatus, appConst.mediumTimeout);
return await this.getText(this.archiveStatus);
let locator = this.emulatorDropdown + lib.H6_DISPLAY_NAME;
await this.waitForElementDisplayed(locator, appConst.mediumTimeout);
return await this.getText(locator);
} catch (err) {
await this.saveScreenshot('err_get_archive_status');
throw new Error('error when getting archive status' + err);
let screenshot = await this.saveScreenshotUniqueName('err_emulator_dropdown');
throw new Error(`Emulator dropdown - error occurred during getting the selected option, screenshot: ${screenshot} ` + err);
}
}

async waitForPanelCleared() {
await this.waitForElementNotDisplayed(this.originalPath, appConst.mediumTimeout);
return await this.waitForElementNotDisplayed(this.archiveStatus, appConst.mediumTimeout);
// Expands the emulator menu:
async clickOnEmulatorDropdown() {
await this.waitForElementDisplayed(this.emulatorDropdown, appConst.mediumTimeout);
return await this.clickOnElement(this.emulatorDropdown);
}

// Expands the emulator menu and clicks on a list-item by its name
async selectOptionInEmulatorDropdown(optionName) {
await this.waitForElementDisplayed(this.emulatorDropdown, appConst.mediumTimeout);
await this.clickOnElement(this.emulatorDropdown);
let optionSelector = this.emulatorDropdown + lib.DROPDOWN_SELECTOR.listItemByDisplayName(optionName);
await this.waitForElementDisplayed(optionSelector, appConst.mediumTimeout);
return await this.clickOnElement(optionSelector);
}

// Gets the selected option in the 'Preview dropdown' Auto, Media, etc.
async getSelectedOptionInPreviewWidget() {
let locator = this.previewWidgetDropdown + lib.H6_DISPLAY_NAME;
await this.waitForElementDisplayed(locator, appConst.mediumTimeout);
return await this.getText(locator);
}

// Clicks on the dropdown handle in the 'Preview dropdown' then clicks on a list-item by its name
async selectOptionInPreviewWidget(optionName) {
await this.waitForPreviewWidgetDropdownDisplayed();
await this.clickOnElement(this.previewWidgetDropdown);
let optionSelector = this.previewWidgetDropdown + lib.DROPDOWN_SELECTOR.listItemByDisplayName(optionName);
await this.waitForElementDisplayed(optionSelector, appConst.mediumTimeout);
await this.clickOnElement(optionSelector);
await this.pause(200);
}

async waitForPreviewWidgetDropdownDisplayed() {
return await this.waitForElementDisplayed(this.previewWidgetDropdown, appConst.mediumTimeout);
}

async waitForPreviewWidgetDropdownNotDisplayed() {
try {
return await this.waitForElementNotDisplayed(this.previewWidgetDropdown, appConst.mediumTimeout);
} catch (err) {
let screenshot = await this.saveScreenshotUniqueName('err_preview_widget_dropdown');
throw new Error(`Preview widget dropdown - is displayed, screenshot: ${screenshot} ` + err);
}
}
}

Expand Down
18 changes: 8 additions & 10 deletions testing/specs/archive.browse.panel.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,9 @@ describe('archive.browse.panel.spec: tests for archive browse panel and selectio
let contentWidgetItemView = new ArchiveContentWidgetItemView();
// 1. Navigate to 'Archive Browse Panel' and click on the checkbox for the archived content:
await archiveBrowsePanel.clickOnCheckboxAndSelectRowByName(FOLDER1.displayName);
// 2. Verify the path and status of the content:
let path = await archiveItemStatisticsPanel.getPath();
assert.equal(path, `/${FOLDER1.displayName}`, "Expected path should be displayed in Item Statistics panel");
// 2. Verify status of the content:
let status = await archiveItemStatisticsPanel.getStatus();
assert.ok(status.includes('Archived'), "Archived status should be displayed in Item Statistics panel");
assert.ok(status.includes('by Super User'), "'by Super User' should be displayed in Item Statistics panel");
assert.equal(status, 'Archived', "Archived status should be displayed in Item Statistics panel");
// 3. Verify that workflow icon is not displayed:
await contentWidgetItemView.waitForWorkflowStateNotDisplayed();
// 4. Verify the name in the content widget:
Expand All @@ -121,13 +118,14 @@ describe('archive.browse.panel.spec: tests for archive browse panel and selectio
let archiveItemStatisticsPanel = new ArchiveItemStatisticsPanel();
// 1. Click on the row and select an item:
await archiveBrowsePanel.clickOnRowByDisplayName(FOLDER1.displayName);
// 2. Verify the path and status of the content:
let path = await archiveItemStatisticsPanel.getPath();
assert.equal(path, `/${FOLDER1.displayName}`, 'Expected path should be displayed in Item Statistics panel');
// 2. Verify status of the content:
let status = await archiveItemStatisticsPanel.getStatus();
assert.equal(status, 'Archived', "Archived status should be displayed in Item Statistics panel");
// 3. Click on the row and unselect the item
await archiveBrowsePanel.clickOnRowByDisplayName(FOLDER1.displayName);
// 4. Verify that Item Statistics panel is cleared:
await archiveItemStatisticsPanel.waitForPanelCleared();
await archiveItemStatisticsPanel.waitForContentStatusNotDisplayed();
await archiveItemStatisticsPanel.waitForPreviewWidgetDropdownNotDisplayed();
});

it("WHEN existing folder is selected THEN 'Archived' status should be displayed in Details Panel",
Expand All @@ -141,7 +139,7 @@ describe('archive.browse.panel.spec: tests for archive browse panel and selectio
await archiveBrowsePanel.clickOnRowByDisplayName(FOLDER1.displayName);
// 3. Verify the Archived status of the content:
let actualStatus = await archivedContentStatusWidget.getStatus();
assert.equal(actualStatus, 'Archived');
assert.equal(actualStatus, 'Archived', "Expected status should be displayed in Details Panel");
});

it("GIVEN existing folder is selected AND 'Versions widget' is opened WHEN 'Show changes' button in Edited item has been clicked THEN compareContentVersionsDialog should be loaded",
Expand Down
Loading

0 comments on commit 5afcc43

Please sign in to comment.