Skip to content

Commit

Permalink
ante: fix merging functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
ChlodAlejandro committed Aug 16, 2023
1 parent b45cc88 commit 2374c07
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 24 deletions.
2 changes: 1 addition & 1 deletion i18n/ante/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"deputy.ante.edit": "Modify content attribution notices for this page",
"deputy.ante.add": "Add a notice",
"deputy.ante.mergeAll": "Merge all notices",
"deputy.ante.mergeAll.confirm": "You are about to merge $1 {{PLURAL:$1|notice|notices}}. Continue?",
"deputy.ante.mergeAll.confirm": "You are about to merge $1 {{PLURAL:$1|notice|notices}} which support rows. Continue?",
"deputy.ante.reset": "Reset all changes",
"deputy.ante.reset.confirm": "This will reset all changes. Proceed?",
"deputy.ante.delete": "Delete all notices",
Expand Down
11 changes: 11 additions & 0 deletions src/modules/ante/models/CTEParsoidDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import TemplateInsertEvent from '../events/TemplateInsertEvent';
import { CTEParsoidTransclusionTemplateNode } from './CTEParsoidTransclusionTemplateNode';
import TemplateFactory from './TemplateFactory';
import moveToStart from '../../../util/moveToStart';
import RowedAttributionNotice from './RowedAttributionNotice';
import organize from '../../../util/organize';

/**
* An object containing an {@link HTMLIFrameElement} along with helper functions
Expand Down Expand Up @@ -111,6 +113,15 @@ export default class CTEParsoidDocument extends ParsoidDocument {
return notices;
}

findRowedNoticesByHref(): Record<string, RowedAttributionNotice<any>[]> {
return organize(
this.findNotices().filter(
v => v instanceof RowedAttributionNotice
) as RowedAttributionNotice<any>[],
(v) => v.node.getTarget().href
);
}

/**
* Finds this document's {{copied}} notices.
*
Expand Down
8 changes: 6 additions & 2 deletions src/modules/ante/models/TemplateMerger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type CopiedTemplate from './templates/CopiedTemplate';
import RowedAttributionNotice from './RowedAttributionNotice';
import { AttributionNoticeRow } from './AttributionNoticeRow';

/**
* Merges templates together. Its own class to avoid circular dependencies.
Expand All @@ -13,11 +14,14 @@ export default class TemplateMerger {
* @param pivot The template to merge into. If not supplied, the first template
* in the list will be used.
*/
static copied( templateList: CopiedTemplate[], pivot?: CopiedTemplate ) {
static merge<T extends RowedAttributionNotice<any>>( templateList: T[], pivot?: T ) {
pivot = pivot ?? templateList[ 0 ];
while ( templateList.length > 0 ) {
const template = templateList[ 0 ];
if ( template !== pivot ) {
if ( template.node.getTarget().href !== pivot.node.getTarget().href ) {
throw new Error("Attempted to merge incompatible templates.");
}
pivot.merge( template, { delete: true } );
}
// Pop the pivot template out of the list.
Expand Down
42 changes: 22 additions & 20 deletions src/modules/ante/ui/CopiedTemplateEditorDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,27 +235,28 @@ function initCopiedTemplateEditorDialog() {
invisibleLabel: true,
label: mw.msg( 'deputy.ante.mergeAll' ),
title: mw.msg( 'deputy.ante.mergeAll' ),
disabled: true
} );
// TODO: Repair mergeButton
this.mergeButton.on( 'click', () => {
const notices = this.parsoid.findNoticeType( 'copied' );
if ( notices.length > 1 ) {
return OO.ui.confirm(
const notices = this.parsoid.findRowedNoticesByHref();
const noticeCount = Object.values(notices)
.filter( v => v.length > 1 )
.reduce( (p, n) => p + n.length, 0 );
return noticeCount ?
OO.ui.confirm(
mw.message(
'deputy.ante.mergeAll.confirm',
`${notices.length}`
`${noticeCount}`
).text()
).done( ( confirmed: boolean ) => {
if ( !confirmed ) {
return;
}

TemplateMerger.copied( notices );
} );
} else {
return OO.ui.alert( 'There are no templates to merge.' );
}
for ( const noticeSet of Object.values(notices)) {
TemplateMerger.merge(noticeSet);
}
} ) :
OO.ui.alert( 'There are no templates to merge.' );
} );

const resetButton = new OO.ui.ButtonWidget( {
Expand Down Expand Up @@ -322,16 +323,16 @@ function initCopiedTemplateEditorDialog() {
} );

this.layout.on( 'remove', () => {
const notices = this.parsoid.findNotices();
// TODO: Repair mergeButton
// this.mergeButton.setDisabled( notices.length < 2 );
deleteButton.setDisabled( notices.length === 0 );
this.mergeButton.setDisabled(
!Object.values(this.parsoid.findRowedNoticesByHref()).some( v => v.length > 1 )
);
deleteButton.setDisabled( this.parsoid.findNotices().length === 0 );
} );
this.parsoid.addEventListener( 'templateInsert', () => {
const notices = this.parsoid.findNotices();
// TODO: Repair mergeButton
// this.mergeButton.setDisabled( notices.length < 2 );
deleteButton.setDisabled( notices.length === 0 );
this.mergeButton.setDisabled(
!Object.values(this.parsoid.findRowedNoticesByHref()).some( v => v.length > 1 )
);
deleteButton.setDisabled( this.parsoid.findNotices().length === 0 );
} );

this.$overlay.append(
Expand Down Expand Up @@ -438,7 +439,8 @@ function initCopiedTemplateEditorDialog() {

// Recheck state of merge button
this.mergeButton.setDisabled(
( this.parsoid.findNoticeType( 'copied' ).length ?? 0 ) < 2
!Object.values(this.parsoid.findRowedNoticesByHref())
.some( v => v.length > 1 )
);

process.next( () => {
Expand Down
2 changes: 1 addition & 1 deletion src/modules/ante/ui/RowPageShared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function renderMergePanel<T extends SupportedAttributionNoticeType>(
).done( ( confirmed: boolean ) => {
if ( confirmed ) {
// Recursively merge all templates
TemplateMerger.copied(
TemplateMerger.merge(
notices as any,
parentTemplate as any
);
Expand Down
16 changes: 16 additions & 0 deletions src/util/organize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export default function organize<T>(
objects: T[],
keyer: ( pivot: T ) => string
): Record<string, T[]> {
const finalObj: Record<string, T[]> = {};

for (const obj of objects) {
const key = keyer( obj );
if (!finalObj[key]) {
finalObj[key] = [];
}
finalObj[key].push(obj);
}

return finalObj;
}

0 comments on commit 2374c07

Please sign in to comment.