Skip to content

Commit

Permalink
Merge branch 'master' into beta
Browse files Browse the repository at this point in the history
* master:
  Update translations from Transifex
  Update POT files using the production database
  Eslint: autosort imports by path (#2603)
  MBS-11388: Convert the relationship editors to React
  Autocomplete: Sync recent entities with Autocomplete2
  WS::js::Edit: Return error for invalid date ranges
  Move is_date_range_valid to MB::S::Validation
  t/sql/initial.sql: Sync series_type with production
  Autocomplete2: Use item name for input value
  DateRangeFieldset: Use "Copy to end date" title string
  Dialog: Prevent mouse and tab keypress events from propagating
  Autocomplete2: Add a colon after the label text
  Autocomplete2: Allow configuring the input label style
  Autocomplete2: Allow configuring the input class
  Autocomplete2: Allow passing disabled through initial state
  Autocomplete2: Allow passing containerClass through initial state
  Popover: Allow configuring the Dialog className
  DeletedLink: Allow configuring the className
  ButtonPopover: Page scrollbar clicks should not close the popover
  ButtonPopover: Allow configuring disabled, id props
  Define .buttons-right class
  Autocomplete2: Get active user from the global JS namespace
  Autocomplete2: Maintain static items list in set-recent-items
  Modal: Center horizontally
  Autocomplete2: Always show menu after clicking the input
  Add Flow libdefs for tape
  Skip links when moving focus into dialogs
  Forward EntityLink props
  Move MBS-6129 test to linkPhrase.js
  forGrouping should take orderable_direction into account
  pThrottle: Remove unused Map
  Autocomplete2: Handle recent items with fake IDs
  Autocomplete2: Don't close menu when using the scrollbar
  Add EMPTY_PARTIAL_DATE constant
  Move external links state initialization into the component
  Allow hydrating components with no props
  Consistently access source entity data from JS
  Factor out usePagedMediumTable from release pages
  FieldErrors: Factor out FieldErrorsList
  Move DISPLAY_NONE_STYLE to common/constants.js
  Controller::Release: Factor out _load_mediums_limited
  Allow customizing relationship entity display
  .flowconfig: turn on unnecessary-invariant lint
  .eslintrc.yaml: turn off flowtype/generic-spacing
  WS::js::Edit: Return created relationship IDs
  WS::js::Edit: Support EDIT_RELATIONSHIPS_REORDER
  WS::js::Edit: Support linkOrder on EDIT_RELATIONSHIP_CREATE
  Pass link_type directly to Edit::Relationship::Reorder
  EnterEditNote.js: allow use as controlled component
  EnterEdit.js: allow use as controlled component
  Add missing keys to EntityLink parts
  Add createFastObjectCloneFunction utility
  Add script for creating empty core entity objects
  Factor out numeric uniqueId utility
  Convert is_database_row_id to JavaScript
  Change source_type/target_type CoreEntityTypeT
  Serialize the Catalyst request method
  Add yearInputRef to FormRowPartialDate
  Add new `createCompoundField` function
  createCompoundField -> createCompoundFieldFromObject
  Allow using div.row styling outside forms
  Move release-editor specific CSS to release-editor.less
  Check for empty dates in relationshipDateText
  expand2react: Remove a use of `any`
  /ws/js/type-info
  Change isDateValid to take a partial date object
  Add sortedFindOrInsert
  Use existing getSortName in groupRelationships.js
  Move isLinkTypeDirectionOrderable to own module
  Update POT files using the production database
  MBS-12335: Link to attribute docs from reltype docs (#2499)
  MBS-12592: Convert cdstub/import to React
  Make InlineSubmitButton reusable
  MBS-12590: Convert cdstub/logged_in to React
  Show CD stub logged in error as last option
  MBS-12591: Actually stop logged-in users from entering CD stubs
  MBS-12587: Convert cdstub/error to React (#2631)
  MBS-12582: Convert cdstub/index to React
  MBS-12580: Convert cdstub/cdstub to React
  MBS-12581: Convert cdstub/layout and /header to React
  Make calculateFullToc reusable
  MBS-12578: Avoid possible ISEs on cdtoc/remove
  MBS-12577: Convert cdtoc/remove to React
  Make CDTocLink content default to cdToc.disc
  Remove now unused TT macro track_duration_changes
  MBS-12575: Convert cdtoc/attach_confirm to React
  MBS-12576: Improve erroring with wrong IDs on CDTOC pages
  MBS-12574: Convert cdtoc/set_durations to React (#2622)
  MBS-12572: Convert cdtoc/info to React (#2621)
  MBS-12563: Block smart links: strm.to (#2625)
  MBS-12567: Fail gracefully when loading unsupported class (#2618)
  MBS-12589: Return if direct search query times out (#2633)
  MBS-12586: Adapt Brahms/IRCAM cleanup to new link style (#2629)
  MBS-12588: Escape user-provided disc ID in regex (#2632)
  Fix building CSS in production Docker images (#2623)
  MBS-12584: Block smart links: onerpm.link
  MBS-12585: Block smart links: withkoji.com
  MBS-12135: Convert the notes received page to React
  Add flow types to setCookie
  Extract reusable getEditHeaderClass function
  MBS-10364: Convert release merge page to React (#1448)
  MBS-12562: Redirect row id url to gid url for works too (#2617)
  Rename edit_template_react now that it's the only one
  Remove conditional now all edits are React
  MBS-12134: Convert the cancel edit page to React
  MBS-12566: Fix incorrect URL shortener detection
  Remove seemingly unused template
  Remove unused TT macro medium_description
  Remove unused TT macro medium_link
  Remove unused TT macro uri_escape
  Remove unused TT macro yesno
  Remove unused TT macro N_ln
  Remove unused TT macro expand
  Remove unused TT macro entity_exists
  Remove unused TT macro link_tag
  Remove unused TT macro link_isrc
  Remove unused TT macro link_iswc
  Remove unused TT macro link_searchable_property
  Remove unused TT macro entity_label
  Remove unused TT macro format_entity_type_name
  Remove unused TT macro format_plural_entity_type_name
  Remove unused TT macro quality_name
  Remove unused TT macro vote_tally
  Remove unused TT macro error
  Remove unused TT macro relationship_target_links
  Remove unused TT macro release_event
  Remove unused TT macro format_isni
  Remove unused TT macro link_type_cardinality_name
  Remove unused TT macro orderable_direction_name
  Remove unused TT macro bugtracker_url
  Remove no longer embedded Aliases
  Remove no longer embedded GroupedTrackRelationships
  Remove no longer embedded RelationshipsTable
  Remove no longer embedded Annotation
  Remove no longer embedded Relationship & Relationships
  Remove no longer embedded WikipediaExtract
  Remove no longer embedded ReleaseEventsDiff
  Remove no longer embedded RelationshipDiff
  Remove no longer embedded CritiqueBrainzReview
  Move isShortenedUrl to its own module
  MBS-12548: Don't update replication_control in MBS-12508 script
  MBS-12548: Handle conflicting tag names in MBS-12508 script
  • Loading branch information
mwiencek committed Sep 14, 2022
2 parents cae71c5 + 255b1eb commit 4e2eec1
Show file tree
Hide file tree
Showing 719 changed files with 36,337 additions and 23,371 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Expand Up @@ -3,6 +3,7 @@ flow-typed/npm/@sentry/*.js
flow-typed/npm/he_*.js
flow-typed/npm/react-dom_*.js
flow-typed/npm/redux_*.js
flow-typed/npm/tape_*.js
perl_modules/**/*.js
root/static/build/**/*.js
root/static/lib/**/*.js
Expand Down
26 changes: 23 additions & 3 deletions .eslintrc.yaml
Expand Up @@ -8,6 +8,7 @@ plugins:
- flowtype
- fb-flow
- react-hooks
- simple-import-sort

env:
browser: true
Expand Down Expand Up @@ -214,7 +215,7 @@ rules:
require-yield: error
rest-spread-spacing: [warn, never]
# sort-imports does not support Flow 'type' imports, so we use the
# import/order rule from eslint-plugin-import instead.
# imports rule from simple-import-sort instead.
sort-imports: off
template-curly-spacing: [warn, never]

Expand All @@ -230,7 +231,6 @@ rules:
import/no-duplicates: warn
import/no-dynamic-require: error
import/no-unresolved: error
import/order: [warn, {newlines-between: always}]

#######################
# eslint-plugin-react #
Expand Down Expand Up @@ -326,7 +326,7 @@ rules:
flowtype/boolean-style: [warn, boolean]
flowtype/define-flow-type: warn
flowtype/delimiter-dangle: [warn, always-multiline]
flowtype/generic-spacing: [warn, never]
flowtype/generic-spacing: off
flowtype/no-dupe-keys: error
flowtype/no-flow-fix-me-comments: off
flowtype/no-mutable-array: off
Expand Down Expand Up @@ -357,3 +357,23 @@ rules:

react-hooks/exhaustive-deps: error
react-hooks/rules-of-hooks: error

####################################
# eslint-plugin-simple-import-sort #
####################################

simple-import-sort/imports: [warn, {groups: [
# Node.js builtins. You could also generate this regex if you use a `.js` config.
# For example: `^(${require("module").builtinModules.join("|")})(/|$)`
["^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)"],
# Packages.
["^@?\\w"],
# Side effect imports.
["^\\u0000"],
# Parent imports. Put `..` last.
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
# Other relative imports. Put same-folder imports and `.` last.
["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"],
],
}]
simple-import-sort/exports: warn
1 change: 1 addition & 0 deletions .flowconfig
Expand Up @@ -15,6 +15,7 @@
./root/vars.js

[lints]
unnecessary-invariant=error

[options]
autoimports=true
Expand Down
4 changes: 3 additions & 1 deletion admin/sql/updates/20220720-mbs-12508.sh
Expand Up @@ -93,6 +93,7 @@ echo `date`: Importing tag data from latest dump
--table release_group_tag \
--table series_tag \
--table work_tag \
--noupdate-replication-control \
"$DUMP_FILE"

echo `date`: Restoring saved tag data from tmp tables
Expand Down Expand Up @@ -144,8 +145,9 @@ INSERT INTO work_tag (SELECT * FROM tmp_work_tag_mbs_12508)
ON CONFLICT (work, tag) DO UPDATE SET count = excluded.count, last_updated = excluded.last_updated;
DROP TABLE tmp_work_tag_mbs_12508;
DELETE FROM tag WHERE id IN (SELECT id FROM tmp_tag_mbs_12508);
INSERT INTO tag (SELECT * FROM tmp_tag_mbs_12508)
ON CONFLICT (id) DO UPDATE SET ref_count = excluded.ref_count;
ON CONFLICT (name) DO UPDATE SET id = excluded.id, ref_count = excluded.ref_count;
DROP TABLE tmp_tag_mbs_12508;
SQL
) || ( echo "$OUTPUT" && exit 1 )
Expand Down
26 changes: 26 additions & 0 deletions docker/scripts/compile_resources_for_image.sh
@@ -0,0 +1,26 @@
#!/usr/bin/env bash

# Explanatory production notes:
#
# Building webpack/server.config.mjs is necessary in order to generate
# *.css files in the Docker image, which are extracted from the image
# in a Jenkins job and synced to a static resources volume on our gateway
# servers.
#
# Building the server-side JS requires a DBDefs file, though, and one isn't
# available when building the image. Our production DBDefs files are stored
# in a private repository and copied into the containers at runtime.
#
# Since the .less files aren't affected by any specific DBDefs configuration,
# and because the server JS is rebuilt anyway after the container starts, we
# can temporarily use the sample DBDefs file in the repository to allow the
# CSS to build into the image, and then remove the useless server JS files
# which contain sample configuration.

cp lib/DBDefs.pm.sample lib/DBDefs.pm

carton exec -- ./script/compile_resources.sh

rm -f \
lib/DBDefs.pm \
root/static/build/{jed-*.source.js,server.js}
3 changes: 2 additions & 1 deletion docker/templates/macros.m4
Expand Up @@ -36,12 +36,13 @@ m4_define(
`m4_dnl
install_javascript(`$1')

copy_mb(``docker/scripts/compile_resources_for_image.sh docker/scripts/'')
copy_mb(``root/ root/'')
copy_mb(``script/compile_resources.sh script/dbdefs_to_js.pl script/start_renderer.pl script/xgettext.js script/'')
copy_mb(``webpack/ webpack/'')

ENV NODE_ENV production
RUN sudo_mb(``carton exec -- ./script/compile_resources.sh client'')
RUN sudo_mb(``./docker/scripts/compile_resources_for_image.sh'')
RUN chown_mb(``/tmp/ttc'')')

m4_define(
Expand Down
111 changes: 111 additions & 0 deletions flow-typed/npm/tape_v4.x.x.js
@@ -0,0 +1,111 @@
// flow-typed signature: d8729919aecb7f7dee0289098715064e
// flow-typed version: dd3f7702d9/tape_v4.x.x/flow_>=v0.104.x

/* eslint-disable */

declare type tape$TestOpts = {
skip: boolean,
timeout?: number,
...
} | {
skip?: boolean,
timeout: number,
...
};


declare type tape$TestCb = (t: tape$Context) => mixed;
declare type tape$TestFn = (a: string | tape$TestOpts | tape$TestCb, b?: tape$TestOpts | tape$TestCb, c?: tape$TestCb) => void;

declare interface tape$Context {
fail(msg?: string): void,
pass(msg?: string): void,

error(err: mixed, msg?: string): void,
ifError(err: mixed, msg?: string): void,
ifErr(err: mixed, msg?: string): void,
iferror(err: mixed, msg?: string): void,

ok(value: mixed, msg?: string): void,
true(value: mixed, msg?: string): void,
assert(value: mixed, msg?: string): void,

notOk(value: mixed, msg?: string): void,
false(value: mixed, msg?: string): void,
notok(value: mixed, msg?: string): void,

// equal + aliases
equal(actual: mixed, expected: mixed, msg?: string): void,
equals(actual: mixed, expected: mixed, msg?: string): void,
isEqual(actual: mixed, expected: mixed, msg?: string): void,
is(actual: mixed, expected: mixed, msg?: string): void,
strictEqual(actual: mixed, expected: mixed, msg?: string): void,
strictEquals(actual: mixed, expected: mixed, msg?: string): void,

// notEqual + aliases
notEqual(actual: mixed, expected: mixed, msg?: string): void,
notEquals(actual: mixed, expected: mixed, msg?: string): void,
notStrictEqual(actual: mixed, expected: mixed, msg?: string): void,
notStrictEquals(actual: mixed, expected: mixed, msg?: string): void,
isNotEqual(actual: mixed, expected: mixed, msg?: string): void,
isNot(actual: mixed, expected: mixed, msg?: string): void,
not(actual: mixed, expected: mixed, msg?: string): void,
doesNotEqual(actual: mixed, expected: mixed, msg?: string): void,
isInequal(actual: mixed, expected: mixed, msg?: string): void,

// deepEqual + aliases
deepEqual(actual: mixed, expected: mixed, msg?: string): void,
deepEquals(actual: mixed, expected: mixed, msg?: string): void,
isEquivalent(actual: mixed, expected: mixed, msg?: string): void,
same(actual: mixed, expected: mixed, msg?: string): void,

// notDeepEqual
notDeepEqual(actual: mixed, expected: mixed, msg?: string): void,
notEquivalent(actual: mixed, expected: mixed, msg?: string): void,
notDeeply(actual: mixed, expected: mixed, msg?: string): void,
notSame(actual: mixed, expected: mixed, msg?: string): void,
isNotDeepEqual(actual: mixed, expected: mixed, msg?: string): void,
isNotDeeply(actual: mixed, expected: mixed, msg?: string): void,
isNotEquivalent(actual: mixed, expected: mixed, msg?: string): void,
isInequivalent(actual: mixed, expected: mixed, msg?: string): void,

// deepLooseEqual
deepLooseEqual(actual: mixed, expected: mixed, msg?: string): void,
looseEqual(actual: mixed, expected: mixed, msg?: string): void,
looseEquals(actual: mixed, expected: mixed, msg?: string): void,

// notDeepLooseEqual
notDeepLooseEqual(actual: mixed, expected: mixed, msg?: string): void,
notLooseEqual(actual: mixed, expected: mixed, msg?: string): void,
notLooseEquals(actual: mixed, expected: mixed, msg?: string): void,

throws(fn: Function, expected?: RegExp | Function, msg?: string): void,
doesNotThrow(fn: Function, expected?: RegExp | Function, msg?: string): void,

timeoutAfter(ms: number): void,

skip(msg?: string): void,
plan(n: number): void,
onFinish(fn: Function): void,
end(): void,
comment(msg: string): void,
test: tape$TestFn,
}


declare module 'tape' {
declare type TestHarness = Tape;
declare type StreamOpts = { objectMode?: boolean, ... };

declare type Tape = {
(a: string | tape$TestOpts | tape$TestCb, b?: tape$TestCb | tape$TestOpts, c?: tape$TestCb, ...rest: Array<void>): void,
test: tape$TestFn,
skip: (name: string, cb?: tape$TestCb) => void,
createHarness: () => TestHarness,
createStream: (opts?: StreamOpts) => stream$Readable,
only: (a: string | tape$TestOpts | tape$TestCb, b?: tape$TestCb | tape$TestOpts, c?: tape$TestCb, ...rest: Array<void>) => void,
...
};

declare module.exports: Tape;
}
2 changes: 2 additions & 0 deletions lib/MusicBrainz/Server.pm
Expand Up @@ -780,6 +780,7 @@ sub TO_JSON {
release_cdtoc_count
server_details
server_languages
source_entity
subscribed
to_merge
top_tags
Expand Down Expand Up @@ -873,6 +874,7 @@ sub TO_JSON {
req => {
body_params => $req->body_params,
headers => \%headers,
method => uc($req->method),
query_params => $req->query_params,
secure => boolean_to_json($req->secure),
uri => '' . $req->uri,
Expand Down
67 changes: 50 additions & 17 deletions lib/MusicBrainz/Server/Controller/CDStub.pm
Expand Up @@ -5,8 +5,11 @@ BEGIN { extends 'MusicBrainz::Server::Controller'; }

use aliased 'MusicBrainz::Server::Entity::CDTOC';

use MusicBrainz::Server::Data::Utils qw( boolean_to_json );
use MusicBrainz::Server::Entity::Util::JSON qw( to_json_array );
use MusicBrainz::Server::Translation qw( l );
use MusicBrainz::Server::ControllerUtils::CDTOC qw( add_dash );
use MusicBrainz::Server::ControllerUtils::JSON qw( serialize_pager );

with 'MusicBrainz::Server::Controller::Role::Load' => {
model => 'CDStub',
Expand All @@ -23,20 +26,20 @@ sub _load

if (!is_valid_discid($id)) {
$c->stash(
template => 'cdstub/error.tt',
not_valid => 1,
discid => $id
);
component_path => 'cdstub/DiscIdNotValid.js',
component_props => { discId => $id },
current_view => 'Node',
);
$c->detach;
return;
}
my $cdstub = $c->model('CDStub')->get_by_discid($id);
if (!$cdstub) {
$c->stash(
template => 'cdstub/error.tt',
not_found => 1,
discid => $id
);
component_path => 'cdstub/CDStubNotFound.js',
component_props => { discId => $id },
current_view => 'Node',
);
$c->detach;
return;
}
Expand All @@ -52,12 +55,9 @@ sub add : Path('add') DenyWhenReadonly
{
my ($self, $c) = @_;

if ($c->user_exists) {
$c->res->code(403);
$c->stash( template => 'cdstub/logged_in.tt' );
}
my $passed_toc = $c->req->query_params->{toc};
my $toc = CDTOC->new_from_toc($passed_toc);

my $toc = CDTOC->new_from_toc( $c->req->query_params->{toc} );
if (!$toc) {
$c->stash( message => l('The required TOC parameter was invalid or not present') );
$c->detach('/error_400');
Expand All @@ -75,6 +75,17 @@ sub add : Path('add') DenyWhenReadonly
$c->detach;
}

if ($c->user_exists) {
$c->res->code(403);

$c->stash(
current_view => 'Node',
component_path => 'cdstub/CDStubAddWhileLoggedIn.js',
component_props => { cdToc => $passed_toc },
);
$c->detach;
}

my $form = $c->form(
form => 'CDStub',
init_object => {
Expand All @@ -99,7 +110,18 @@ sub show : Chained('load') PathPart('')
{
my ($self, $c) = @_;

$c->stash( template => 'cdstub/index.tt' );
my $cdstub = $c->stash->{cdstub};

my %props = (
cdstub => $cdstub->TO_JSON,
showArtists => boolean_to_json($c->stash->{show_artists}),
);

$c->stash(
current_view => 'Node',
component_path => 'cdstub/CDStubIndex.js',
component_props => \%props,
);
}

sub browse : Path('browse')
Expand Down Expand Up @@ -144,10 +166,21 @@ sub import : Chained('load') RequireAuth
$search_query = $form->field('query')->value;
}

my $artists = $self->_load_paged($c, sub {
$c->model('Search')->search('artist', $search_query, shift, shift);
});

my %props = (
artists => to_json_array($artists),
cdstub => $cdstub->TO_JSON,
form => $form->TO_JSON,
pager => serialize_pager($c->stash->{pager}),
);

$c->stash(
artists => $self->_load_paged($c, sub {
$c->model('Search')->search('artist', $search_query, shift, shift);
})
current_view => 'Node',
component_path => 'cdstub/ImportCDStub.js',
component_props => \%props,
);
}

Expand Down

0 comments on commit 4e2eec1

Please sign in to comment.