Skip to content

Commit

Permalink
Merge branch 'master' into beta
Browse files Browse the repository at this point in the history
* master:
  MBS-12870: Trap focus inside the Popover component (#2826)
  MBS-12863: Tooltips too far to the left (#2819)
  MBS-12888: Check ended when copying end date
  Actually look at stringy dates with isDateEmpty
  Autocomplete2: For "noop" actions, hide the menu instead
  MBS-12872: Autocomplete2: Don't focus the first item unless searching
  MBS-12885: Instrument disappears after adding another
  Sort attributes passed to fromDistinctAscArray
  MBS-12874: Don't split new relationships with one instrument or vocal
  • Loading branch information
mwiencek committed Feb 8, 2023
2 parents 8d2fc18 + 50a7a28 commit fadb8a7
Show file tree
Hide file tree
Showing 17 changed files with 386 additions and 42 deletions.
7 changes: 3 additions & 4 deletions root/static/scripts/common/components/Autocomplete2.js
Original file line number Diff line number Diff line change
Expand Up @@ -551,11 +551,9 @@ const Autocomplete2 = (React.memo(<+T: EntityItemT>(

case 'Enter':
case 'Tab': {
if (isOpen) {
if (isOpen && highlightedItem) {
event.preventDefault();
if (highlightedItem) {
selectItem(highlightedItem);
}
selectItem(highlightedItem);
}
break;
}
Expand Down Expand Up @@ -822,6 +820,7 @@ const Autocomplete2 = (React.memo(<+T: EntityItemT>(
? 'visible'
: 'hidden',
}}
tabIndex="-1"
>
{disabled ? null : menuItemElements}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ export const HIGHLIGHT_PREVIOUS_ITEM = {
type: 'highlight-previous-item',
};

export const NOOP = {
type: 'noop',
};

export const SHOW_MENU = {
type: 'set-menu-visibility',
value: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import {bracketedText} from '../../utility/bracketed.js';

import {
NOOP,
HIDE_MENU,
SEARCH_AGAIN,
SHOW_MORE_RESULTS,
TOGGLE_INDEXED_SEARCH,
Expand Down Expand Up @@ -71,19 +71,19 @@ export const MENU_ITEMS: {+[name: string]: ActionItemT<empty>, ...} = {
},
LOOKUP_ERROR: {
type: 'action',
action: NOOP,
action: HIDE_MENU,
id: 'lookup-error',
name: N_l('An error occurred while looking up the MBID you entered.'),
},
LOOKUP_TYPE_ERROR: {
type: 'action',
action: NOOP,
action: HIDE_MENU,
id: 'lookup-type-error',
name: N_l('The type of entity you pasted isn’t supported here.'),
},
NO_RESULTS: {
type: 'action',
action: NOOP,
action: HIDE_MENU,
id: 'no-results',
name: () => bracketedText(l('No results')),
},
Expand Down
14 changes: 4 additions & 10 deletions root/static/scripts/common/components/Autocomplete2/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ export function runReducer<+T: EntityItemT>(
const wasOpen = state.isOpen;
let updateItems = false;
let updateStatusMessage = false;
let highlightFirstIndex = false;

switch (action.type) {
case 'change-entity-type': {
Expand Down Expand Up @@ -417,9 +418,6 @@ export function runReducer<+T: EntityItemT>(
break;
}

case 'noop':
break;

case 'toggle-add-entity-dialog': {
state.isAddEntityDialogOpen = action.isOpen;
break;
Expand Down Expand Up @@ -477,7 +475,7 @@ export function runReducer<+T: EntityItemT>(
* where "Show more" was clicked).
*/
} else {
state.highlightedIndex = 0;
highlightFirstIndex = true;
}

state.results = newResults;
Expand Down Expand Up @@ -563,6 +561,7 @@ export function runReducer<+T: EntityItemT>(
if (nonEmpty(newInputValue)) {
// We'll display "(No results)" even if `results` is null.
state.isOpen = true;
highlightFirstIndex = true;
}
} else {
state.results = null;
Expand Down Expand Up @@ -595,9 +594,8 @@ export function runReducer<+T: EntityItemT>(
state.statusMessage = generateStatusMessage(state);
}

// Highlight the first item by default.
const isOpen = state.isOpen;
if (isOpen && (!wasOpen || state.highlightedIndex < 0)) {
if (isOpen && highlightFirstIndex) {
state.highlightedIndex = getFirstHighlightableIndex(state);
} else if (wasOpen && !isOpen) {
state.highlightedIndex = -1;
Expand All @@ -608,10 +606,6 @@ export default function reducer<+T: EntityItemT>(
state: StateT<T>,
action: ActionT<T>,
): StateT<T> {
if (action.type === 'noop') {
return state;
}

const nextState = {...state};
runReducer<T>(nextState, action);
return nextState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export type ActionT<+T: EntityItemT> =
| { +type: 'highlight-index', +index: number }
| { +type: 'highlight-next-item' }
| { +type: 'highlight-previous-item' }
| { +type: 'noop' }
| { +type: 'reset-menu' }
| { +type: 'select-item', +item: ItemT<T> }
| { +type: 'set-menu-visibility', +value: boolean }
Expand Down
2 changes: 1 addition & 1 deletion root/static/scripts/common/components/Popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const Popover = (props: PropsT): React.Portal => {
dialogRef={dialogRef}
onEscape={closeAndReturnFocus}
siblings={<div data-popper-arrow />}
trapFocus={false}
trapFocus
>
{buildChildren(closeAndReturnFocus)}
</Dialog>,
Expand Down
8 changes: 1 addition & 7 deletions root/static/scripts/common/utility/isDateEmpty.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,9 @@
* later version: http://www.gnu.org/licenses/gpl-2.0.txt
*/

declare type PartialDateStringsT = {
+day?: string,
+month?: string,
+year?: string,
};

export default function isDateEmpty(
date: ?PartialDateT | ?PartialDateStringsT,
): boolean %checks {
return (date == null) ||
(date.year == null && date.month == null && date.day == null);
(empty(date.year) && empty(date.month) && empty(date.day));
}
10 changes: 9 additions & 1 deletion root/static/scripts/edit/components/DateRangeFieldset.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,21 @@ export function runReducer(
const year = String(beginDateFields.year.value ?? '');
const month = String(beginDateFields.month.value ?? '');
const day = String(beginDateFields.day.value ?? '');
const newEndDate: PartialDateStringsT =
{day: day, month: month, year: year};
runFormRowPartialDateReducer(
subfields.end_date,
{
date: {day: day, month: month, year: year},
date: newEndDate,
type: 'set-date',
},
);
if (!isDateEmpty(newEndDate)) {
runReducer(
state,
{enabled: true, type: 'set-ended'},
);
}
validateDatePeriod(state);
applyAllPendingErrors(state);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,11 +446,22 @@ export function runReducer(
const updates = [];

if (oldRelationshipState != null) {
updates.push({
relationship: oldRelationshipState,
throwIfNotExists: false,
type: REMOVE_RELATIONSHIP,
});
/*
* The old relationship state must be removed first in a separate
* `updateRelationships` call, because its presence affects other
* functions that act on the current state, like
* `mergeRelationship`.
*/
updateRelationships(
writableState,
[
{
relationship: oldRelationshipState,
throwIfNotExists: false,
type: REMOVE_RELATIONSHIP,
},
],
);
}

updates.push(...getUpdatesForAcceptedRelationship(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type {

import {cloneRelationshipState} from './cloneState.js';
import {
areLinkAttributesEqual,
compareLinkAttributeIds,
compareLinkAttributeRootIds,
compareLinkAttributes,
Expand Down Expand Up @@ -238,6 +239,21 @@ export default function splitRelationshipByAttributes(
}
}

/*
* If (1) this is a new relationship, (2) `newAttributesToSplit` contains a
* single attribute, and (3) it's identical to `newAttributes`, then
* there's nothing to split; we can just return the relationship as-is.
* (Triggered MBS-12874 in a roundabout way.)
*/
if (
origRelationship == null &&
newAttributesToSplit != null &&
newAttributesToSplit.size === 1 &&
areLinkAttributesEqual(newAttributes, newAttributesToSplit)
) {
newAttributesToSplit = null;
}

for (const linkAttribute of tree.iterate(newAttributesToSplit)) {
const newRelationship = cloneRelationshipState(relationship);
newRelationship._lineage = [
Expand Down
49 changes: 46 additions & 3 deletions root/static/scripts/tests/relationship-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {

import {defaultContext} from '../../../context.mjs';
import linkedEntities from '../common/linkedEntities.mjs';
import {uniqueNegativeId} from '../common/utility/numbers.js';
import {
createInitialState,
reducer,
Expand Down Expand Up @@ -271,7 +272,7 @@ test('merging duplicate relationships', function (t) {
});

test('splitRelationshipByAttributes', function (t) {
t.plan(14);
t.plan(16);

const lyre = {
type: {
Expand Down Expand Up @@ -371,7 +372,7 @@ test('splitRelationshipByAttributes', function (t) {
// Add a new credit to the existing lyre attribute.
{...lyre, credited_as: 'LYRE'},
drums,
]),
].sort(compareLinkAttributeIds)),
compareLinkAttributeIds,
onConflictUseSecondValue,
),
Expand Down Expand Up @@ -595,7 +596,12 @@ test('splitRelationshipByAttributes', function (t) {
...existingRelationship4,
_original: existingRelationship4,
_status: REL_STATUS_EDIT,
attributes: tree.fromDistinctAscArray([drums, leadVocals]),
attributes: tree.fromDistinctAscArray(
[
drums,
leadVocals,
].sort(compareLinkAttributeIds),
),
};

splitRelationships =
Expand Down Expand Up @@ -626,6 +632,43 @@ test('splitRelationshipByAttributes', function (t) {
),
'second relationship contains drums',
);

/*
* This test attempts to split a newly-added relationship with a single
* vocal attribute. Since there's no need to split a single attribute,
* we should return the same relationship as-is (MBS-12874).
*/

const newRelationship1: RelationshipStateT = {
_lineage: [],
_original: null,
_status: REL_STATUS_ADD,
attributes: tree.fromDistinctAscArray([leadVocals]),
begin_date: null,
editsPending: false,
end_date: null,
ended: false,
entity0: artist,
entity0_credit: '',
entity1: event,
entity1_credit: '',
id: uniqueNegativeId(),
linkOrder: 0,
linkTypeID: 798,
};
Object.freeze(newRelationship1);

splitRelationships =
splitRelationshipByAttributes(newRelationship1);

t.ok(
splitRelationships.length === 1,
'one relationships is returned',
);
t.ok(
splitRelationships[0] === newRelationship1,
'the same relationship is returned back',
);
});

function addRelationships(
Expand Down
10 changes: 9 additions & 1 deletion root/static/styles/relationship-editor.less
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
#content.rel-editor #tracklist td {vertical-align: top;}
#content.rel-editor #tracklist td.midcol {vertical-align: middle; font-size: @small-text;}
#content.rel-editor #tracklist input[type="checkbox"] {vertical-align: middle;}
#content.rel-editor #batch-tools {width: 100%; margin: 0.8em;}
#content.rel-editor #batch-tools {
width: 100%;
margin: 0.8em;
/*
* Center the tooltips so that they're less likely to clip
* outside the viewport.
*/
.tooltip-container { left: 50%; }
}
#content.rel-editor div.ars {padding: 0; margin: 0.5em 0; margin-left: 1.5em;}
#content.rel-editor #release-rels {margin-top: 1em;}

Expand Down
2 changes: 1 addition & 1 deletion root/static/styles/tooltip.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
visibility: hidden;
position: absolute;
top: -12px;
left: 50%;
left: 100%;
z-index: 1000;

.tooltip-triangle-mixin {
Expand Down
6 changes: 6 additions & 0 deletions root/types/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ declare type PartialDateT = {
+year: number | null,
};

declare type PartialDateStringsT = {
+day?: string,
+month?: string,
+year?: string,
};

declare type TypeRoleT<T> = {
+typeID: number | null,
+typeName?: string,
Expand Down
2 changes: 2 additions & 0 deletions t/selenium.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,8 @@ const seleniumTests = [
{name: 'MBS-11730.json5', login: true},
{name: 'MBS-11735.json5', login: true},
{name: 'MBS-12859.json5', login: true},
{name: 'MBS-12874.json5', login: true},
{name: 'MBS-12885.json5', login: true},
{name: 'Artist_Credit_Editor.json5', login: true},
{name: 'Autocomplete2.json5'},
{name: 'CAA.json5', login: true},
Expand Down
Loading

0 comments on commit fadb8a7

Please sign in to comment.