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

Consolidated Item Removal process which can be used on offshoot pages. #417

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "The Internet Archive Collection Browser.",
"license": "AGPL-3.0-only",
"author": "Internet Archive",
"version": "2.7.6",
"version": "2.7.6-alpha4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder not to merge the alpha version into main.

"main": "dist/index.js",
"module": "dist/index.js",
"scripts": {
Expand Down
42 changes: 38 additions & 4 deletions src/app-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,10 +489,8 @@ export class AppRoot extends LitElement {
@baseQueryChanged=${this.baseQueryChanged}
@searchTypeChanged=${this.searchTypeChanged}
@manageModeChanged=${this.manageModeChanged}
@itemRemovalRequested=${(e: CustomEvent) =>
console.log(e.detail.items)}
@itemManagerRequested=${(e: CustomEvent) =>
console.log(e.detail.items)}
@itemRemovalRequested=${this.handleItemRemovalRequest}
@itemManagerRequested=${this.handleItemManagerRequest}
>
${this.toggleSlots
? html`<div slot="sortbar-left-slot">Sort Slot</div>`
Expand Down Expand Up @@ -707,6 +705,36 @@ export class AppRoot extends LitElement {
if (manageCheckbox) manageCheckbox.checked = e.detail;
}

/**
* Handler for item removal
*/
private handleItemRemovalRequest(e: CustomEvent) {
this.collectionBrowser.showRemoveItemsProcessingModal();
console.log('itemRemovalRequested: ', e.detail.items);

setTimeout(() => {
// execute item-removal-service, and response is successfully deleted
const status = false;

if (status) {
// looking for success?
this.collectionBrowser.isManageView = false;
this.modalManager?.closeModal();
this.modalManager?.classList.remove('remove-items');
} else {
// looking for failure?
this.collectionBrowser.showRemoveItemsErrorModal();
}
}, 2000); // let's wait to see processing modal
}

/**
* Handler when item manage requested
*/
private handleItemManagerRequest(e: CustomEvent) {
console.log('itemManagerRequested: ', e.detail.items);
}

/**
* Handler for when the dev panel's "Enable manage mode" checkbox is changed.
*/
Expand Down Expand Up @@ -936,6 +964,12 @@ export class AppRoot extends LitElement {
modal-manager[mode='open'] {
display: block;
}
modal-manager.remove-items {
--modalWidth: 58rem;
--modalBorder: 2px solid var(--primaryButtonBGColor, #194880);
--modalTitleLineHeight: 4rem;
--modalTitleFontSize: 1.8rem;
}
modal-manager.more-search-facets {
--modalWidth: 85rem;
--modalBorder: 2px solid var(--primaryButtonBGColor, #194880);
Expand Down
52 changes: 36 additions & 16 deletions src/collection-browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ import type {
} from './data-source/collection-browser-query-state';
import { FACETLESS_PAGE_ELEMENTS } from './data-source/models';
import type { CollectionFacets } from './collection-facets';
import type { ManageableItem } from './manage/manage-bar';
import type { CollectionBrowserDataSourceInterface } from './data-source/collection-browser-data-source-interface';
import {
analyticsActions,
Expand All @@ -66,9 +65,9 @@ import {
import chevronIcon from './assets/img/icons/chevron';
import { srOnlyStyle } from './styles/sr-only';
import { sha1 } from './utils/sha1';
import { formatDate } from './utils/format-date';
import { log } from './utils/log';
import type { PlaceholderType } from './empty-placeholder';
import type { ManageBar } from './manage/manage-bar';

import './empty-placeholder';
import './tiles/tile-dispatcher';
Expand Down Expand Up @@ -299,6 +298,8 @@ export class CollectionBrowser

@query('collection-facets') private collectionFacets?: CollectionFacets;

@query('manage-bar') private manageBar?: ManageBar;

@property({ type: Object, attribute: false })
analyticsHandler?: AnalyticsManagerInterface;

Expand Down Expand Up @@ -774,15 +775,23 @@ export class CollectionBrowser
* showing the management view. This generally replaces the sort bar when present.
*/
private get manageBarTemplate(): TemplateResult {
const manageViewModelMsg =
this.profileElement === 'uploads'
? 'Note: it may take a few minutes for these items to stop appearing in your uploads list.'
: nothing;

return html`
<manage-bar
.label=${this.manageViewLabel}
.pageContext=${this.pageContext}
.modalManager=${this.modalManager}
.selectedItems=${this.dataSource.checkedTileModels}
.manageViewModelMsg=${manageViewModelMsg}
showSelectAll
showUnselectAll
?showItemManageButton=${this.pageContext === 'search'}
?removeAllowed=${this.dataSource.checkedTileModels.length !== 0}
@removeItems=${this.handleRemoveItems}
@itemsManager=${this.handleItemsManager}
@manageItems=${this.handleManageItems}
@selectAll=${() => this.dataSource.checkAllTiles()}
@unselectAll=${() => this.dataSource.uncheckAllTiles()}
@cancel=${() => {
Expand All @@ -799,13 +808,11 @@ export class CollectionBrowser
*/
private handleRemoveItems(): void {
this.dispatchEvent(
new CustomEvent<{ items: ManageableItem[] }>('itemRemovalRequested', {
new CustomEvent<{ items: String[] }>('itemRemovalRequested', {
detail: {
items: this.dataSource.checkedTileModels.map(model => {
const cloned = model.clone();
cloned.dateStr = formatDate(model.datePublished, 'long');
return cloned as ManageableItem;
}),
items: this.dataSource.checkedTileModels.map(model =>
model?.identifier ? model.identifier : ''
),
},
})
);
Expand All @@ -814,19 +821,32 @@ export class CollectionBrowser
/**
* Handler when user request to bulk edit from /search/ page
*/
private handleItemsManager(): void {
private handleManageItems(): void {
this.dispatchEvent(
new CustomEvent('itemManagerRequested', {
new CustomEvent<{ items: String[] }>('itemManagerRequested', {
detail: {
items: this.dataSource.checkedTileModels
.map(item => item.identifier)
.filter(Boolean)
.join(','),
items: this.dataSource.checkedTileModels.map(model =>
model?.identifier ? model.identifier : ''
),
},
})
);
}

/**
* Handler to show processing modal while removing item
*/
showRemoveItemsProcessingModal(): void {
this.manageBar?.showRemoveItemsProcessingModal();
}

/**
* Handler to show error modal when item removal failed
*/
showRemoveItemsErrorModal(): void {
this.manageBar?.showRemoveItemsErrorModal();
}

/**
* Removes all tile models that are currently checked & adjusts the paging
* of the data source to account for any new gaps in the data.
Expand Down
142 changes: 119 additions & 23 deletions src/manage/manage-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { msg } from '@lit/localize';
import { LitElement, html, css, TemplateResult, CSSResultGroup } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';
import {
ModalConfig,
type ModalManagerInterface,
} from '@internetarchive/modal-manager';
import type { ManageableItem } from '../models';
import iaButtonStyle from '../styles/ia-button';

export interface ManageableItem {
identifier: string;
title?: string;
dateStr?: string;
}
import './remove-items-modal-content';

@customElement('manage-bar')
export class ManageBar extends LitElement {
Expand All @@ -18,9 +18,19 @@ export class ManageBar extends LitElement {
@property({ type: String }) label = msg('Select items to remove');

/**
* Specifies the context in which the collection browser is being used
* The shared modal manager component for displaying modal dialogs on this page
*/
@property({ type: String }) pageContext?: string;
@property({ type: Object }) modalManager?: ModalManagerInterface;

/**
* Array of items that have been selected for management
*/
@property({ type: Object }) selectedItems: Array<ManageableItem> = [];

/**
* Message shows as note in the modal when removing items
*/
@property({ type: String }) manageViewModelMsg?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting a possible small typo: Model -> Modal ?


/**
* Whether to show the "Select All" button (default false)
Expand All @@ -32,6 +42,11 @@ export class ManageBar extends LitElement {
*/
@property({ type: Boolean }) showUnselectAll = false;

/**
* Whether to show "Item Manager the items" button (default false)
*/
@property({ type: Boolean }) showItemManageButton = false;

/**
* Whether to active delete button for selectable items
*/
Expand All @@ -48,21 +63,20 @@ export class ManageBar extends LitElement {
<button
class="ia-button danger"
?disabled=${!this.removeAllowed}
@click=${this.removeClicked}
@click=${this.showRemoveItemsModal}
>
${msg('Remove selected items')}
</button>
${this.pageContext === 'search'
? html`
<button
class="ia-button warning"
?disabled=${!this.removeAllowed}
@click=${this.itemsManagerClicked}
>
${msg('Item Manager the items')}
</button>
`
: ''}
${when(
this.showItemManageButton,
() => html` <button
class="ia-button warning"
?disabled=${!this.removeAllowed}
@click=${this.manageItemsClicked}
>
${msg('Item Manager the items')}
</button>`
)}
<div class="selection-buttons">
${when(
this.showSelectAll,
Expand Down Expand Up @@ -92,12 +106,12 @@ export class ManageBar extends LitElement {
this.dispatchEvent(new CustomEvent('cancel'));
}

private removeClicked(): void {
private removeItemsClicked(): void {
this.dispatchEvent(new CustomEvent('removeItems'));
}

private itemsManagerClicked(): void {
this.dispatchEvent(new CustomEvent('itemsManager'));
private manageItemsClicked(): void {
this.dispatchEvent(new CustomEvent('manageItems'));
}

private selectAllClicked(): void {
Expand All @@ -108,6 +122,88 @@ export class ManageBar extends LitElement {
this.dispatchEvent(new CustomEvent('unselectAll'));
}

/**
* Shows a modal dialog confirming the list of items to be removed
* @param items Which items to list in the modal
*/
private showRemoveItemsModal(): void {
const customModalContent = html`
<remove-items-modal-content
.items=${this.selectedItems}
.message=${this.manageViewModelMsg}
@confirm=${() => this.removeItemsClicked()}
></remove-items-modal-content>
`;

const config = new ModalConfig({
showProcessingIndicator: false,
processingImageMode: 'processing',
bodyColor: '#fff',
headerColor: '#194880',
showHeaderLogo: false,
closeOnBackdropClick: true,
title: html`${msg('Are you sure you want to remove these items?')}`,
});

this.modalManager?.classList.add('remove-items');
this.modalManager?.showModal({
config,
customModalContent,
userClosedModalCallback: () => {
this.modalManager?.classList.remove('remove-items');
},
});
}

/**
* Shows a modal dialog indicating that item removal is being processed
*/
showRemoveItemsProcessingModal(): void {
const config = new ModalConfig({
showProcessingIndicator: true,
processingImageMode: 'processing',
bodyColor: '#fff',
headerColor: '#194880',
showHeaderLogo: false,
closeOnBackdropClick: true,
title: html`${msg('Removing selected items...')}`,
});

this.modalManager?.classList.add('remove-items');
this.modalManager?.showModal({
config,
userClosedModalCallback: () => {
this.modalManager?.classList.remove('remove-items');
},
});
}

/**
* Shows a modal dialog indicating that an error occurred while removing items
*/
showRemoveItemsErrorModal(): void {
const config = new ModalConfig({
showProcessingIndicator: false,
processingImageMode: 'processing',
bodyColor: '#fff',
headerColor: '#691916',
showHeaderLogo: false,
closeOnBackdropClick: true,
title: html`${msg('Error: unable to remove items')}`,
message: html`${msg(
'An error occurred while removing items. Please try again in a few minutes.'
)}`,
});

this.modalManager?.classList.add('remove-items');
this.modalManager?.showModal({
config,
userClosedModalCallback: () => {
this.modalManager?.classList.remove('remove-items');
},
});
}

static get styles(): CSSResultGroup {
return css`
${iaButtonStyle}
Expand Down
Loading
Loading