Compare commits
16 Commits
collection
...
zeus-old
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66aeb19d88 | ||
|
|
455aca85bd | ||
|
|
a29d794cbe | ||
|
|
bb3123772f | ||
|
|
46a20e1dcd | ||
|
|
993144b67a | ||
|
|
1f209848dc | ||
|
|
3dafe44fed | ||
|
|
767e75ca45 | ||
|
|
1d4db26f17 | ||
|
|
757cb9a956 | ||
|
|
5dc3726023 | ||
|
|
5b2f30227b | ||
|
|
ed94eee859 | ||
|
|
6eb271eee4 | ||
|
|
9fe205727c |
@@ -40,18 +40,9 @@ dotnet_naming_style.instance_field_style.capitalization = camel_case
|
|||||||
dotnet_naming_style.instance_field_style.required_prefix = _
|
dotnet_naming_style.instance_field_style.required_prefix = _
|
||||||
|
|
||||||
# Prefer "var" everywhere
|
# Prefer "var" everywhere
|
||||||
csharp_style_var_for_built_in_types = true
|
csharp_style_var_for_built_in_types = true:suggestion
|
||||||
csharp_style_var_when_type_is_apparent = true
|
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||||
csharp_style_var_elsewhere = true
|
csharp_style_var_elsewhere = true:suggestion
|
||||||
# Prefer "out" variables to be declared inline
|
|
||||||
csharp_style_inlined_variable_declaration = true
|
|
||||||
|
|
||||||
# Using directive is unnecessary.
|
|
||||||
dotnet_diagnostic.IDE0005.severity = error
|
|
||||||
# Use var instead of explicit type
|
|
||||||
dotnet_diagnostic.IDE0007.severity = error
|
|
||||||
# Inline variable declaration
|
|
||||||
dotnet_diagnostic.IDE0018.severity = error
|
|
||||||
|
|
||||||
# Stylecop Rules
|
# Stylecop Rules
|
||||||
dotnet_diagnostic.SA0001.severity = none
|
dotnet_diagnostic.SA0001.severity = none
|
||||||
@@ -270,7 +261,7 @@ dotnet_diagnostic.CA5397.severity = suggestion
|
|||||||
|
|
||||||
dotnet_diagnostic.SYSLIB0006.severity = none
|
dotnet_diagnostic.SYSLIB0006.severity = none
|
||||||
|
|
||||||
[*.{js,html,hbs,less,css,ts,tsx}]
|
[*.{js,html,js,hbs,less,css}]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|||||||
2
.gitattributes
vendored
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
# Explicitly set bash scripts to have unix endings
|
# Explicitly set bash scripts to have unix endings
|
||||||
*.sh text eol=lf
|
*.sh text eol=lf
|
||||||
distribution/osx/Radarr text eol=lf
|
macOS/Radarr text eol=lf
|
||||||
|
|
||||||
# Custom for Visual Studio
|
# Custom for Visual Studio
|
||||||
*.cs diff=csharp
|
*.cs diff=csharp
|
||||||
|
|||||||
13
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,5 +1,5 @@
|
|||||||
name: Bug Report
|
name: Bug Report
|
||||||
description: 'Report a new bug, if you are not 100% certain this is a bug please go to our Discord first'
|
description: 'Report a new bug, if you are not 100% certain this is a bug please go to our Reddit or Discord first'
|
||||||
labels: ['Type: Bug', 'Status: Needs Triage']
|
labels: ['Type: Bug', 'Status: Needs Triage']
|
||||||
body:
|
body:
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
@@ -65,18 +65,11 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Trace Logs? **Not Optional**
|
label: Trace Logs?
|
||||||
description: |
|
description: |
|
||||||
Trace Logs (https://wiki.servarr.com/radarr/troubleshooting#logging-and-log-files)
|
Trace Logs (https://wiki.servarr.com/radarr/troubleshooting#logging-and-log-files)
|
||||||
***Generally speaking, all bug reports MUST have trace logs provided.***
|
***Generally speaking, all bug reports must have trace logs provided.***
|
||||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||||
Additionally, any additional info? Screenshots? References? Anything that will give us more context about the issue you are encountering!
|
Additionally, any additional info? Screenshots? References? Anything that will give us more context about the issue you are encountering!
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Trace Logs have been provided as applicable. Reports will be closed if the required logs are not provided.
|
|
||||||
description: Trace logs are **generally required** and are not optional for all bug reports and contain `trace`. Info logs are invalid for bug reports and do not contain `debug` nor `trace`
|
|
||||||
options:
|
|
||||||
- label: I have read and followed the steps in the wiki link above and provided the required trace logs - the logs contain `trace` - that are relevant and show this issue.
|
|
||||||
required: true
|
|
||||||
|
|||||||
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -3,3 +3,6 @@ contact_links:
|
|||||||
- name: Support via Discord
|
- name: Support via Discord
|
||||||
url: https://radarr.video/discord
|
url: https://radarr.video/discord
|
||||||
about: Chat with users and devs on support and setup related topics.
|
about: Chat with users and devs on support and setup related topics.
|
||||||
|
- name: Support via Reddit
|
||||||
|
url: https://reddit.com/r/radarr
|
||||||
|
about: Discuss and search thru support topics.
|
||||||
|
|||||||
16
.github/label-actions.yml
vendored
@@ -1,16 +0,0 @@
|
|||||||
# Configuration for Label Actions - https://github.com/dessant/label-actions
|
|
||||||
|
|
||||||
'Type: Support':
|
|
||||||
comment: >
|
|
||||||
:wave: @{issue-author}, we use the issue tracker exclusively
|
|
||||||
for bug reports and feature requests. However, this issue appears
|
|
||||||
to be a support request. Please hop over onto our [Discord](https://radarr.video/discord).
|
|
||||||
close: true
|
|
||||||
close-reason: 'not planned'
|
|
||||||
|
|
||||||
'Status: Logs Needed':
|
|
||||||
comment: >
|
|
||||||
:wave: @{issue-author}, In order to help you further we'll need to see logs.
|
|
||||||
You'll need to enable trace logging and replicate the problem that you encountered.
|
|
||||||
Guidance on how to enable trace logging can be found in
|
|
||||||
our [troubleshooting guide](https://wiki.servarr.com/radarr/troubleshooting#logging-and-log-files).
|
|
||||||
28
.github/labeler.yml
vendored
@@ -1,28 +0,0 @@
|
|||||||
'Area: API':
|
|
||||||
- src/Radarr.Api.V3/**/*
|
|
||||||
|
|
||||||
'Area: Db-migration':
|
|
||||||
- src/NzbDrone.Core/Datastore/Migration/*
|
|
||||||
|
|
||||||
'Area: Download Clients':
|
|
||||||
- src/NzbDrone.Core/Download/Clients/**/*
|
|
||||||
|
|
||||||
'Area: Import Lists':
|
|
||||||
- src/NzbDrone.Core/ImportLists/**/*
|
|
||||||
|
|
||||||
'Area: Indexer':
|
|
||||||
- src/NzbDrone.Core/Indexers/**/*
|
|
||||||
|
|
||||||
'Area: Notifications':
|
|
||||||
- src/NzbDrone.Core/Notifications/**/*
|
|
||||||
|
|
||||||
'Area: Organizer':
|
|
||||||
- src/NzbDrone.Core/Organizer/**/*
|
|
||||||
|
|
||||||
'Area: Parser':
|
|
||||||
- src/NzbDrone.Core/Parser/**/*
|
|
||||||
|
|
||||||
'Area: UI':
|
|
||||||
- frontend/**/*
|
|
||||||
- package.json
|
|
||||||
- yarn.lock
|
|
||||||
17
.github/workflows/label-actions.yml
vendored
@@ -1,17 +0,0 @@
|
|||||||
name: 'Label Actions'
|
|
||||||
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types: [labeled, unlabeled]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
issues: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
action:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: dessant/label-actions@v3
|
|
||||||
with:
|
|
||||||
process-only: 'issues'
|
|
||||||
12
.github/workflows/labeler.yml
vendored
@@ -1,12 +0,0 @@
|
|||||||
name: "Pull Request Labeler"
|
|
||||||
on:
|
|
||||||
- pull_request_target
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
triage:
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/labeler@v4
|
|
||||||
12
.github/workflows/lock.yml
vendored
@@ -14,13 +14,13 @@ jobs:
|
|||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: dessant/lock-threads@v4
|
- uses: dessant/lock-threads@v2
|
||||||
with:
|
with:
|
||||||
github-token: ${{ github.token }}
|
github-token: ${{ github.token }}
|
||||||
issue-inactive-days: '90'
|
issue-lock-inactive-days: '90'
|
||||||
exclude-issue-created-before: ''
|
issue-exclude-created-before: ''
|
||||||
exclude-any-issue-labels: ''
|
issue-exclude-labels: ''
|
||||||
add-issue-labels: ''
|
issue-lock-labels: ''
|
||||||
issue-comment: ''
|
issue-lock-comment: ''
|
||||||
issue-lock-reason: 'resolved'
|
issue-lock-reason: 'resolved'
|
||||||
process-only: ''
|
process-only: ''
|
||||||
|
|||||||
25
.github/workflows/support.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
name: 'Support requests'
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [labeled, unlabeled, reopened]
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
jobs:
|
||||||
|
support:
|
||||||
|
permissions:
|
||||||
|
issues: write # to modify issues
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: dessant/support-requests@v2
|
||||||
|
with:
|
||||||
|
github-token: ${{ github.token }}
|
||||||
|
support-label: 'Type: Support'
|
||||||
|
issue-comment: >
|
||||||
|
:wave: @{issue-author}, we use the issue tracker exclusively
|
||||||
|
for bug reports and feature requests. However, this issue appears
|
||||||
|
to be a support request. Please hop over onto our [Discord](https://radarr.video/discord)
|
||||||
|
or [Subreddit](https://reddit.com/r/radarr)
|
||||||
|
close-issue: true
|
||||||
|
lock-issue: false
|
||||||
BIN
Logo/1024.png
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 49 KiB |
BIN
Logo/128.png
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 4.1 KiB |
BIN
Logo/16.png
|
Before Width: | Height: | Size: 331 B After Width: | Height: | Size: 577 B |
BIN
Logo/256.png
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 10 KiB |
BIN
Logo/32.png
|
Before Width: | Height: | Size: 666 B After Width: | Height: | Size: 1.1 KiB |
BIN
Logo/400.png
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 17 KiB |
BIN
Logo/48.png
|
Before Width: | Height: | Size: 987 B After Width: | Height: | Size: 1.7 KiB |
BIN
Logo/512.png
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 21 KiB |
BIN
Logo/64.png
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
Logo/800.png
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 49 KiB |
BIN
Logo/text256.png
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 32 KiB |
@@ -35,6 +35,7 @@ Note that only one type of a given movie is supported. If you want both an 4k ve
|
|||||||
|
|
||||||
[](https://wiki.servarr.com/radarr)
|
[](https://wiki.servarr.com/radarr)
|
||||||
[](https://radarr.video/discord)
|
[](https://radarr.video/discord)
|
||||||
|
[](https://www.reddit.com/r/Radarr)
|
||||||
|
|
||||||
Note: GitHub Issues are for Bugs and Feature Requests Only
|
Note: GitHub Issues are for Bugs and Feature Requests Only
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ variables:
|
|||||||
testsFolder: './_tests'
|
testsFolder: './_tests'
|
||||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||||
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
||||||
majorVersion: '5.0.3'
|
majorVersion: '5.0.0'
|
||||||
minorVersion: $[counter('minorVersion', 2000)]
|
minorVersion: $[counter('minorVersion', 2000)]
|
||||||
radarrVersion: '$(majorVersion).$(minorVersion)'
|
radarrVersion: '$(majorVersion).$(minorVersion)'
|
||||||
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
|
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
|
||||||
sentryOrg: 'servarr'
|
sentryOrg: 'servarr'
|
||||||
sentryUrl: 'https://sentry.servarr.com'
|
sentryUrl: 'https://sentry.servarr.com'
|
||||||
dotnetVersion: '6.0.413'
|
dotnetVersion: '6.0.400'
|
||||||
nodeVersion: '16.X'
|
nodeVersion: '16.X'
|
||||||
innoVersion: '6.2.0'
|
innoVersion: '6.2.0'
|
||||||
windowsImage: 'windows-2022'
|
windowsImage: 'windows-2022'
|
||||||
@@ -27,10 +27,7 @@ trigger:
|
|||||||
include:
|
include:
|
||||||
- develop
|
- develop
|
||||||
- master
|
- master
|
||||||
paths:
|
- zeus
|
||||||
exclude:
|
|
||||||
- .github
|
|
||||||
- src/Radarr.Api.*/openapi.json
|
|
||||||
|
|
||||||
pr:
|
pr:
|
||||||
branches:
|
branches:
|
||||||
@@ -38,7 +35,6 @@ pr:
|
|||||||
- develop
|
- develop
|
||||||
paths:
|
paths:
|
||||||
exclude:
|
exclude:
|
||||||
- .github
|
|
||||||
- src/NzbDrone.Core/Localization/Core
|
- src/NzbDrone.Core/Localization/Core
|
||||||
- src/Radarr.Api.*/openapi.json
|
- src/Radarr.Api.*/openapi.json
|
||||||
|
|
||||||
@@ -216,8 +212,8 @@ stages:
|
|||||||
displayName: Fetch Frontend
|
displayName: Fetch Frontend
|
||||||
- bash: |
|
- bash: |
|
||||||
./build.sh --packages --installer
|
./build.sh --packages --installer
|
||||||
cp distribution/windows/setup/output/Radarr.*win-x64.exe ${BUILD_ARTIFACTSTAGINGDIRECTORY}/Radarr.${BUILDNAME}.windows-core-x64-installer.exe
|
cp setup/output/Radarr.*win-x64.exe ${BUILD_ARTIFACTSTAGINGDIRECTORY}/Radarr.${BUILDNAME}.windows-core-x64-installer.exe
|
||||||
cp distribution/windows/setup/output/Radarr.*win-x86.exe ${BUILD_ARTIFACTSTAGINGDIRECTORY}/Radarr.${BUILDNAME}.windows-core-x86-installer.exe
|
cp setup/output/Radarr.*win-x86.exe ${BUILD_ARTIFACTSTAGINGDIRECTORY}/Radarr.${BUILDNAME}.windows-core-x86-installer.exe
|
||||||
displayName: Create Installers
|
displayName: Create Installers
|
||||||
- publish: $(Build.ArtifactStagingDirectory)
|
- publish: $(Build.ArtifactStagingDirectory)
|
||||||
artifact: 'WindowsInstaller'
|
artifact: 'WindowsInstaller'
|
||||||
@@ -368,7 +364,7 @@ stages:
|
|||||||
- bash: |
|
- bash: |
|
||||||
echo "Uploading source maps to sentry"
|
echo "Uploading source maps to sentry"
|
||||||
curl -sL https://sentry.io/get-cli/ | bash
|
curl -sL https://sentry.io/get-cli/ | bash
|
||||||
RELEASENAME="Radarr@${RADARRVERSION}-${BUILD_SOURCEBRANCHNAME}"
|
RELEASENAME="${RADARRVERSION}-${BUILD_SOURCEBRANCHNAME}"
|
||||||
sentry-cli releases new --finalize -p radarr -p radarr-ui -p radarr-update "${RELEASENAME}"
|
sentry-cli releases new --finalize -p radarr -p radarr-ui -p radarr-update "${RELEASENAME}"
|
||||||
sentry-cli releases -p radarr-ui files "${RELEASENAME}" upload-sourcemaps _output/UI/ --rewrite
|
sentry-cli releases -p radarr-ui files "${RELEASENAME}" upload-sourcemaps _output/UI/ --rewrite
|
||||||
sentry-cli releases set-commits --auto "${RELEASENAME}"
|
sentry-cli releases set-commits --auto "${RELEASENAME}"
|
||||||
@@ -541,8 +537,8 @@ stages:
|
|||||||
testRunTitle: '$(testName) Unit Tests'
|
testRunTitle: '$(testName) Unit Tests'
|
||||||
failTaskOnFailedTests: true
|
failTaskOnFailedTests: true
|
||||||
|
|
||||||
- job: Unit_LinuxCore_Postgres14
|
- job: Unit_LinuxCore_Postgres
|
||||||
displayName: Unit Native LinuxCore with Postgres14 Database
|
displayName: Unit Native LinuxCore with Postgres Database
|
||||||
dependsOn: Prepare
|
dependsOn: Prepare
|
||||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||||
variables:
|
variables:
|
||||||
@@ -594,63 +590,7 @@ stages:
|
|||||||
inputs:
|
inputs:
|
||||||
testResultsFormat: 'NUnit'
|
testResultsFormat: 'NUnit'
|
||||||
testResultsFiles: '**/TestResult.xml'
|
testResultsFiles: '**/TestResult.xml'
|
||||||
testRunTitle: 'LinuxCore Postgres14 Unit Tests'
|
testRunTitle: 'LinuxCore Postgres Unit Tests'
|
||||||
failTaskOnFailedTests: true
|
|
||||||
|
|
||||||
- job: Unit_LinuxCore_Postgres15
|
|
||||||
displayName: Unit Native LinuxCore with Postgres15 Database
|
|
||||||
dependsOn: Prepare
|
|
||||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
|
||||||
variables:
|
|
||||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
|
||||||
artifactName: linux-x64-tests
|
|
||||||
Radarr__Postgres__Host: 'localhost'
|
|
||||||
Radarr__Postgres__Port: '5432'
|
|
||||||
Radarr__Postgres__User: 'radarr'
|
|
||||||
Radarr__Postgres__Password: 'radarr'
|
|
||||||
|
|
||||||
pool:
|
|
||||||
vmImage: ${{ variables.linuxImage }}
|
|
||||||
|
|
||||||
timeoutInMinutes: 10
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- task: UseDotNet@2
|
|
||||||
displayName: 'Install .net core'
|
|
||||||
inputs:
|
|
||||||
version: $(dotnetVersion)
|
|
||||||
- checkout: none
|
|
||||||
- task: DownloadPipelineArtifact@2
|
|
||||||
displayName: Download Test Artifact
|
|
||||||
inputs:
|
|
||||||
buildType: 'current'
|
|
||||||
artifactName: $(artifactName)
|
|
||||||
targetPath: $(testsFolder)
|
|
||||||
- bash: |
|
|
||||||
chmod a+x _tests/ffprobe
|
|
||||||
displayName: Make ffprobe Executable
|
|
||||||
- bash: find ${TESTSFOLDER} -name "Radarr.Test.Dummy" -exec chmod a+x {} \;
|
|
||||||
displayName: Make Test Dummy Executable
|
|
||||||
condition: and(succeeded(), ne(variables['osName'], 'Windows'))
|
|
||||||
- bash: |
|
|
||||||
docker run -d --name=postgres15 \
|
|
||||||
-e POSTGRES_PASSWORD=radarr \
|
|
||||||
-e POSTGRES_USER=radarr \
|
|
||||||
-p 5432:5432/tcp \
|
|
||||||
-v /usr/share/zoneinfo/America/Chicago:/etc/localtime:ro \
|
|
||||||
postgres:15
|
|
||||||
displayName: Start postgres
|
|
||||||
- bash: |
|
|
||||||
chmod a+x ${TESTSFOLDER}/test.sh
|
|
||||||
ls -lR ${TESTSFOLDER}
|
|
||||||
${TESTSFOLDER}/test.sh Linux Unit Test
|
|
||||||
displayName: Run Tests
|
|
||||||
- task: PublishTestResults@2
|
|
||||||
displayName: Publish Test Results
|
|
||||||
inputs:
|
|
||||||
testResultsFormat: 'NUnit'
|
|
||||||
testResultsFiles: '**/TestResult.xml'
|
|
||||||
testRunTitle: 'LinuxCore Postgres15 Unit Tests'
|
|
||||||
failTaskOnFailedTests: true
|
failTaskOnFailedTests: true
|
||||||
|
|
||||||
- stage: Integration
|
- stage: Integration
|
||||||
@@ -736,8 +676,8 @@ stages:
|
|||||||
failTaskOnFailedTests: true
|
failTaskOnFailedTests: true
|
||||||
displayName: Publish Test Results
|
displayName: Publish Test Results
|
||||||
|
|
||||||
- job: Integration_LinuxCore_Postgres14
|
- job: Integration_LinuxCore_Postgres
|
||||||
displayName: Integration Native LinuxCore with Postgres14 Database
|
displayName: Integration Native LinuxCore with Postgres Database
|
||||||
dependsOn: Prepare
|
dependsOn: Prepare
|
||||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||||
variables:
|
variables:
|
||||||
@@ -794,70 +734,7 @@ stages:
|
|||||||
inputs:
|
inputs:
|
||||||
testResultsFormat: 'NUnit'
|
testResultsFormat: 'NUnit'
|
||||||
testResultsFiles: '**/TestResult.xml'
|
testResultsFiles: '**/TestResult.xml'
|
||||||
testRunTitle: 'Integration LinuxCore Postgres14 Database Integration Tests'
|
testRunTitle: 'Integration LinuxCore Postgres Database Integration Tests'
|
||||||
failTaskOnFailedTests: true
|
|
||||||
displayName: Publish Test Results
|
|
||||||
|
|
||||||
|
|
||||||
- job: Integration_LinuxCore_Postgres15
|
|
||||||
displayName: Integration Native LinuxCore with Postgres Database
|
|
||||||
dependsOn: Prepare
|
|
||||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
|
||||||
variables:
|
|
||||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
|
||||||
Radarr__Postgres__Host: 'localhost'
|
|
||||||
Radarr__Postgres__Port: '5432'
|
|
||||||
Radarr__Postgres__User: 'radarr'
|
|
||||||
Radarr__Postgres__Password: 'radarr'
|
|
||||||
|
|
||||||
pool:
|
|
||||||
vmImage: ${{ variables.linuxImage }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- task: UseDotNet@2
|
|
||||||
displayName: 'Install .net core'
|
|
||||||
inputs:
|
|
||||||
version: $(dotnetVersion)
|
|
||||||
- checkout: none
|
|
||||||
- task: DownloadPipelineArtifact@2
|
|
||||||
displayName: Download Test Artifact
|
|
||||||
inputs:
|
|
||||||
buildType: 'current'
|
|
||||||
artifactName: 'linux-x64-tests'
|
|
||||||
targetPath: $(testsFolder)
|
|
||||||
- task: DownloadPipelineArtifact@2
|
|
||||||
displayName: Download Build Artifact
|
|
||||||
inputs:
|
|
||||||
buildType: 'current'
|
|
||||||
artifactName: Packages
|
|
||||||
itemPattern: '**/$(pattern)'
|
|
||||||
targetPath: $(Build.ArtifactStagingDirectory)
|
|
||||||
- task: ExtractFiles@1
|
|
||||||
inputs:
|
|
||||||
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
|
|
||||||
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
|
|
||||||
displayName: Extract Package
|
|
||||||
- bash: |
|
|
||||||
mkdir -p ./bin/
|
|
||||||
cp -r -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin/Radarr/. ./bin/
|
|
||||||
displayName: Move Package Contents
|
|
||||||
- bash: |
|
|
||||||
docker run -d --name=postgres15 \
|
|
||||||
-e POSTGRES_PASSWORD=radarr \
|
|
||||||
-e POSTGRES_USER=radarr \
|
|
||||||
-p 5432:5432/tcp \
|
|
||||||
-v /usr/share/zoneinfo/America/Chicago:/etc/localtime:ro \
|
|
||||||
postgres:15
|
|
||||||
displayName: Start postgres
|
|
||||||
- bash: |
|
|
||||||
chmod a+x ${TESTSFOLDER}/test.sh
|
|
||||||
${TESTSFOLDER}/test.sh Linux Integration Test
|
|
||||||
displayName: Run Integration Tests
|
|
||||||
- task: PublishTestResults@2
|
|
||||||
inputs:
|
|
||||||
testResultsFormat: 'NUnit'
|
|
||||||
testResultsFiles: '**/TestResult.xml'
|
|
||||||
testRunTitle: 'Integration LinuxCore Postgres15 Database Integration Tests'
|
|
||||||
failTaskOnFailedTests: true
|
failTaskOnFailedTests: true
|
||||||
displayName: Publish Test Results
|
displayName: Publish Test Results
|
||||||
|
|
||||||
@@ -1216,7 +1093,7 @@ stages:
|
|||||||
projectVersion: '$(radarrVersion)'
|
projectVersion: '$(radarrVersion)'
|
||||||
extraProperties: |
|
extraProperties: |
|
||||||
sonar.exclusions=**/obj/**,**/*.dll,**/NzbDrone.Core.Test/Files/**/*,./frontend/**,**/ExternalModules/**,./src/Libraries/**
|
sonar.exclusions=**/obj/**,**/*.dll,**/NzbDrone.Core.Test/Files/**/*,./frontend/**,**/ExternalModules/**,./src/Libraries/**
|
||||||
sonar.coverage.exclusions=**/Radarr.Api.V3/**/*
|
sonar.coverage.exclusions=**/Radarr.Api.V*/**/*
|
||||||
sonar.cs.opencover.reportsPaths=$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml
|
sonar.cs.opencover.reportsPaths=$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml
|
||||||
sonar.cs.nunit.reportsPaths=$(Build.SourcesDirectory)/TestResult.xml
|
sonar.cs.nunit.reportsPaths=$(Build.SourcesDirectory)/TestResult.xml
|
||||||
- bash: |
|
- bash: |
|
||||||
|
|||||||
19
build.sh
@@ -21,7 +21,7 @@ UpdateVersionNumber()
|
|||||||
echo "Updating Version Info"
|
echo "Updating Version Info"
|
||||||
sed -i'' -e "s/<AssemblyVersion>[0-9.*]\+<\/AssemblyVersion>/<AssemblyVersion>$RADARRVERSION<\/AssemblyVersion>/g" src/Directory.Build.props
|
sed -i'' -e "s/<AssemblyVersion>[0-9.*]\+<\/AssemblyVersion>/<AssemblyVersion>$RADARRVERSION<\/AssemblyVersion>/g" src/Directory.Build.props
|
||||||
sed -i'' -e "s/<AssemblyConfiguration>[\$()A-Za-z-]\+<\/AssemblyConfiguration>/<AssemblyConfiguration>${BUILD_SOURCEBRANCHNAME}<\/AssemblyConfiguration>/g" src/Directory.Build.props
|
sed -i'' -e "s/<AssemblyConfiguration>[\$()A-Za-z-]\+<\/AssemblyConfiguration>/<AssemblyConfiguration>${BUILD_SOURCEBRANCHNAME}<\/AssemblyConfiguration>/g" src/Directory.Build.props
|
||||||
sed -i'' -e "s/<string>10.0.0.0<\/string>/<string>$RADARRVERSION<\/string>/g" distribution/osx/Radarr.app/Contents/Info.plist
|
sed -i'' -e "s/<string>10.0.0.0<\/string>/<string>$RADARRVERSION<\/string>/g" macOS/Radarr.app/Contents/Info.plist
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ PackageMacOSApp()
|
|||||||
|
|
||||||
rm -rf $folder
|
rm -rf $folder
|
||||||
mkdir -p $folder
|
mkdir -p $folder
|
||||||
cp -r distribution/osx/Radarr.app $folder
|
cp -r macOS/Radarr.app $folder
|
||||||
mkdir -p $folder/Radarr.app/Contents/MacOS
|
mkdir -p $folder/Radarr.app/Contents/MacOS
|
||||||
|
|
||||||
echo "Copying Binaries"
|
echo "Copying Binaries"
|
||||||
@@ -246,7 +246,7 @@ BuildInstaller()
|
|||||||
local framework="$1"
|
local framework="$1"
|
||||||
local runtime="$2"
|
local runtime="$2"
|
||||||
|
|
||||||
./_inno/ISCC.exe distribution/windows/setup/radarr.iss "//DFramework=$framework" "//DRuntime=$runtime"
|
./_inno/ISCC.exe setup/radarr.iss "//DFramework=$framework" "//DRuntime=$runtime"
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallInno()
|
InstallInno()
|
||||||
@@ -392,21 +392,22 @@ then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$LINT" = "YES" || "$FRONTEND" = "YES" ]];
|
if [ "$FRONTEND" = "YES" ];
|
||||||
then
|
then
|
||||||
YarnInstall
|
YarnInstall
|
||||||
|
RunWebpack
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$LINT" = "YES" ];
|
if [ "$LINT" = "YES" ];
|
||||||
then
|
then
|
||||||
|
if [ -z "$FRONTEND" ];
|
||||||
|
then
|
||||||
|
YarnInstall
|
||||||
|
fi
|
||||||
|
|
||||||
LintUI
|
LintUI
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$FRONTEND" = "YES" ];
|
|
||||||
then
|
|
||||||
RunWebpack
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$PACKAGES" = "YES" ];
|
if [ "$PACKAGES" = "YES" ];
|
||||||
then
|
then
|
||||||
UpdateVersionNumber
|
UpdateVersionNumber
|
||||||
|
|||||||
5
debian/changelog
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
nzbdrone {version} {branch}; urgency=low
|
||||||
|
|
||||||
|
* Automatic Release.
|
||||||
|
|
||||||
|
-- NzbDrone <contact@nzbdrone.com> Mon, 26 Aug 2013 00:00:00 -0700
|
||||||
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
12
debian/control
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Section: web
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Sonarr <contact@nzbdrone.com>
|
||||||
|
Source: nzbdrone
|
||||||
|
Homepage: https://sonarr.tv
|
||||||
|
Vcs-Git: git@github.com:Sonarr/Sonarr.git
|
||||||
|
Vcs-Browser: https://github.com/Sonarr/Sonarr
|
||||||
|
|
||||||
|
Package: nzbdrone
|
||||||
|
Architecture: all
|
||||||
|
Depends: libmono-cil-dev (>= 3.2), sqlite3 (>= 3.7), mediainfo (>= 0.7.52)
|
||||||
|
Description: Sonarr is an internet PVR
|
||||||
24
debian/copyright
vendored
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: nzbdrone
|
||||||
|
Source: https://github.com/Sonarr/Sonarr
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2010-2016 Sonarr <hello@sonarr.tv>
|
||||||
|
|
||||||
|
License: GPL-3.0+
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
.
|
||||||
|
This package is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
.
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
.
|
||||||
|
On Debian systems, the complete text of the GNU General
|
||||||
|
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||||
1
debian/install
vendored
Executable file
@@ -0,0 +1 @@
|
|||||||
|
nzbdrone_bin/* opt/NzbDrone
|
||||||
13
debian/rules
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
# Sample debian/rules that uses debhelper.
|
||||||
|
# This file was originally written by Joey Hess and Craig Small.
|
||||||
|
# As a special exception, when this file is copied by dh-make into a
|
||||||
|
# dh-make output file, you may use that output file without restriction.
|
||||||
|
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
10
docs.sh
@@ -3,9 +3,9 @@ PLATFORM=$1
|
|||||||
if [ "$PLATFORM" = "Windows" ]; then
|
if [ "$PLATFORM" = "Windows" ]; then
|
||||||
RUNTIME="win-x64"
|
RUNTIME="win-x64"
|
||||||
elif [ "$PLATFORM" = "Linux" ]; then
|
elif [ "$PLATFORM" = "Linux" ]; then
|
||||||
RUNTIME="linux-x64"
|
WHERE="linux-x64"
|
||||||
elif [ "$PLATFORM" = "Mac" ]; then
|
elif [ "$PLATFORM" = "Mac" ]; then
|
||||||
RUNTIME="osx-x64"
|
WHERE="osx-x64"
|
||||||
else
|
else
|
||||||
echo "Platform must be provided as first arguement: Windows, Linux or Mac"
|
echo "Platform must be provided as first arguement: Windows, Linux or Mac"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -27,12 +27,12 @@ dotnet clean $slnFile -c Release
|
|||||||
dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids
|
dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids
|
||||||
|
|
||||||
dotnet new tool-manifest
|
dotnet new tool-manifest
|
||||||
dotnet tool install --version 6.5.0 Swashbuckle.AspNetCore.Cli
|
dotnet tool install --version 6.3.0 Swashbuckle.AspNetCore.Cli
|
||||||
|
|
||||||
dotnet tool run swagger tofile --output ./src/Radarr.Api.V3/openapi.json "$outputFolder/net6.0/$RUNTIME/radarr.console.dll" v3 &
|
dotnet tool run swagger tofile --output ./src/Radarr.Api.V4/openapi.json "$outputFolder/net6.0/$RUNTIME/radarr.console.dll" v4 &
|
||||||
|
|
||||||
sleep 45
|
sleep 45
|
||||||
|
|
||||||
kill %1
|
kill %1
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
25
frontend/.csscomb.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"remove-empty-rulesets": true,
|
||||||
|
"always-semicolon": true,
|
||||||
|
"color-case": "lower",
|
||||||
|
"block-indent": " ",
|
||||||
|
"color-shorthand": false,
|
||||||
|
"element-case": "lower",
|
||||||
|
"eof-newline": true,
|
||||||
|
"leading-zero": true,
|
||||||
|
"quotes": "double",
|
||||||
|
"sort-order-fallback": "abc",
|
||||||
|
"space-before-colon": "",
|
||||||
|
"space-after-colon": " ",
|
||||||
|
"space-before-combinator": " ",
|
||||||
|
"space-after-combinator": " ",
|
||||||
|
"space-between-declarations": "\n",
|
||||||
|
"space-before-opening-brace": " ",
|
||||||
|
"space-after-opening-brace": "\n",
|
||||||
|
"space-after-selector-delimiter": " ",
|
||||||
|
"space-before-selector-delimiter": "",
|
||||||
|
"space-before-closing-brace": "\n",
|
||||||
|
"strip-spaces": true,
|
||||||
|
"tab-size": true,
|
||||||
|
"unitless-zero": false
|
||||||
|
}
|
||||||
335
frontend/.esformatter
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
{
|
||||||
|
"indent": {
|
||||||
|
"value": " ",
|
||||||
|
"FunctionExpression": 1,
|
||||||
|
"ArrayExpression": 1,
|
||||||
|
"ObjectExpression": 1
|
||||||
|
},
|
||||||
|
"lineBreak": {
|
||||||
|
"value": "\n",
|
||||||
|
|
||||||
|
"before": {
|
||||||
|
"ArrayPatternClosing": 0,
|
||||||
|
"ArrayPatternComma": 0,
|
||||||
|
"ArrayPatternOpening": 0,
|
||||||
|
"ArrowFunctionExpressionArrow": 0,
|
||||||
|
"ArrowFunctionExpressionClosingBrace": ">=1",
|
||||||
|
"ArrowFunctionExpressionOpeningBrace": 0,
|
||||||
|
"AssignmentExpression": ">=1",
|
||||||
|
"AssignmentOperator": 0,
|
||||||
|
"BlockStatement": 0,
|
||||||
|
"BreakKeyword": ">=1",
|
||||||
|
"CallExpression": -1,
|
||||||
|
"CallExpressionClosingParentheses": -1,
|
||||||
|
"CallExpressionOpeningParentheses": 0,
|
||||||
|
"CatchClosingBrace": ">=1",
|
||||||
|
"CatchKeyword": 0,
|
||||||
|
"CatchOpeningBrace": 0,
|
||||||
|
"ClassDeclaration": ">=1",
|
||||||
|
"ClassDeclarationClosingBrace": ">=1",
|
||||||
|
"ClassDeclarationOpeningBrace": 0,
|
||||||
|
"ConditionalExpression": ">=1",
|
||||||
|
"DeleteOperator": ">=1",
|
||||||
|
"DoWhileStatement": ">=1",
|
||||||
|
"DoWhileStatementClosingBrace": ">=1",
|
||||||
|
"DoWhileStatementOpeningBrace": 0,
|
||||||
|
"ElseIfStatement": 0,
|
||||||
|
"ElseIfStatementClosingBrace": ">=1",
|
||||||
|
"ElseIfStatementOpeningBrace": 0,
|
||||||
|
"ElseStatement": 0,
|
||||||
|
"ElseStatementClosingBrace": ">=1",
|
||||||
|
"ElseStatementOpeningBrace": 0,
|
||||||
|
"EmptyStatement": -1,
|
||||||
|
"EndOfFile": -1,
|
||||||
|
"FinallyClosingBrace": ">=1",
|
||||||
|
"FinallyKeyword": -1,
|
||||||
|
"FinallyOpeningBrace": 0,
|
||||||
|
"ForInStatement": ">=1",
|
||||||
|
"ForInStatementClosingBrace": ">=1",
|
||||||
|
"ForInStatementExpressionClosing": 0,
|
||||||
|
"ForInStatementExpressionOpening": 0,
|
||||||
|
"ForInStatementOpeningBrace": 0,
|
||||||
|
"ForStatement": ">=1",
|
||||||
|
"ForStatementClosingBrace": ">=1",
|
||||||
|
"ForStatementExpressionClosing": "<2",
|
||||||
|
"ForStatementExpressionOpening": 0,
|
||||||
|
"ForStatementOpeningBrace": 0,
|
||||||
|
"FunctionDeclaration": ">=1",
|
||||||
|
"FunctionDeclarationClosingBrace": ">=1",
|
||||||
|
"FunctionDeclarationOpeningBrace": 0,
|
||||||
|
"FunctionExpression": 0,
|
||||||
|
"FunctionExpressionClosingBrace": 1,
|
||||||
|
"FunctionExpressionOpeningBrace":0,
|
||||||
|
"IIFEClosingParentheses": 0,
|
||||||
|
"IfStatement": ">=1",
|
||||||
|
"IfStatementClosingBrace": ">=1",
|
||||||
|
"IfStatementOpeningBrace": 0,
|
||||||
|
"LogicalExpression": -1,
|
||||||
|
"MemberExpressionClosing": 0,
|
||||||
|
"MemberExpressionOpening": 0,
|
||||||
|
"MemberExpressionPeriod": -1,
|
||||||
|
"MethodDefinition": ">=1",
|
||||||
|
"ObjectExpressionClosingBrace": "<=1",
|
||||||
|
"ObjectPatternClosingBrace": 0,
|
||||||
|
"ObjectPatternComma": 0,
|
||||||
|
"ObjectPatternOpeningBrace": 0,
|
||||||
|
"ParameterDefault": 0,
|
||||||
|
"Property": "<=2",
|
||||||
|
"PropertyValue": 0,
|
||||||
|
"ReturnStatement": -1,
|
||||||
|
"SwitchClosingBrace": ">=1",
|
||||||
|
"SwitchOpeningBrace": 0,
|
||||||
|
"ThisExpression": -1,
|
||||||
|
"ThrowStatement": ">=1",
|
||||||
|
"TryClosingBrace": ">=1",
|
||||||
|
"TryKeyword": -1,
|
||||||
|
"TryOpeningBrace": 0,
|
||||||
|
"VariableDeclaration": ">=1",
|
||||||
|
"VariableDeclarationSemiColon": 0,
|
||||||
|
"VariableDeclarationWithoutInit": ">=1",
|
||||||
|
"VariableName": ">=1",
|
||||||
|
"VariableValue": 0,
|
||||||
|
"WhileStatement": ">=1",
|
||||||
|
"WhileStatementClosingBrace": ">=1",
|
||||||
|
"WhileStatementOpeningBrace": 0
|
||||||
|
},
|
||||||
|
|
||||||
|
"after": {
|
||||||
|
"ArrayPatternClosing": 0,
|
||||||
|
"ArrayPatternComma": 0,
|
||||||
|
"ArrayPatternOpening": 0,
|
||||||
|
"ArrowFunctionExpressionArrow": 0,
|
||||||
|
"ArrowFunctionExpressionClosingBrace": -1,
|
||||||
|
"ArrowFunctionExpressionOpeningBrace": ">=1",
|
||||||
|
"AssignmentExpression": ">=1",
|
||||||
|
"AssignmentOperator": 0,
|
||||||
|
"BlockStatement": 0,
|
||||||
|
"BreakKeyword": -1,
|
||||||
|
"CallExpression": -1,
|
||||||
|
"CallExpressionClosingParentheses": -1,
|
||||||
|
"CallExpressionOpeningParentheses": -1,
|
||||||
|
"CatchClosingBrace": ">=0",
|
||||||
|
"CatchKeyword": 0,
|
||||||
|
"CatchOpeningBrace": ">=1",
|
||||||
|
"ClassDeclaration": ">=1",
|
||||||
|
"ClassDeclarationClosingBrace": ">=1",
|
||||||
|
"ClassDeclarationOpeningBrace": ">=1",
|
||||||
|
"ConditionalExpression": ">=1",
|
||||||
|
"DeleteOperator": ">=1",
|
||||||
|
"DoWhileStatement": ">=1",
|
||||||
|
"DoWhileStatementClosingBrace": 0,
|
||||||
|
"DoWhileStatementOpeningBrace": ">=1",
|
||||||
|
"ElseIfStatement": ">=1",
|
||||||
|
"ElseIfStatementClosingBrace": ">=1",
|
||||||
|
"ElseIfStatementOpeningBrace": ">=1",
|
||||||
|
"ElseStatement": ">=1",
|
||||||
|
"ElseStatementClosingBrace": ">=1",
|
||||||
|
"ElseStatementOpeningBrace": ">=1",
|
||||||
|
"EmptyStatement": -1,
|
||||||
|
"FinallyClosingBrace": ">=1",
|
||||||
|
"FinallyKeyword": -1,
|
||||||
|
"FinallyOpeningBrace": ">=1",
|
||||||
|
"ForInStatement": ">=1",
|
||||||
|
"ForInStatementClosingBrace": ">=1",
|
||||||
|
"ForInStatementExpressionClosing": -1,
|
||||||
|
"ForInStatementExpressionOpening": "<2",
|
||||||
|
"ForInStatementOpeningBrace": ">=1",
|
||||||
|
"ForStatement": ">=1",
|
||||||
|
"ForStatementClosingBrace": ">=1",
|
||||||
|
"ForStatementExpressionClosing": -1,
|
||||||
|
"ForStatementExpressionOpening": "<2",
|
||||||
|
"ForStatementOpeningBrace": ">=1",
|
||||||
|
"FunctionDeclaration": ">=1",
|
||||||
|
"FunctionDeclarationClosingBrace": ">=1",
|
||||||
|
"FunctionDeclarationOpeningBrace": ">=1",
|
||||||
|
"FunctionExpression": 0,
|
||||||
|
"FunctionExpressionClosingBrace": -1,
|
||||||
|
"FunctionExpressionOpeningBrace": 1,
|
||||||
|
"IIFEOpeningParentheses": 0,
|
||||||
|
"IfStatement": ">=1",
|
||||||
|
"IfStatementClosingBrace": ">=1",
|
||||||
|
"IfStatementOpeningBrace": ">=1",
|
||||||
|
"LogicalExpression": -1,
|
||||||
|
"MemberExpressionClosing": 0,
|
||||||
|
"MemberExpressionOpening": 0,
|
||||||
|
"MemberExpressionPeriod": 0,
|
||||||
|
"MethodDefinition": ">=1",
|
||||||
|
"ObjectExpressionOpeningBrace": "<=1",
|
||||||
|
"ObjectPatternClosingBrace": 0,
|
||||||
|
"ObjectPatternComma": 0,
|
||||||
|
"ObjectPatternOpeningBrace": 0,
|
||||||
|
"ParameterDefault": 0,
|
||||||
|
"Property": -1,
|
||||||
|
"PropertyName": 0,
|
||||||
|
"ReturnStatement": -1,
|
||||||
|
"SwitchCaseColon": ">=1",
|
||||||
|
"SwitchClosingBrace": ">=1",
|
||||||
|
"SwitchOpeningBrace": ">=1",
|
||||||
|
"ThisExpression": 0,
|
||||||
|
"ThrowStatement": ">=1",
|
||||||
|
"TryClosingBrace": 0,
|
||||||
|
"TryKeyword": -1,
|
||||||
|
"TryOpeningBrace": ">=1",
|
||||||
|
"VariableDeclaration": ">=1",
|
||||||
|
"VariableDeclarationSemiColon": ">=1",
|
||||||
|
"VariableValue": -1,
|
||||||
|
"WhileStatement": ">=1",
|
||||||
|
"WhileStatementClosingBrace": ">=1",
|
||||||
|
"WhileStatementOpeningBrace": ">=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"whiteSpace": {
|
||||||
|
"value": " ",
|
||||||
|
"removeTrailing": 1,
|
||||||
|
"before": {
|
||||||
|
"ArgumentComma": 0,
|
||||||
|
"ArgumentList": 0,
|
||||||
|
"ArgumentListArrayExpression": 0,
|
||||||
|
"ArgumentListFunctionExpression": 1,
|
||||||
|
"ArgumentListObjectExpression": 0,
|
||||||
|
"ArrayExpressionClosing": 0,
|
||||||
|
"ArrayExpressionComma": 0,
|
||||||
|
"ArrayExpressionOpening": 1,
|
||||||
|
"AssignmentOperator": 1,
|
||||||
|
"BinaryExpression": 0,
|
||||||
|
"BinaryExpressionOperator": 1,
|
||||||
|
"BlockComment": 1,
|
||||||
|
"CallExpression": 1,
|
||||||
|
"CatchClosingBrace": 1,
|
||||||
|
"CatchKeyword": 1,
|
||||||
|
"CatchOpeningBrace": 1,
|
||||||
|
"CatchParameterList": 0,
|
||||||
|
"CommaOperator": 0,
|
||||||
|
"ConditionalExpressionAlternate": 1,
|
||||||
|
"ConditionalExpressionConsequent": 1,
|
||||||
|
"DoWhileStatementClosingBrace": 1,
|
||||||
|
"DoWhileStatementConditional": 1,
|
||||||
|
"DoWhileStatementOpeningBrace": 1,
|
||||||
|
"ElseIfStatementClosingBrace": 1,
|
||||||
|
"ElseIfStatementOpeningBrace": 1,
|
||||||
|
"ElseStatementClosingBrace": 1,
|
||||||
|
"ElseStatementOpeningBrace": 1,
|
||||||
|
"EmptyStatement": 0,
|
||||||
|
"ExpressionClosingParentheses": 0,
|
||||||
|
"FinallyClosingBrace": 1,
|
||||||
|
"FinallyKeyword": -1,
|
||||||
|
"FinallyOpeningBrace": 1,
|
||||||
|
"ForInStatement": 1,
|
||||||
|
"ForInStatementClosingBrace": 1,
|
||||||
|
"ForInStatementExpressionClosing": 0,
|
||||||
|
"ForInStatementExpressionOpening": 1,
|
||||||
|
"ForInStatementOpeningBrace": 1,
|
||||||
|
"ForStatement": 1,
|
||||||
|
"ForStatementClosingBrace": 1,
|
||||||
|
"ForStatementExpressionClosing": 0,
|
||||||
|
"ForStatementExpressionOpening": 1,
|
||||||
|
"ForStatementOpeningBrace": 1,
|
||||||
|
"ForStatementSemicolon": 0,
|
||||||
|
"FunctionDeclarationClosingBrace": 1,
|
||||||
|
"FunctionDeclarationOpeningBrace": 1,
|
||||||
|
"FunctionExpressionClosingBrace": 1,
|
||||||
|
"FunctionExpressionOpeningBrace": 1,
|
||||||
|
"IfStatementClosingBrace": 1,
|
||||||
|
"IfStatementConditionalClosing": 0,
|
||||||
|
"IfStatementConditionalOpening": 1,
|
||||||
|
"IfStatementOpeningBrace": 1,
|
||||||
|
"LineComment": 1,
|
||||||
|
"LogicalExpressionOperator": 1,
|
||||||
|
"MemberExpressionClosing": 0,
|
||||||
|
"ObjectExpressionClosingBrace": 1,
|
||||||
|
"ParameterComma": 0,
|
||||||
|
"ParameterList": 0,
|
||||||
|
"Property": 1,
|
||||||
|
"PropertyName": 1,
|
||||||
|
"PropertyValue": 1,
|
||||||
|
"SwitchDiscriminantClosing": 0,
|
||||||
|
"SwitchDiscriminantOpening": 1,
|
||||||
|
"ThrowKeyword": 1,
|
||||||
|
"TryClosingBrace": 1,
|
||||||
|
"TryKeyword": -1,
|
||||||
|
"TryOpeningBrace": 1,
|
||||||
|
"UnaryExpressionOperator": 0,
|
||||||
|
"VariableName": 1,
|
||||||
|
"VariableValue": 1,
|
||||||
|
"WhileStatementClosingBrace": 1,
|
||||||
|
"WhileStatementConditionalClosing": 0,
|
||||||
|
"WhileStatementConditionalOpening": 1,
|
||||||
|
"WhileStatementOpeningBrace": 1
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"ArgumentComma": 1,
|
||||||
|
"ArgumentList": 0,
|
||||||
|
"ArgumentListArrayExpression": 1,
|
||||||
|
"ArgumentListFunctionExpression": 1,
|
||||||
|
"ArgumentListObjectExpression": 0,
|
||||||
|
"ArrayExpressionClosing": 0,
|
||||||
|
"ArrayExpressionComma": 1,
|
||||||
|
"ArrayExpressionOpening": 0,
|
||||||
|
"AssignmentOperator": 1,
|
||||||
|
"BinaryExpression": 0,
|
||||||
|
"BinaryExpressionOperator": 1,
|
||||||
|
"BlockComment": 1,
|
||||||
|
"CallExpression": 0,
|
||||||
|
"CatchClosingBrace": 1,
|
||||||
|
"CatchKeyword": 1,
|
||||||
|
"CatchOpeningBrace": 1,
|
||||||
|
"CatchParameterList": 0,
|
||||||
|
"CommaOperator": 1,
|
||||||
|
"ConditionalExpressionConsequent": 1,
|
||||||
|
"ConditionalExpressionTest": 1,
|
||||||
|
"DoWhileStatementBody": 1,
|
||||||
|
"DoWhileStatementClosingBrace": 1,
|
||||||
|
"DoWhileStatementOpeningBrace": 1,
|
||||||
|
"ElseIfStatementClosingBrace": 1,
|
||||||
|
"ElseIfStatementOpeningBrace": 1,
|
||||||
|
"ElseStatementClosingBrace": 1,
|
||||||
|
"ElseStatementOpeningBrace": 1,
|
||||||
|
"EmptyStatement": 0,
|
||||||
|
"ExpressionOpeningParentheses": 0,
|
||||||
|
"FinallyClosingBrace": 1,
|
||||||
|
"FinallyKeyword": -1,
|
||||||
|
"FinallyOpeningBrace": 1,
|
||||||
|
"ForInStatement": 1,
|
||||||
|
"ForInStatementClosingBrace": 1,
|
||||||
|
"ForInStatementExpressionClosing": 1,
|
||||||
|
"ForInStatementExpressionOpening": 0,
|
||||||
|
"ForInStatementOpeningBrace": 1,
|
||||||
|
"ForStatement": 1,
|
||||||
|
"ForStatementClosingBrace": 1,
|
||||||
|
"ForStatementExpressionClosing": 1,
|
||||||
|
"ForStatementExpressionOpening": 0,
|
||||||
|
"ForStatementOpeningBrace": 1,
|
||||||
|
"ForStatementSemicolon": 1,
|
||||||
|
"FunctionDeclarationClosingBrace": 0,
|
||||||
|
"FunctionDeclarationOpeningBrace": 0,
|
||||||
|
"FunctionExpressionClosingBrace": 0,
|
||||||
|
"FunctionExpressionOpeningBrace": 0,
|
||||||
|
"FunctionName": 0,
|
||||||
|
"FunctionReservedWord": 0,
|
||||||
|
"IfStatementClosingBrace": 1,
|
||||||
|
"IfStatementConditionalClosing": 0,
|
||||||
|
"IfStatementConditionalOpening": 0,
|
||||||
|
"IfStatementOpeningBrace": 1,
|
||||||
|
"LogicalExpressionOperator": 1,
|
||||||
|
"MemberExpressionOpening": 0,
|
||||||
|
"ObjectExpressionClosingBrace": 0,
|
||||||
|
"ObjectExpressionOpeningBrace": 1,
|
||||||
|
"ParameterComma": 1,
|
||||||
|
"ParameterList": 0,
|
||||||
|
"PropertyName": 0,
|
||||||
|
"PropertyValue": 0,
|
||||||
|
"SwitchDiscriminantClosing": 1,
|
||||||
|
"SwitchDiscriminantOpening": 0,
|
||||||
|
"ThrowKeyword": 1,
|
||||||
|
"TryClosingBrace": 1,
|
||||||
|
"TryKeyword": -1,
|
||||||
|
"TryOpeningBrace": 1,
|
||||||
|
"UnaryExpressionOperator": 0,
|
||||||
|
"VariableName": 1,
|
||||||
|
"WhileStatementClosingBrace": 1,
|
||||||
|
"WhileStatementConditionalClosing": 1,
|
||||||
|
"WhileStatementConditionalOpening": 0,
|
||||||
|
"WhileStatementOpeningBrace": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +1 @@
|
|||||||
**/JsLibraries/**
|
**/JsLibraries/**
|
||||||
**/*.css.d.ts
|
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
||||||
const path = require('path');
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
||||||
const typescriptEslintRecommended = require('@typescript-eslint/eslint-plugin').configs.recommended;
|
|
||||||
|
|
||||||
const frontendFolder = __dirname;
|
|
||||||
|
|
||||||
const dirs = fs
|
const dirs = fs
|
||||||
.readdirSync(path.join(frontendFolder, 'src'), { withFileTypes: true })
|
.readdirSync('frontend/src', { withFileTypes: true })
|
||||||
.filter((dirent) => dirent.isDirectory())
|
.filter((dirent) => dirent.isDirectory())
|
||||||
.map((dirent) => dirent.name)
|
.map((dirent) => dirent.name)
|
||||||
.join('|');
|
.join('|');
|
||||||
|
|
||||||
module.exports = {
|
const frontendFolder = __dirname;
|
||||||
root: true,
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
parser: '@babel/eslint-parser',
|
parser: '@babel/eslint-parser',
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
@@ -28,8 +21,7 @@ module.exports = {
|
|||||||
globals: {
|
globals: {
|
||||||
expect: false,
|
expect: false,
|
||||||
chai: false,
|
chai: false,
|
||||||
sinon: false,
|
sinon: false
|
||||||
JSX: true
|
|
||||||
},
|
},
|
||||||
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
@@ -49,9 +41,7 @@ module.exports = {
|
|||||||
'react',
|
'react',
|
||||||
'react-hooks',
|
'react-hooks',
|
||||||
'simple-import-sort',
|
'simple-import-sort',
|
||||||
'import',
|
'import'
|
||||||
'@typescript-eslint',
|
|
||||||
'prettier'
|
|
||||||
],
|
],
|
||||||
|
|
||||||
settings: {
|
settings: {
|
||||||
@@ -234,7 +224,7 @@ module.exports = {
|
|||||||
'consistent-this': ['error', 'self'],
|
'consistent-this': ['error', 'self'],
|
||||||
'eol-last': 'error',
|
'eol-last': 'error',
|
||||||
'func-names': 'off',
|
'func-names': 'off',
|
||||||
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
|
'func-style': ['error', 'declaration'],
|
||||||
indent: ['error', 2, { SwitchCase: 1 }],
|
indent: ['error', 2, { SwitchCase: 1 }],
|
||||||
'key-spacing': ['error', { beforeColon: false, afterColon: true }],
|
'key-spacing': ['error', { beforeColon: false, afterColon: true }],
|
||||||
'keyword-spacing': ['error', { before: true, after: true }],
|
'keyword-spacing': ['error', { before: true, after: true }],
|
||||||
@@ -325,9 +315,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: [
|
files: ['*.js'],
|
||||||
'*.js'
|
|
||||||
],
|
|
||||||
rules: {
|
rules: {
|
||||||
'simple-import-sort/imports': [
|
'simple-import-sort/imports': [
|
||||||
'error',
|
'error',
|
||||||
@@ -342,52 +330,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'*.ts',
|
|
||||||
'*.tsx'
|
|
||||||
],
|
|
||||||
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
parserOptions: {
|
|
||||||
project: './tsconfig.json'
|
|
||||||
},
|
|
||||||
|
|
||||||
extends: [
|
|
||||||
'prettier'
|
|
||||||
],
|
|
||||||
|
|
||||||
rules: Object.assign(typescriptEslintRecommended.rules, {
|
|
||||||
'no-shadow': 'off',
|
|
||||||
// These should be enabled after cleaning things up
|
|
||||||
'@typescript-eslint/no-unused-vars': 'warn',
|
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
||||||
'react/prop-types': 'off',
|
|
||||||
'prettier/prettier': 'error',
|
|
||||||
'simple-import-sort/imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
groups: [
|
|
||||||
// Packages
|
|
||||||
// Absolute Paths
|
|
||||||
// Relative Paths
|
|
||||||
// Css
|
|
||||||
['^@?\\w', `^(${dirs})(/.*|$)`, '^\\.', '^\\..*css$']
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'*.css.d.ts'
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'filenames/match-exported': 'off',
|
|
||||||
'init-declarations': 'off',
|
|
||||||
'prettier/prettier': 'off'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
12
frontend/.jsbeautifyrc
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"js": {
|
||||||
|
"indent_size": 2,
|
||||||
|
"indent_char": " ",
|
||||||
|
"indent_level": 2,
|
||||||
|
"indent_with_tabs": false,
|
||||||
|
"preserve_newlines": true,
|
||||||
|
"brace_style": "collapse",
|
||||||
|
"max_preserve_newlines": 2,
|
||||||
|
"jslint_happy": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# Ignore everything recursively
|
|
||||||
*
|
|
||||||
|
|
||||||
# But not the .ts files
|
|
||||||
!*.ts*
|
|
||||||
|
|
||||||
*css.d.ts
|
|
||||||
|
|
||||||
# Check subdirectories too
|
|
||||||
!*/
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"arrowParens": "always",
|
|
||||||
"endOfLine": "auto",
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "es5"
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"stylelint-order"
|
"stylelint-order"
|
||||||
],
|
],
|
||||||
"ignoreFiles": [
|
"ignoreFiles": [
|
||||||
"frontend/src/Styles/scaffolding.css",
|
"frontend/src/Styles/scaffolding.css",
|
||||||
"**/*.js"
|
"**/*.js"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"at-rule-empty-line-before": [
|
"at-rule-empty-line-before": [
|
||||||
"always",
|
"always",
|
||||||
{
|
{
|
||||||
@@ -15,6 +15,9 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"at-rule-name-case": "lower",
|
||||||
|
"at-rule-name-newline-after": "always-multi-line",
|
||||||
|
"at-rule-name-space-after": "always",
|
||||||
"at-rule-no-unknown": [
|
"at-rule-no-unknown": [
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
@@ -25,36 +28,83 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"at-rule-no-vendor-prefix": true,
|
"at-rule-no-vendor-prefix": true,
|
||||||
|
"at-rule-semicolon-newline-after": "always",
|
||||||
|
"at-rule-semicolon-space-before": "never",
|
||||||
|
"block-closing-brace-empty-line-before": "never",
|
||||||
|
"block-closing-brace-newline-after": "always",
|
||||||
|
"block-closing-brace-newline-before": "always",
|
||||||
|
"block-closing-brace-space-after": "always-single-line",
|
||||||
|
"block-closing-brace-space-before": "always-single-line",
|
||||||
"block-no-empty": true,
|
"block-no-empty": true,
|
||||||
|
"block-opening-brace-newline-after": "always",
|
||||||
|
"block-opening-brace-newline-before": "never-single-line",
|
||||||
|
"block-opening-brace-space-after": "always-single-line",
|
||||||
|
"block-opening-brace-space-before": "always",
|
||||||
|
"color-hex-case": "lower",
|
||||||
"color-hex-length": "short",
|
"color-hex-length": "short",
|
||||||
"color-named": "never",
|
"color-named": "never",
|
||||||
"color-no-invalid-hex": true,
|
"color-no-invalid-hex": true,
|
||||||
"comment-whitespace-inside": "always",
|
"comment-whitespace-inside": "always",
|
||||||
|
"declaration-bang-space-after": "never",
|
||||||
|
"declaration-bang-space-before": "always",
|
||||||
"declaration-block-no-duplicate-properties": [
|
"declaration-block-no-duplicate-properties": [
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
"ignoreProperties": [
|
"ignoreProperties": [
|
||||||
"composes"
|
"composes"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"declaration-block-no-redundant-longhand-properties": true,
|
"declaration-block-no-redundant-longhand-properties": true,
|
||||||
"declaration-block-no-shorthand-property-overrides": true,
|
"declaration-block-no-shorthand-property-overrides": true,
|
||||||
|
"declaration-block-semicolon-newline-after": "always",
|
||||||
|
"declaration-block-semicolon-newline-before": "never-multi-line",
|
||||||
|
"declaration-block-semicolon-space-before": "never",
|
||||||
"declaration-block-single-line-max-declarations": 1,
|
"declaration-block-single-line-max-declarations": 1,
|
||||||
|
"declaration-block-trailing-semicolon": "always",
|
||||||
|
"declaration-colon-space-after": "always",
|
||||||
|
"declaration-colon-space-before": "never",
|
||||||
"font-family-name-quotes": "always-unless-keyword",
|
"font-family-name-quotes": "always-unless-keyword",
|
||||||
"function-calc-no-unspaced-operator": true,
|
"function-calc-no-unspaced-operator": true,
|
||||||
|
"function-comma-newline-after": "never-multi-line",
|
||||||
|
"function-comma-newline-before": "never-multi-line",
|
||||||
|
"function-comma-space-after": "always",
|
||||||
|
"function-comma-space-before": "never",
|
||||||
"function-linear-gradient-no-nonstandard-direction": true,
|
"function-linear-gradient-no-nonstandard-direction": true,
|
||||||
"function-name-case": "lower",
|
"function-name-case": "lower",
|
||||||
|
"function-parentheses-newline-inside": "never-multi-line",
|
||||||
|
"function-parentheses-space-inside": "never",
|
||||||
"function-url-quotes": "always",
|
"function-url-quotes": "always",
|
||||||
"function-url-scheme-disallowed-list": [
|
"function-url-scheme-disallowed-list": [
|
||||||
"data"
|
"data"
|
||||||
],
|
],
|
||||||
|
"function-whitespace-after": "always",
|
||||||
|
"indentation": 2,
|
||||||
"keyframe-declaration-no-important": true,
|
"keyframe-declaration-no-important": true,
|
||||||
"length-zero-no-unit": true,
|
"length-zero-no-unit": true,
|
||||||
|
"max-empty-lines": 1,
|
||||||
|
"max-line-length": [
|
||||||
|
100,
|
||||||
|
{
|
||||||
|
"ignore": [
|
||||||
|
"non-comments"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"max-nesting-depth": 2,
|
"max-nesting-depth": 2,
|
||||||
|
"media-feature-colon-space-after": "always",
|
||||||
|
"media-feature-colon-space-before": "never",
|
||||||
|
"media-feature-name-case": "lower",
|
||||||
"media-feature-name-no-vendor-prefix": true,
|
"media-feature-name-no-vendor-prefix": true,
|
||||||
|
"media-feature-range-operator-space-after": "always",
|
||||||
|
"media-feature-range-operator-space-before": "always",
|
||||||
"no-empty-source": true,
|
"no-empty-source": true,
|
||||||
|
"no-eol-whitespace": true,
|
||||||
|
"no-extra-semicolons": true,
|
||||||
"no-invalid-double-slash-comments": true,
|
"no-invalid-double-slash-comments": true,
|
||||||
|
"no-missing-end-of-source-newline": true,
|
||||||
|
"number-leading-zero": "always",
|
||||||
|
"number-no-trailing-zeros": true,
|
||||||
"order/order": [
|
"order/order": [
|
||||||
"custom-properties",
|
"custom-properties",
|
||||||
"dollar-variables",
|
"dollar-variables",
|
||||||
@@ -82,7 +132,6 @@
|
|||||||
"right",
|
"right",
|
||||||
"bottom",
|
"bottom",
|
||||||
"left",
|
"left",
|
||||||
"inset",
|
|
||||||
"z-index",
|
"z-index",
|
||||||
"display",
|
"display",
|
||||||
"visibility",
|
"visibility",
|
||||||
@@ -294,33 +343,54 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"property-case": "lower",
|
||||||
"property-no-vendor-prefix": true,
|
"property-no-vendor-prefix": true,
|
||||||
"rule-empty-line-before": [
|
"rule-empty-line-before": [
|
||||||
"always",
|
"always",
|
||||||
{
|
{
|
||||||
"except": [
|
"except": [
|
||||||
"first-nested"
|
"first-nested"
|
||||||
],
|
],
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"after-comment"
|
"after-comment"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"selector-attribute-brackets-space-inside": "never",
|
||||||
|
"selector-attribute-operator-space-after": "never",
|
||||||
|
"selector-attribute-operator-space-before": "never",
|
||||||
"selector-attribute-quotes": "never",
|
"selector-attribute-quotes": "never",
|
||||||
"selector-class-pattern": "^[A-Za-z0-9]+$",
|
"selector-class-pattern": "^[A-Za-z0-9]+$",
|
||||||
|
"selector-combinator-space-after": "always",
|
||||||
|
"selector-combinator-space-before": "always",
|
||||||
|
"selector-descendant-combinator-no-non-space": true,
|
||||||
|
"selector-list-comma-newline-after": "always",
|
||||||
|
"selector-list-comma-newline-before": "never-multi-line",
|
||||||
|
"selector-list-comma-space-before": "never",
|
||||||
"selector-max-attribute": 0,
|
"selector-max-attribute": 0,
|
||||||
"selector-max-class": 3,
|
"selector-max-class": 3,
|
||||||
"selector-max-compound-selectors": 3,
|
"selector-max-compound-selectors": 3,
|
||||||
|
"selector-max-empty-lines": 0,
|
||||||
"selector-max-id": 0,
|
"selector-max-id": 0,
|
||||||
"selector-max-universal": 0,
|
"selector-max-universal": 0,
|
||||||
|
"selector-pseudo-class-case": "lower",
|
||||||
|
"selector-pseudo-class-parentheses-space-inside": "never",
|
||||||
|
"selector-pseudo-element-case": "lower",
|
||||||
"selector-pseudo-element-colon-notation": "double",
|
"selector-pseudo-element-colon-notation": "double",
|
||||||
"selector-pseudo-element-no-unknown": true,
|
"selector-pseudo-element-no-unknown": true,
|
||||||
"selector-type-case": "lower",
|
"selector-type-case": "lower",
|
||||||
"selector-type-no-unknown": true,
|
"selector-type-no-unknown": true,
|
||||||
"shorthand-property-no-redundant-values": true,
|
"shorthand-property-no-redundant-values": true,
|
||||||
"string-no-newline": true,
|
"string-no-newline": true,
|
||||||
|
"string-quotes": "single",
|
||||||
"time-min-milliseconds": 100,
|
"time-min-milliseconds": 100,
|
||||||
|
"unit-case": "lower",
|
||||||
"unit-no-unknown": true,
|
"unit-no-unknown": true,
|
||||||
|
"value-list-comma-newline-after": "never-multi-line",
|
||||||
|
"value-list-comma-newline-before": "never-multi-line",
|
||||||
|
"value-list-comma-space-after": "always",
|
||||||
|
"value-list-comma-space-before": "never",
|
||||||
|
"value-list-max-empty-lines": 0,
|
||||||
"value-no-vendor-prefix": true
|
"value-no-vendor-prefix": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
frontend/.vscode/extensions.json
vendored
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"stylelint.vscode-stylelint",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"esbenp.prettier-vscode"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
23
frontend/.vscode/settings.json
vendored
@@ -1,23 +0,0 @@
|
|||||||
// Place your settings in this file to overwrite default and user settings.
|
|
||||||
{
|
|
||||||
"files.insertFinalNewline": true,
|
|
||||||
|
|
||||||
"files.exclude": {
|
|
||||||
"**/node_modules": true,
|
|
||||||
"**/*.d.css": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"editor.formatOnSave": false,
|
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.fixAll": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"typescript.preferences.quoteStyle": "single",
|
|
||||||
|
|
||||||
"eslint.validate": [
|
|
||||||
"javascript",
|
|
||||||
"javascriptreact",
|
|
||||||
"typescript",
|
|
||||||
"typescriptreact"
|
|
||||||
],
|
|
||||||
}
|
|
||||||
@@ -4,21 +4,20 @@ module.exports = {
|
|||||||
plugins: [
|
plugins: [
|
||||||
// Stage 1
|
// Stage 1
|
||||||
'@babel/plugin-proposal-export-default-from',
|
'@babel/plugin-proposal-export-default-from',
|
||||||
['@babel/plugin-transform-optional-chaining', { loose }],
|
['@babel/plugin-proposal-optional-chaining', { loose }],
|
||||||
['@babel/plugin-transform-nullish-coalescing-operator', { loose }],
|
['@babel/plugin-proposal-nullish-coalescing-operator', { loose }],
|
||||||
|
|
||||||
// Stage 2
|
// Stage 2
|
||||||
'@babel/plugin-transform-export-namespace-from',
|
'@babel/plugin-proposal-export-namespace-from',
|
||||||
|
|
||||||
// Stage 3
|
// Stage 3
|
||||||
['@babel/plugin-transform-class-properties', { loose }],
|
['@babel/plugin-proposal-class-properties', { loose }],
|
||||||
'@babel/plugin-syntax-dynamic-import'
|
'@babel/plugin-syntax-dynamic-import'
|
||||||
],
|
],
|
||||||
env: {
|
env: {
|
||||||
development: {
|
development: {
|
||||||
presets: [
|
presets: [
|
||||||
['@babel/preset-react', { development: true }],
|
['@babel/preset-react', { development: true }]
|
||||||
'@babel/preset-typescript'
|
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
'babel-plugin-inline-classnames'
|
'babel-plugin-inline-classnames'
|
||||||
@@ -26,8 +25,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
production: {
|
production: {
|
||||||
presets: [
|
presets: [
|
||||||
'@babel/preset-react',
|
'@babel/preset-react'
|
||||||
'@babel/preset-typescript'
|
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
'babel-plugin-transform-react-remove-prop-types'
|
'babel-plugin-transform-react-remove-prop-types'
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const FileManagerPlugin = require('filemanager-webpack-plugin');
|
const FileManagerPlugin = require('filemanager-webpack-plugin');
|
||||||
@@ -6,7 +5,6 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|||||||
const LiveReloadPlugin = require('webpack-livereload-plugin');
|
const LiveReloadPlugin = require('webpack-livereload-plugin');
|
||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
const TerserPlugin = require('terser-webpack-plugin');
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
|
||||||
|
|
||||||
module.exports = (env) => {
|
module.exports = (env) => {
|
||||||
const uiFolder = 'UI';
|
const uiFolder = 'UI';
|
||||||
@@ -36,22 +34,17 @@ module.exports = (env) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
entry: {
|
entry: {
|
||||||
index: 'index.ts'
|
index: 'index.js'
|
||||||
},
|
},
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: [
|
|
||||||
'.ts',
|
|
||||||
'.tsx',
|
|
||||||
'.js'
|
|
||||||
],
|
|
||||||
modules: [
|
modules: [
|
||||||
srcFolder,
|
srcFolder,
|
||||||
path.join(srcFolder, 'Shims'),
|
path.join(srcFolder, 'Shims'),
|
||||||
'node_modules'
|
'node_modules'
|
||||||
],
|
],
|
||||||
alias: {
|
alias: {
|
||||||
jquery: 'jquery/dist/jquery.min'
|
jquery: 'jquery/src/jquery'
|
||||||
},
|
},
|
||||||
fallback: {
|
fallback: {
|
||||||
buffer: false,
|
buffer: false,
|
||||||
@@ -66,23 +59,23 @@ module.exports = (env) => {
|
|||||||
output: {
|
output: {
|
||||||
path: distFolder,
|
path: distFolder,
|
||||||
publicPath: '/',
|
publicPath: '/',
|
||||||
filename: '[name]-[contenthash].js',
|
filename: '[name].js',
|
||||||
sourceMapFilename: '[file].map'
|
sourceMapFilename: '[file].map'
|
||||||
},
|
},
|
||||||
|
|
||||||
optimization: {
|
optimization: {
|
||||||
moduleIds: 'deterministic',
|
moduleIds: 'deterministic',
|
||||||
chunkIds: isProduction ? 'deterministic' : 'named'
|
chunkIds: 'named',
|
||||||
|
splitChunks: {
|
||||||
|
chunks: 'initial',
|
||||||
|
name: 'vendors'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
performance: {
|
performance: {
|
||||||
hints: false
|
hints: false
|
||||||
},
|
},
|
||||||
|
|
||||||
experiments: {
|
|
||||||
topLevelAwait: true
|
|
||||||
},
|
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
__DEV__: !isProduction,
|
__DEV__: !isProduction,
|
||||||
@@ -90,15 +83,13 @@ module.exports = (env) => {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: 'Content/styles.css',
|
filename: 'Content/styles.css'
|
||||||
chunkFilename: 'Content/[id]-[chunkhash].css'
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: 'frontend/src/index.ejs',
|
template: 'frontend/src/index.ejs',
|
||||||
filename: 'index.html',
|
filename: 'index.html',
|
||||||
publicPath: '/',
|
publicPath: '/'
|
||||||
inject: false
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new FileManagerPlugin({
|
new FileManagerPlugin({
|
||||||
@@ -139,8 +130,6 @@ module.exports = (env) => {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new ForkTsCheckerWebpackPlugin(),
|
|
||||||
|
|
||||||
new LiveReloadPlugin()
|
new LiveReloadPlugin()
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -164,7 +153,7 @@ module.exports = (env) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: [/\.jsx?$/, /\.tsx?$/],
|
test: /\.js?$/,
|
||||||
exclude: /(node_modules|JsLibraries)/,
|
exclude: /(node_modules|JsLibraries)/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
@@ -195,7 +184,6 @@ module.exports = (env) => {
|
|||||||
exclude: /(node_modules|globals.css)/,
|
exclude: /(node_modules|globals.css)/,
|
||||||
use: [
|
use: [
|
||||||
{ loader: MiniCssExtractPlugin.loader },
|
{ loader: MiniCssExtractPlugin.loader },
|
||||||
{ loader: 'css-modules-typescript-loader' },
|
|
||||||
{
|
{
|
||||||
loader: 'css-loader',
|
loader: 'css-loader',
|
||||||
options: {
|
options: {
|
||||||
@@ -235,7 +223,6 @@ module.exports = (env) => {
|
|||||||
{
|
{
|
||||||
loader: 'url-loader',
|
loader: 'url-loader',
|
||||||
options: {
|
options: {
|
||||||
limit: 10240,
|
|
||||||
mimetype: 'application/font-woff',
|
mimetype: 'application/font-woff',
|
||||||
emitFile: false,
|
emitFile: false,
|
||||||
name: 'Content/Fonts/[name].[ext]'
|
name: 'Content/Fonts/[name].[ext]'
|
||||||
@@ -264,19 +251,18 @@ module.exports = (env) => {
|
|||||||
config.resolve.alias['react-dom$'] = 'react-dom/profiling';
|
config.resolve.alias['react-dom$'] = 'react-dom/profiling';
|
||||||
config.resolve.alias['scheduler/tracing'] = 'scheduler/tracing-profiling';
|
config.resolve.alias['scheduler/tracing'] = 'scheduler/tracing-profiling';
|
||||||
|
|
||||||
config.optimization = {
|
config.optimization.minimizer = [
|
||||||
minimize: true,
|
new TerserPlugin({
|
||||||
minimizer: [
|
cache: true,
|
||||||
new TerserPlugin({
|
parallel: true,
|
||||||
terserOptions: {
|
sourceMap: true, // Must be set to true if using source-maps in production
|
||||||
sourceMap: true, // Must be set to true if using source-maps in production
|
terserOptions: {
|
||||||
mangle: false,
|
mangle: false,
|
||||||
keep_classnames: true,
|
keep_classnames: true,
|
||||||
keep_fnames: true
|
keep_fnames: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
]
|
];
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
|
|||||||
4
frontend/src/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// Place your settings in this file to overwrite default and user settings.
|
||||||
|
{
|
||||||
|
"files.insertFinalNewline": true
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Alert from 'Components/Alert';
|
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
@@ -157,16 +156,16 @@ class Blocklist extends Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
!isFetching && !!error &&
|
!isFetching && !!error &&
|
||||||
<Alert kind={kinds.DANGER}>
|
<div>
|
||||||
{translate('BlocklistLoadError')}
|
{translate('UnableToLoadBlocklist')}
|
||||||
</Alert>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
isPopulated && !error && !items.length &&
|
isPopulated && !error && !items.length &&
|
||||||
<Alert kind={kinds.INFO}>
|
<div>
|
||||||
{translate('NoHistoryBlocklist')}
|
{translate('NoHistory')}
|
||||||
</Alert>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -210,7 +209,7 @@ class Blocklist extends Component {
|
|||||||
isOpen={isConfirmRemoveModalOpen}
|
isOpen={isConfirmRemoveModalOpen}
|
||||||
kind={kinds.DANGER}
|
kind={kinds.DANGER}
|
||||||
title={translate('RemoveSelected')}
|
title={translate('RemoveSelected')}
|
||||||
message={translate('RemoveSelectedBlocklistMessageText')}
|
message={translate('AreYouSureYouWantToRemoveTheSelectedItemsFromBlocklist')}
|
||||||
confirmLabel={translate('RemoveSelected')}
|
confirmLabel={translate('RemoveSelected')}
|
||||||
onConfirm={this.onRemoveSelectedConfirmed}
|
onConfirm={this.onRemoveSelectedConfirmed}
|
||||||
onCancel={this.onConfirmRemoveModalClose}
|
onCancel={this.onConfirmRemoveModalClose}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'actions': string;
|
|
||||||
'indexer': string;
|
|
||||||
'language': string;
|
|
||||||
'quality': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -82,7 +82,7 @@ class BlocklistRow extends Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'movieMetadata.sortTitle') {
|
if (name === 'movies.sortTitle') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
<MovieTitleLink
|
<MovieTitleLink
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'description': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -7,7 +7,6 @@ import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionList
|
|||||||
import Link from 'Components/Link/Link';
|
import Link from 'Components/Link/Link';
|
||||||
import formatDateTime from 'Utilities/Date/formatDateTime';
|
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||||
import formatAge from 'Utilities/Number/formatAge';
|
import formatAge from 'Utilities/Number/formatAge';
|
||||||
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
|
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import styles from './HistoryDetails.css';
|
import styles from './HistoryDetails.css';
|
||||||
|
|
||||||
@@ -16,7 +15,6 @@ function HistoryDetails(props) {
|
|||||||
eventType,
|
eventType,
|
||||||
sourceTitle,
|
sourceTitle,
|
||||||
data,
|
data,
|
||||||
downloadId,
|
|
||||||
shortDateFormat,
|
shortDateFormat,
|
||||||
timeFormat
|
timeFormat
|
||||||
} = props;
|
} = props;
|
||||||
@@ -25,11 +23,10 @@ function HistoryDetails(props) {
|
|||||||
const {
|
const {
|
||||||
indexer,
|
indexer,
|
||||||
releaseGroup,
|
releaseGroup,
|
||||||
movieMatchType,
|
|
||||||
customFormatScore,
|
|
||||||
nzbInfoUrl,
|
nzbInfoUrl,
|
||||||
downloadClient,
|
downloadClient,
|
||||||
downloadClientName,
|
downloadClientName,
|
||||||
|
downloadId,
|
||||||
age,
|
age,
|
||||||
ageHours,
|
ageHours,
|
||||||
ageMinutes,
|
ageMinutes,
|
||||||
@@ -47,55 +44,33 @@ function HistoryDetails(props) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{
|
{
|
||||||
indexer ?
|
!!indexer &&
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
title={translate('Indexer')}
|
title={translate('Indexer')}
|
||||||
data={indexer}
|
data={indexer}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
releaseGroup ?
|
!!releaseGroup &&
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
descriptionClassName={styles.description}
|
descriptionClassName={styles.description}
|
||||||
title={translate('ReleaseGroup')}
|
title={translate('ReleaseGroup')}
|
||||||
data={releaseGroup}
|
data={releaseGroup}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
customFormatScore && customFormatScore !== '0' ?
|
!!nzbInfoUrl &&
|
||||||
<DescriptionListItem
|
|
||||||
title={translate('CustomFormatScore')}
|
|
||||||
data={formatCustomFormatScore(customFormatScore)}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
movieMatchType ?
|
|
||||||
<DescriptionListItem
|
|
||||||
descriptionClassName={styles.description}
|
|
||||||
title={translate('MovieMatchType')}
|
|
||||||
data={movieMatchType}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
nzbInfoUrl ?
|
|
||||||
<span>
|
<span>
|
||||||
<DescriptionListItemTitle>
|
<DescriptionListItemTitle>
|
||||||
{translate('InfoUrl')}
|
Info URL
|
||||||
</DescriptionListItemTitle>
|
</DescriptionListItemTitle>
|
||||||
|
|
||||||
<DescriptionListItemDescription>
|
<DescriptionListItemDescription>
|
||||||
<Link to={nzbInfoUrl}>{nzbInfoUrl}</Link>
|
<Link to={nzbInfoUrl}>{nzbInfoUrl}</Link>
|
||||||
</DescriptionListItemDescription>
|
</DescriptionListItemDescription>
|
||||||
</span> :
|
</span>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -108,30 +83,27 @@ function HistoryDetails(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
downloadId ?
|
!!downloadId &&
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
title={translate('GrabId')}
|
title={translate('GrabID')}
|
||||||
data={downloadId}
|
data={downloadId}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
indexer ?
|
!!indexer &&
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
title={translate('AgeWhenGrabbed')}
|
title={translate('AgeWhenGrabbed')}
|
||||||
data={formatAge(age, ageHours, ageMinutes)}
|
data={formatAge(age, ageHours, ageMinutes)}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
publishedDate ?
|
!!publishedDate &&
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
title={translate('PublishedDate')}
|
title={translate('PublishedDate')}
|
||||||
data={formatDateTime(publishedDate, shortDateFormat, timeFormat, { includeSeconds: true })}
|
data={formatDateTime(publishedDate, shortDateFormat, timeFormat, { includeSeconds: true })}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
</DescriptionList>
|
</DescriptionList>
|
||||||
);
|
);
|
||||||
@@ -151,21 +123,11 @@ function HistoryDetails(props) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{
|
{
|
||||||
downloadId ?
|
!!message &&
|
||||||
<DescriptionListItem
|
|
||||||
title={translate('GrabId')}
|
|
||||||
data={downloadId}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
message ?
|
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
title={translate('Message')}
|
title={translate('Message')}
|
||||||
data={message}
|
data={message}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
</DescriptionList>
|
</DescriptionList>
|
||||||
);
|
);
|
||||||
@@ -173,7 +135,6 @@ function HistoryDetails(props) {
|
|||||||
|
|
||||||
if (eventType === 'downloadFolderImported') {
|
if (eventType === 'downloadFolderImported') {
|
||||||
const {
|
const {
|
||||||
customFormatScore,
|
|
||||||
droppedPath,
|
droppedPath,
|
||||||
importedPath
|
importedPath
|
||||||
} = data;
|
} = data;
|
||||||
@@ -187,32 +148,21 @@ function HistoryDetails(props) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{
|
{
|
||||||
droppedPath ?
|
!!droppedPath &&
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
descriptionClassName={styles.description}
|
descriptionClassName={styles.description}
|
||||||
title={translate('Source')}
|
title={translate('Source')}
|
||||||
data={droppedPath}
|
data={droppedPath}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
importedPath ?
|
!!importedPath &&
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
descriptionClassName={styles.description}
|
descriptionClassName={styles.description}
|
||||||
title={translate('ImportedTo')}
|
title={translate('ImportedTo')}
|
||||||
data={importedPath}
|
data={importedPath}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
customFormatScore && customFormatScore !== '0' ?
|
|
||||||
<DescriptionListItem
|
|
||||||
title={translate('CustomFormatScore')}
|
|
||||||
data={formatCustomFormatScore(customFormatScore)}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
</DescriptionList>
|
</DescriptionList>
|
||||||
);
|
);
|
||||||
@@ -220,21 +170,20 @@ function HistoryDetails(props) {
|
|||||||
|
|
||||||
if (eventType === 'movieFileDeleted') {
|
if (eventType === 'movieFileDeleted') {
|
||||||
const {
|
const {
|
||||||
reason,
|
reason
|
||||||
customFormatScore
|
|
||||||
} = data;
|
} = data;
|
||||||
|
|
||||||
let reasonMessage = '';
|
let reasonMessage = '';
|
||||||
|
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case 'Manual':
|
case 'Manual':
|
||||||
reasonMessage = translate('DeletedReasonManual');
|
reasonMessage = translate('FileWasDeletedByViaUI');
|
||||||
break;
|
break;
|
||||||
case 'MissingFromDisk':
|
case 'MissingFromDisk':
|
||||||
reasonMessage = translate('DeletedReasonMissingFromDisk');
|
reasonMessage = translate('MissingFromDisk');
|
||||||
break;
|
break;
|
||||||
case 'Upgrade':
|
case 'Upgrade':
|
||||||
reasonMessage = translate('DeletedReasonUpgrade');
|
reasonMessage = translate('FileWasDeletedByUpgrade');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
reasonMessage = '';
|
reasonMessage = '';
|
||||||
@@ -251,15 +200,6 @@ function HistoryDetails(props) {
|
|||||||
title={translate('Reason')}
|
title={translate('Reason')}
|
||||||
data={reasonMessage}
|
data={reasonMessage}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{
|
|
||||||
customFormatScore && customFormatScore !== '0' ?
|
|
||||||
<DescriptionListItem
|
|
||||||
title={translate('CustomFormatScore')}
|
|
||||||
data={formatCustomFormatScore(customFormatScore)}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</DescriptionList>
|
</DescriptionList>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -311,21 +251,11 @@ function HistoryDetails(props) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{
|
{
|
||||||
downloadId ?
|
!!message &&
|
||||||
<DescriptionListItem
|
|
||||||
title={translate('GrabId')}
|
|
||||||
data={downloadId}
|
|
||||||
/> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
message ?
|
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
title={translate('Message')}
|
title={translate('Message')}
|
||||||
data={message}
|
data={message}
|
||||||
/> :
|
/>
|
||||||
null
|
|
||||||
}
|
}
|
||||||
</DescriptionList>
|
</DescriptionList>
|
||||||
);
|
);
|
||||||
@@ -346,7 +276,6 @@ HistoryDetails.propTypes = {
|
|||||||
eventType: PropTypes.string.isRequired,
|
eventType: PropTypes.string.isRequired,
|
||||||
sourceTitle: PropTypes.string.isRequired,
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
downloadId: PropTypes.string,
|
|
||||||
shortDateFormat: PropTypes.string.isRequired,
|
shortDateFormat: PropTypes.string.isRequired,
|
||||||
timeFormat: PropTypes.string.isRequired
|
timeFormat: PropTypes.string.isRequired
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'markAsFailedButton': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -15,19 +15,19 @@ import styles from './HistoryDetailsModal.css';
|
|||||||
function getHeaderTitle(eventType) {
|
function getHeaderTitle(eventType) {
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case 'grabbed':
|
case 'grabbed':
|
||||||
return translate('Grabbed');
|
return 'Grabbed';
|
||||||
case 'downloadFailed':
|
case 'downloadFailed':
|
||||||
return translate('DownloadFailed');
|
return 'Download Failed';
|
||||||
case 'downloadFolderImported':
|
case 'downloadFolderImported':
|
||||||
return translate('MovieImported');
|
return 'Movie Imported';
|
||||||
case 'movieFileDeleted':
|
case 'movieFileDeleted':
|
||||||
return translate('MovieFileDeleted');
|
return 'Movie File Deleted';
|
||||||
case 'movieFileRenamed':
|
case 'movieFileRenamed':
|
||||||
return translate('MovieFileRenamed');
|
return 'Movie File Renamed';
|
||||||
case 'downloadIgnored':
|
case 'downloadIgnored':
|
||||||
return translate('DownloadIgnored');
|
return 'Download Ignored';
|
||||||
default:
|
default:
|
||||||
return translate('Unknown');
|
return 'Unknown';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,6 @@ function HistoryDetailsModal(props) {
|
|||||||
eventType,
|
eventType,
|
||||||
sourceTitle,
|
sourceTitle,
|
||||||
data,
|
data,
|
||||||
downloadId,
|
|
||||||
isMarkingAsFailed,
|
isMarkingAsFailed,
|
||||||
shortDateFormat,
|
shortDateFormat,
|
||||||
timeFormat,
|
timeFormat,
|
||||||
@@ -60,7 +59,6 @@ function HistoryDetailsModal(props) {
|
|||||||
eventType={eventType}
|
eventType={eventType}
|
||||||
sourceTitle={sourceTitle}
|
sourceTitle={sourceTitle}
|
||||||
data={data}
|
data={data}
|
||||||
downloadId={downloadId}
|
|
||||||
shortDateFormat={shortDateFormat}
|
shortDateFormat={shortDateFormat}
|
||||||
timeFormat={timeFormat}
|
timeFormat={timeFormat}
|
||||||
/>
|
/>
|
||||||
@@ -75,7 +73,7 @@ function HistoryDetailsModal(props) {
|
|||||||
isSpinning={isMarkingAsFailed}
|
isSpinning={isMarkingAsFailed}
|
||||||
onPress={onMarkAsFailedPress}
|
onPress={onMarkAsFailedPress}
|
||||||
>
|
>
|
||||||
{translate('MarkAsFailed')}
|
Mark as Failed
|
||||||
</SpinnerButton>
|
</SpinnerButton>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +93,6 @@ HistoryDetailsModal.propTypes = {
|
|||||||
eventType: PropTypes.string.isRequired,
|
eventType: PropTypes.string.isRequired,
|
||||||
sourceTitle: PropTypes.string.isRequired,
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
downloadId: PropTypes.string,
|
|
||||||
isMarkingAsFailed: PropTypes.bool.isRequired,
|
isMarkingAsFailed: PropTypes.bool.isRequired,
|
||||||
shortDateFormat: PropTypes.string.isRequired,
|
shortDateFormat: PropTypes.string.isRequired,
|
||||||
timeFormat: PropTypes.string.isRequired,
|
timeFormat: PropTypes.string.isRequired,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Alert from 'Components/Alert';
|
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
import FilterMenu from 'Components/Menu/FilterMenu';
|
import FilterMenu from 'Components/Menu/FilterMenu';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
@@ -12,7 +11,7 @@ import Table from 'Components/Table/Table';
|
|||||||
import TableBody from 'Components/Table/TableBody';
|
import TableBody from 'Components/Table/TableBody';
|
||||||
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||||
import TablePager from 'Components/Table/TablePager';
|
import TablePager from 'Components/Table/TablePager';
|
||||||
import { align, icons, kinds } from 'Helpers/Props';
|
import { align, icons } from 'Helpers/Props';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import HistoryRowConnector from './HistoryRowConnector';
|
import HistoryRowConnector from './HistoryRowConnector';
|
||||||
|
|
||||||
@@ -84,9 +83,9 @@ class History extends Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
!isFetchingAny && hasError &&
|
!isFetchingAny && hasError &&
|
||||||
<Alert kind={kinds.DANGER}>
|
<div>
|
||||||
{translate('HistoryLoadError')}
|
{translate('UnableToLoadHistory')}
|
||||||
</Alert>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -94,9 +93,9 @@ class History extends Component {
|
|||||||
// wait for the episodes to populate because they are never coming.
|
// wait for the episodes to populate because they are never coming.
|
||||||
|
|
||||||
isPopulated && !hasError && !items.length &&
|
isPopulated && !hasError && !items.length &&
|
||||||
<Alert kind={kinds.INFO}>
|
<div>
|
||||||
{translate('NoHistoryFound')}
|
{translate('NoHistory')}
|
||||||
</Alert>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'cell': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -3,7 +3,6 @@ import React from 'react';
|
|||||||
import Icon from 'Components/Icon';
|
import Icon from 'Components/Icon';
|
||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import { icons, kinds } from 'Helpers/Props';
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
import styles from './HistoryEventTypeCell.css';
|
import styles from './HistoryEventTypeCell.css';
|
||||||
|
|
||||||
function getIconName(eventType) {
|
function getIconName(eventType) {
|
||||||
@@ -39,21 +38,21 @@ function getIconKind(eventType) {
|
|||||||
function getTooltip(eventType, data) {
|
function getTooltip(eventType, data) {
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case 'grabbed':
|
case 'grabbed':
|
||||||
return translate('MovieGrabbedHistoryTooltip', { indexer: data.indexer, downloadClient: data.downloadClient });
|
return `Movie grabbed from ${data.indexer} and sent to ${data.downloadClient}`;
|
||||||
case 'movieFolderImported':
|
case 'movieFolderImported':
|
||||||
return translate('MovieFolderImportedTooltip');
|
return 'Movie imported from movie folder';
|
||||||
case 'downloadFolderImported':
|
case 'downloadFolderImported':
|
||||||
return translate('MovieImportedTooltip');
|
return 'Movie downloaded successfully and picked up from download client';
|
||||||
case 'downloadFailed':
|
case 'downloadFailed':
|
||||||
return translate('MovieDownloadFailedTooltip');
|
return 'Movie download failed';
|
||||||
case 'movieFileDeleted':
|
case 'movieFileDeleted':
|
||||||
return translate('MovieFileDeletedTooltip');
|
return 'Movie file deleted';
|
||||||
case 'movieFileRenamed':
|
case 'movieFileRenamed':
|
||||||
return translate('MovieFileRenamedTooltip');
|
return 'Movie file renamed';
|
||||||
case 'downloadIgnored':
|
case 'downloadIgnored':
|
||||||
return translate('MovieDownloadIgnoredTooltip');
|
return 'Movie Download Ignored';
|
||||||
default:
|
default:
|
||||||
return translate('UnknownEventTooltip');
|
return 'Unknown event';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'customFormatScore': string;
|
|
||||||
'details': string;
|
|
||||||
'downloadClient': string;
|
|
||||||
'indexer': string;
|
|
||||||
'releaseGroup': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -4,8 +4,7 @@ import IconButton from 'Components/Link/IconButton';
|
|||||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
import { icons } from 'Helpers/Props';
|
||||||
import { icons, tooltipPositions } from 'Helpers/Props';
|
|
||||||
import MovieFormats from 'Movie/MovieFormats';
|
import MovieFormats from 'Movie/MovieFormats';
|
||||||
import MovieLanguage from 'Movie/MovieLanguage';
|
import MovieLanguage from 'Movie/MovieLanguage';
|
||||||
import MovieQuality from 'Movie/MovieQuality';
|
import MovieQuality from 'Movie/MovieQuality';
|
||||||
@@ -64,7 +63,6 @@ class HistoryRow extends Component {
|
|||||||
sourceTitle,
|
sourceTitle,
|
||||||
date,
|
date,
|
||||||
data,
|
data,
|
||||||
downloadId,
|
|
||||||
isMarkingAsFailed,
|
isMarkingAsFailed,
|
||||||
columns,
|
columns,
|
||||||
shortDateFormat,
|
shortDateFormat,
|
||||||
@@ -99,7 +97,7 @@ class HistoryRow extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'movieMetadata.sortTitle') {
|
if (name === 'movies.sortTitle') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
<MovieTitleLink
|
<MovieTitleLink
|
||||||
@@ -178,14 +176,7 @@ class HistoryRow extends Component {
|
|||||||
key={name}
|
key={name}
|
||||||
className={styles.customFormatScore}
|
className={styles.customFormatScore}
|
||||||
>
|
>
|
||||||
<Tooltip
|
{formatCustomFormatScore(customFormatScore)}
|
||||||
anchor={formatCustomFormatScore(
|
|
||||||
customFormatScore,
|
|
||||||
customFormats.length
|
|
||||||
)}
|
|
||||||
tooltip={<MovieFormats formats={customFormats} />}
|
|
||||||
position={tooltipPositions.BOTTOM}
|
|
||||||
/>
|
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -217,12 +208,10 @@ class HistoryRow extends Component {
|
|||||||
key={name}
|
key={name}
|
||||||
className={styles.details}
|
className={styles.details}
|
||||||
>
|
>
|
||||||
<div className={styles.actionContents}>
|
<IconButton
|
||||||
<IconButton
|
name={icons.INFO}
|
||||||
name={icons.INFO}
|
onPress={this.onDetailsPress}
|
||||||
onPress={this.onDetailsPress}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -236,7 +225,6 @@ class HistoryRow extends Component {
|
|||||||
eventType={eventType}
|
eventType={eventType}
|
||||||
sourceTitle={sourceTitle}
|
sourceTitle={sourceTitle}
|
||||||
data={data}
|
data={data}
|
||||||
downloadId={downloadId}
|
|
||||||
isMarkingAsFailed={isMarkingAsFailed}
|
isMarkingAsFailed={isMarkingAsFailed}
|
||||||
shortDateFormat={shortDateFormat}
|
shortDateFormat={shortDateFormat}
|
||||||
timeFormat={timeFormat}
|
timeFormat={timeFormat}
|
||||||
@@ -261,7 +249,6 @@ HistoryRow.propTypes = {
|
|||||||
sourceTitle: PropTypes.string.isRequired,
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
date: PropTypes.string.isRequired,
|
date: PropTypes.string.isRequired,
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
downloadId: PropTypes.string,
|
|
||||||
isMarkingAsFailed: PropTypes.bool,
|
isMarkingAsFailed: PropTypes.bool,
|
||||||
markAsFailedError: PropTypes.object,
|
markAsFailedError: PropTypes.object,
|
||||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
@@ -270,8 +257,4 @@ HistoryRow.propTypes = {
|
|||||||
onMarkAsFailedPress: PropTypes.func.isRequired
|
onMarkAsFailedPress: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoryRow.defaultProps = {
|
|
||||||
customFormats: []
|
|
||||||
};
|
|
||||||
|
|
||||||
export default HistoryRow;
|
export default HistoryRow;
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'torrent': string;
|
|
||||||
'usenet': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Alert from 'Components/Alert';
|
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
@@ -13,7 +12,7 @@ import Table from 'Components/Table/Table';
|
|||||||
import TableBody from 'Components/Table/TableBody';
|
import TableBody from 'Components/Table/TableBody';
|
||||||
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||||
import TablePager from 'Components/Table/TablePager';
|
import TablePager from 'Components/Table/TablePager';
|
||||||
import { align, icons, kinds } from 'Helpers/Props';
|
import { align, icons } from 'Helpers/Props';
|
||||||
import getRemovedItems from 'Utilities/Object/getRemovedItems';
|
import getRemovedItems from 'Utilities/Object/getRemovedItems';
|
||||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
@@ -232,17 +231,17 @@ class Queue extends Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
!isRefreshing && hasError ?
|
!isRefreshing && hasError ?
|
||||||
<Alert kind={kinds.DANGER}>
|
<div>
|
||||||
{translate('QueueLoadError')}
|
{translate('FailedToLoadQueue')}
|
||||||
</Alert> :
|
</div> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
isAllPopulated && !hasError && !items.length ?
|
isAllPopulated && !hasError && !items.length ?
|
||||||
<Alert kind={kinds.INFO}>
|
<div>
|
||||||
{translate('QueueIsEmpty')}
|
{translate('QueueIsEmpty')}
|
||||||
</Alert> :
|
</div> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
.progressBarContainer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'progressBarContainer': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -1,71 +1,116 @@
|
|||||||
|
import moment from 'moment';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from 'Components/Icon';
|
import Icon from 'Components/Icon';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
import { icons, tooltipPositions } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import QueueStatus from './QueueStatus';
|
|
||||||
import styles from './QueueDetails.css';
|
|
||||||
|
|
||||||
function QueueDetails(props) {
|
function QueueDetails(props) {
|
||||||
const {
|
const {
|
||||||
title,
|
title,
|
||||||
size,
|
size,
|
||||||
sizeleft,
|
sizeleft,
|
||||||
|
estimatedCompletionTime,
|
||||||
status,
|
status,
|
||||||
trackedDownloadState,
|
trackedDownloadState,
|
||||||
trackedDownloadStatus,
|
trackedDownloadStatus,
|
||||||
statusMessages,
|
|
||||||
errorMessage,
|
errorMessage,
|
||||||
progressBar
|
progressBar
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const progress = size ? (100 - sizeleft / size * 100) : 0;
|
const progress = size ? (100 - sizeleft / size * 100) : 0;
|
||||||
const isDownloading = status === 'downloading';
|
|
||||||
const isPaused = status === 'paused';
|
|
||||||
const hasWarning = trackedDownloadStatus === 'warning';
|
|
||||||
const hasError = trackedDownloadStatus === 'error';
|
|
||||||
|
|
||||||
if (
|
|
||||||
(isDownloading || isPaused) &&
|
|
||||||
!hasWarning &&
|
|
||||||
!hasError
|
|
||||||
) {
|
|
||||||
const state = isPaused ? translate('Paused') : translate('Downloading');
|
|
||||||
|
|
||||||
if (progress < 5) {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={icons.DOWNLOADING}
|
|
||||||
title={`${state} - ${progress.toFixed(1)}% ${title}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (status === 'pending') {
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Icon
|
||||||
className={styles.progressBarContainer}
|
name={icons.PENDING}
|
||||||
anchor={progressBar}
|
title={translate('ReleaseWillBeProcessedInterp', [moment(estimatedCompletionTime).fromNow()])}
|
||||||
title={`${state} - ${progress.toFixed(1)}%`}
|
|
||||||
body={
|
|
||||||
<div>{title}</div>
|
|
||||||
}
|
|
||||||
position={tooltipPositions.LEFT}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
if (status === 'completed') {
|
||||||
<QueueStatus
|
if (errorMessage) {
|
||||||
sourceTitle={title}
|
return (
|
||||||
status={status}
|
<Icon
|
||||||
trackedDownloadStatus={trackedDownloadStatus}
|
name={icons.DOWNLOAD}
|
||||||
trackedDownloadState={trackedDownloadState}
|
kind={kinds.DANGER}
|
||||||
statusMessages={statusMessages}
|
title={translate('ImportFailedInterp', [errorMessage])}
|
||||||
errorMessage={errorMessage}
|
/>
|
||||||
position={tooltipPositions.LEFT}
|
);
|
||||||
/>
|
}
|
||||||
);
|
|
||||||
|
if (trackedDownloadStatus === 'warning') {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name={icons.DOWNLOAD}
|
||||||
|
kind={kinds.WARNING}
|
||||||
|
title={translate('UnableToImportCheckLogs')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackedDownloadState === 'importPending') {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name={icons.DOWNLOAD}
|
||||||
|
kind={kinds.PURPLE}
|
||||||
|
title={`${translate('Downloaded')} - ${translate('WaitingToImport')}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackedDownloadState === 'importing') {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name={icons.DOWNLOAD}
|
||||||
|
kind={kinds.PURPLE}
|
||||||
|
title={`${translate('Downloaded')} - ${translate('Importing')}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorMessage) {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name={icons.DOWNLOADING}
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
title={translate('DownloadFailedInterp', [errorMessage])}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'failed') {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name={icons.DOWNLOADING}
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
title={translate('DownloadFailedCheckDownloadClientForMoreDetails')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'warning') {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name={icons.DOWNLOADING}
|
||||||
|
kind={kinds.WARNING}
|
||||||
|
title={translate('DownloadWarningCheckDownloadClientForMoreDetails')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progress < 5) {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
name={icons.DOWNLOADING}
|
||||||
|
title={translate('MovieIsDownloadingInterp', [progress.toFixed(1), title])}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return progressBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueDetails.propTypes = {
|
QueueDetails.propTypes = {
|
||||||
@@ -76,7 +121,6 @@ QueueDetails.propTypes = {
|
|||||||
status: PropTypes.string.isRequired,
|
status: PropTypes.string.isRequired,
|
||||||
trackedDownloadState: PropTypes.string.isRequired,
|
trackedDownloadState: PropTypes.string.isRequired,
|
||||||
trackedDownloadStatus: PropTypes.string.isRequired,
|
trackedDownloadStatus: PropTypes.string.isRequired,
|
||||||
statusMessages: PropTypes.arrayOf(PropTypes.object),
|
|
||||||
errorMessage: PropTypes.string,
|
errorMessage: PropTypes.string,
|
||||||
progressBar: PropTypes.node.isRequired
|
progressBar: PropTypes.node.isRequired
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class QueueOptions extends Component {
|
|||||||
type={inputTypes.CHECK}
|
type={inputTypes.CHECK}
|
||||||
name="includeUnknownMovieItems"
|
name="includeUnknownMovieItems"
|
||||||
value={includeUnknownMovieItems}
|
value={includeUnknownMovieItems}
|
||||||
helpText={translate('ShowUnknownMovieItemsHelpText')}
|
helpText={translate('IncludeUnknownMovieItemsHelpText')}
|
||||||
onChange={this.onOptionChange}
|
onChange={this.onOptionChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|||||||
@@ -16,12 +16,6 @@
|
|||||||
width: 150px;
|
width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.customFormatScore {
|
|
||||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
|
||||||
|
|
||||||
width: 55px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||||
|
|
||||||
|
|||||||
11
frontend/src/Activity/Queue/QueueRow.css.d.ts
vendored
@@ -1,11 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'actions': string;
|
|
||||||
'customFormatScore': string;
|
|
||||||
'progress': string;
|
|
||||||
'protocol': string;
|
|
||||||
'quality': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -8,15 +8,13 @@ import ProgressBar from 'Components/ProgressBar';
|
|||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
|
||||||
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
|
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
|
||||||
import MovieFormats from 'Movie/MovieFormats';
|
import MovieFormats from 'Movie/MovieFormats';
|
||||||
import MovieLanguage from 'Movie/MovieLanguage';
|
import MovieLanguage from 'Movie/MovieLanguage';
|
||||||
import MovieQuality from 'Movie/MovieQuality';
|
import MovieQuality from 'Movie/MovieQuality';
|
||||||
import MovieTitleLink from 'Movie/MovieTitleLink';
|
import MovieTitleLink from 'Movie/MovieTitleLink';
|
||||||
import formatBytes from 'Utilities/Number/formatBytes';
|
import formatBytes from 'Utilities/Number/formatBytes';
|
||||||
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
|
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import QueueStatusCell from './QueueStatusCell';
|
import QueueStatusCell from './QueueStatusCell';
|
||||||
import RemoveQueueItemModal from './RemoveQueueItemModal';
|
import RemoveQueueItemModal from './RemoveQueueItemModal';
|
||||||
@@ -44,14 +42,14 @@ class QueueRow extends Component {
|
|||||||
this.setState({ isRemoveQueueItemModalOpen: true });
|
this.setState({ isRemoveQueueItemModalOpen: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
onRemoveQueueItemModalConfirmed = (blocklist, skipRedownload) => {
|
onRemoveQueueItemModalConfirmed = (blocklist) => {
|
||||||
const {
|
const {
|
||||||
onRemoveQueueItemPress,
|
onRemoveQueueItemPress,
|
||||||
onQueueRowModalOpenOrClose
|
onQueueRowModalOpenOrClose
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
onQueueRowModalOpenOrClose(false);
|
onQueueRowModalOpenOrClose(false);
|
||||||
onRemoveQueueItemPress(blocklist, skipRedownload);
|
onRemoveQueueItemPress(blocklist);
|
||||||
|
|
||||||
this.setState({ isRemoveQueueItemModalOpen: false });
|
this.setState({ isRemoveQueueItemModalOpen: false });
|
||||||
};
|
};
|
||||||
@@ -90,7 +88,6 @@ class QueueRow extends Component {
|
|||||||
movie,
|
movie,
|
||||||
quality,
|
quality,
|
||||||
customFormats,
|
customFormats,
|
||||||
customFormatScore,
|
|
||||||
languages,
|
languages,
|
||||||
protocol,
|
protocol,
|
||||||
indexer,
|
indexer,
|
||||||
@@ -204,24 +201,6 @@ class QueueRow extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'customFormatScore') {
|
|
||||||
return (
|
|
||||||
<TableRowCell
|
|
||||||
key={name}
|
|
||||||
className={styles.customFormatScore}
|
|
||||||
>
|
|
||||||
<Tooltip
|
|
||||||
anchor={formatCustomFormatScore(
|
|
||||||
customFormatScore,
|
|
||||||
customFormats.length
|
|
||||||
)}
|
|
||||||
tooltip={<MovieFormats formats={customFormats} />}
|
|
||||||
position={tooltipPositions.BOTTOM}
|
|
||||||
/>
|
|
||||||
</TableRowCell>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name === 'protocol') {
|
if (name === 'protocol') {
|
||||||
return (
|
return (
|
||||||
<TableRowCell key={name}>
|
<TableRowCell key={name}>
|
||||||
@@ -386,7 +365,6 @@ QueueRow.propTypes = {
|
|||||||
movie: PropTypes.object,
|
movie: PropTypes.object,
|
||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
customFormats: PropTypes.arrayOf(PropTypes.object),
|
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||||
customFormatScore: PropTypes.number.isRequired,
|
|
||||||
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
languages: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
protocol: PropTypes.string.isRequired,
|
protocol: PropTypes.string.isRequired,
|
||||||
indexer: PropTypes.string,
|
indexer: PropTypes.string,
|
||||||
@@ -412,7 +390,6 @@ QueueRow.propTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
QueueRow.defaultProps = {
|
QueueRow.defaultProps = {
|
||||||
customFormats: [],
|
|
||||||
isGrabbing: false,
|
isGrabbing: false,
|
||||||
isRemoving: false
|
isRemoving: false
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
.noMessages {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'noMessages': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import Icon from 'Components/Icon';
|
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
|
||||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
import styles from './QueueStatus.css';
|
|
||||||
|
|
||||||
function getDetailedPopoverBody(statusMessages) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
statusMessages.map(({ title, messages }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={title}
|
|
||||||
className={messages.length ? undefined: styles.noMessages}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
<ul>
|
|
||||||
{
|
|
||||||
messages.map((message) => {
|
|
||||||
return (
|
|
||||||
<li key={message}>
|
|
||||||
{message}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function QueueStatus(props) {
|
|
||||||
const {
|
|
||||||
sourceTitle,
|
|
||||||
status,
|
|
||||||
trackedDownloadStatus,
|
|
||||||
trackedDownloadState,
|
|
||||||
statusMessages,
|
|
||||||
errorMessage,
|
|
||||||
position,
|
|
||||||
canFlip
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const hasWarning = trackedDownloadStatus === 'warning';
|
|
||||||
const hasError = trackedDownloadStatus === 'error';
|
|
||||||
|
|
||||||
// status === 'downloading'
|
|
||||||
let iconName = icons.DOWNLOADING;
|
|
||||||
let iconKind = kinds.DEFAULT;
|
|
||||||
let title = translate('Downloading');
|
|
||||||
|
|
||||||
if (status === 'paused') {
|
|
||||||
iconName = icons.PAUSED;
|
|
||||||
title = translate('Paused');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'queued') {
|
|
||||||
iconName = icons.QUEUED;
|
|
||||||
title = translate('Queued');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'completed') {
|
|
||||||
iconName = icons.DOWNLOADED;
|
|
||||||
title = translate('Downloaded');
|
|
||||||
|
|
||||||
if (trackedDownloadState === 'importPending') {
|
|
||||||
title += ` - ${translate('WaitingToImport')}`;
|
|
||||||
iconKind = kinds.PURPLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackedDownloadState === 'importing') {
|
|
||||||
title += ` - ${translate('Importing')}`;
|
|
||||||
iconKind = kinds.PURPLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackedDownloadState === 'failedPending') {
|
|
||||||
title += ` - ${translate('WaitingToProcess')}`;
|
|
||||||
iconKind = kinds.DANGER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasWarning) {
|
|
||||||
iconKind = kinds.WARNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'delay') {
|
|
||||||
iconName = icons.PENDING;
|
|
||||||
title = translate('Pending');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'downloadClientUnavailable') {
|
|
||||||
iconName = icons.PENDING;
|
|
||||||
iconKind = kinds.WARNING;
|
|
||||||
title = translate('PendingDownloadClientUnavailable');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'failed') {
|
|
||||||
iconName = icons.DOWNLOADING;
|
|
||||||
iconKind = kinds.DANGER;
|
|
||||||
title = translate('DownloadFailed');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'warning') {
|
|
||||||
iconName = icons.DOWNLOADING;
|
|
||||||
iconKind = kinds.WARNING;
|
|
||||||
const warningMessage = errorMessage || translate('CheckDownloadClientForDetails');
|
|
||||||
title = translate('DownloadWarning', { warningMessage });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasError) {
|
|
||||||
if (status === 'completed') {
|
|
||||||
iconName = icons.DOWNLOAD;
|
|
||||||
iconKind = kinds.DANGER;
|
|
||||||
title = translate('ImportFailed', { sourceTitle });
|
|
||||||
} else {
|
|
||||||
iconName = icons.DOWNLOADING;
|
|
||||||
iconKind = kinds.DANGER;
|
|
||||||
title = translate('DownloadFailed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Popover
|
|
||||||
anchor={
|
|
||||||
<Icon
|
|
||||||
name={iconName}
|
|
||||||
kind={iconKind}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
title={title}
|
|
||||||
body={hasWarning || hasError ? getDetailedPopoverBody(statusMessages) : sourceTitle}
|
|
||||||
position={position}
|
|
||||||
canFlip={canFlip}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
QueueStatus.propTypes = {
|
|
||||||
sourceTitle: PropTypes.string.isRequired,
|
|
||||||
status: PropTypes.string.isRequired,
|
|
||||||
trackedDownloadStatus: PropTypes.string.isRequired,
|
|
||||||
trackedDownloadState: PropTypes.string.isRequired,
|
|
||||||
statusMessages: PropTypes.arrayOf(PropTypes.object),
|
|
||||||
errorMessage: PropTypes.string,
|
|
||||||
position: PropTypes.oneOf(tooltipPositions.all).isRequired,
|
|
||||||
canFlip: PropTypes.bool.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
QueueStatus.defaultProps = {
|
|
||||||
trackedDownloadStatus: 'ok',
|
|
||||||
trackedDownloadState: 'downloading',
|
|
||||||
canFlip: false
|
|
||||||
};
|
|
||||||
|
|
||||||
export default QueueStatus;
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'status': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -1,11 +1,39 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Icon from 'Components/Icon';
|
||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import { tooltipPositions } from 'Helpers/Props';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
|
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import QueueStatus from './QueueStatus';
|
|
||||||
import styles from './QueueStatusCell.css';
|
import styles from './QueueStatusCell.css';
|
||||||
|
|
||||||
|
function getDetailedPopoverBody(statusMessages) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
statusMessages.map(({ title, messages }) => {
|
||||||
|
return (
|
||||||
|
<div key={title}>
|
||||||
|
{title}
|
||||||
|
<ul>
|
||||||
|
{
|
||||||
|
messages.map((message) => {
|
||||||
|
return (
|
||||||
|
<li key={message}>
|
||||||
|
{message}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function QueueStatusCell(props) {
|
function QueueStatusCell(props) {
|
||||||
const {
|
const {
|
||||||
sourceTitle,
|
sourceTitle,
|
||||||
@@ -16,16 +44,97 @@ function QueueStatusCell(props) {
|
|||||||
errorMessage
|
errorMessage
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const hasWarning = trackedDownloadStatus === 'warning';
|
||||||
|
const hasError = trackedDownloadStatus === 'error';
|
||||||
|
|
||||||
|
// status === 'downloading'
|
||||||
|
let iconName = icons.DOWNLOADING;
|
||||||
|
let iconKind = kinds.DEFAULT;
|
||||||
|
let title = translate('Downloading');
|
||||||
|
|
||||||
|
if (status === 'paused') {
|
||||||
|
iconName = icons.PAUSED;
|
||||||
|
title = translate('Paused');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'queued') {
|
||||||
|
iconName = icons.QUEUED;
|
||||||
|
title = translate('Queued');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'completed') {
|
||||||
|
iconName = icons.DOWNLOADED;
|
||||||
|
title = translate('Downloaded');
|
||||||
|
|
||||||
|
if (trackedDownloadState === 'importPending') {
|
||||||
|
title += ` - ${translate('WaitingToImport')}`;
|
||||||
|
iconKind = kinds.PURPLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackedDownloadState === 'importing') {
|
||||||
|
title += ` - ${translate('Importing')}`;
|
||||||
|
iconKind = kinds.PURPLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackedDownloadState === 'failedPending') {
|
||||||
|
title += ` - ${translate('WaitingToProcess')}`;
|
||||||
|
iconKind = kinds.DANGER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasWarning) {
|
||||||
|
iconKind = kinds.WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'delay') {
|
||||||
|
iconName = icons.PENDING;
|
||||||
|
title = translate('Pending');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'DownloadClientUnavailable') {
|
||||||
|
iconName = icons.PENDING;
|
||||||
|
iconKind = kinds.WARNING;
|
||||||
|
title = `${translate('Pending')} - ${translate('DownloadClientUnavailable')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'failed') {
|
||||||
|
iconName = icons.DOWNLOADING;
|
||||||
|
iconKind = kinds.DANGER;
|
||||||
|
title = translate('DownloadFailed');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'warning') {
|
||||||
|
iconName = icons.DOWNLOADING;
|
||||||
|
iconKind = kinds.WARNING;
|
||||||
|
const warningMessage = errorMessage || translate('CheckDownloadClientForDetails');
|
||||||
|
title = translate('DownloadWarning', [warningMessage]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasError) {
|
||||||
|
if (status === 'completed') {
|
||||||
|
iconName = icons.DOWNLOAD;
|
||||||
|
iconKind = kinds.DANGER;
|
||||||
|
title = translate('ImportFailed', [sourceTitle]);
|
||||||
|
} else {
|
||||||
|
iconName = icons.DOWNLOADING;
|
||||||
|
iconKind = kinds.DANGER;
|
||||||
|
title = translate('DownloadFailed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRowCell className={styles.status}>
|
<TableRowCell className={styles.status}>
|
||||||
<QueueStatus
|
<Popover
|
||||||
sourceTitle={sourceTitle}
|
anchor={
|
||||||
status={status}
|
<Icon
|
||||||
trackedDownloadStatus={trackedDownloadStatus}
|
name={iconName}
|
||||||
trackedDownloadState={trackedDownloadState}
|
kind={iconKind}
|
||||||
statusMessages={statusMessages}
|
/>
|
||||||
errorMessage={errorMessage}
|
}
|
||||||
|
title={title}
|
||||||
|
body={hasWarning || hasError ? getDetailedPopoverBody(statusMessages) : sourceTitle}
|
||||||
position={tooltipPositions.RIGHT}
|
position={tooltipPositions.RIGHT}
|
||||||
|
canFlip={false}
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ class RemoveQueueItemModal extends Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
remove: true,
|
remove: true,
|
||||||
blocklist: false,
|
blocklist: false
|
||||||
skipRedownload: false
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,8 +32,7 @@ class RemoveQueueItemModal extends Component {
|
|||||||
resetState = function() {
|
resetState = function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
remove: true,
|
remove: true,
|
||||||
blocklist: false,
|
blocklist: false
|
||||||
skipRedownload: false
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,10 +47,6 @@ class RemoveQueueItemModal extends Component {
|
|||||||
this.setState({ blocklist: value });
|
this.setState({ blocklist: value });
|
||||||
};
|
};
|
||||||
|
|
||||||
onSkipRedownloadChange = ({ value }) => {
|
|
||||||
this.setState({ skipRedownload: value });
|
|
||||||
};
|
|
||||||
|
|
||||||
onRemoveConfirmed = () => {
|
onRemoveConfirmed = () => {
|
||||||
const state = this.state;
|
const state = this.state;
|
||||||
|
|
||||||
@@ -76,7 +70,7 @@ class RemoveQueueItemModal extends Component {
|
|||||||
isPending
|
isPending
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const { remove, blocklist, skipRedownload } = this.state;
|
const { remove, blocklist } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
@@ -88,12 +82,12 @@ class RemoveQueueItemModal extends Component {
|
|||||||
onModalClose={this.onModalClose}
|
onModalClose={this.onModalClose}
|
||||||
>
|
>
|
||||||
<ModalHeader>
|
<ModalHeader>
|
||||||
{translate('RemoveQueueItem', { sourceTitle })}
|
{translate('Remove')} - {sourceTitle}
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
|
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<div>
|
<div>
|
||||||
{translate('RemoveQueueItemConfirmation', { sourceTitle })}
|
{translate('RemoveFromQueueText', [sourceTitle])}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -106,7 +100,7 @@ class RemoveQueueItemModal extends Component {
|
|||||||
type={inputTypes.CHECK}
|
type={inputTypes.CHECK}
|
||||||
name="remove"
|
name="remove"
|
||||||
value={remove}
|
value={remove}
|
||||||
helpTextWarning={translate('RemoveFromDownloadClientHelpTextWarning')}
|
helpTextWarning={translate('RemoveHelpTextWarning')}
|
||||||
isDisabled={!canIgnore}
|
isDisabled={!canIgnore}
|
||||||
onChange={this.onRemoveChange}
|
onChange={this.onRemoveChange}
|
||||||
/>
|
/>
|
||||||
@@ -115,30 +109,15 @@ class RemoveQueueItemModal extends Component {
|
|||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>{translate('BlocklistRelease')}</FormLabel>
|
<FormLabel>{translate('BlocklistRelease')}</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.CHECK}
|
type={inputTypes.CHECK}
|
||||||
name="blocklist"
|
name="blocklist"
|
||||||
value={blocklist}
|
value={blocklist}
|
||||||
helpText={translate('BlocklistReleaseHelpText')}
|
helpText={translate('BlocklistHelpText')}
|
||||||
onChange={this.onBlocklistChange}
|
onChange={this.onBlocklistChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
{
|
|
||||||
blocklist ?
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('SkipRedownload')}</FormLabel>
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="skipRedownload"
|
|
||||||
value={skipRedownload}
|
|
||||||
helpText={translate('SkipRedownloadHelpText')}
|
|
||||||
onChange={this.onSkipRedownloadChange}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
@@ -150,7 +129,7 @@ class RemoveQueueItemModal extends Component {
|
|||||||
kind={kinds.DANGER}
|
kind={kinds.DANGER}
|
||||||
onPress={this.onRemoveConfirmed}
|
onPress={this.onRemoveConfirmed}
|
||||||
>
|
>
|
||||||
{translate('Remove')}
|
Remove
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'message': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -23,8 +23,7 @@ class RemoveQueueItemsModal extends Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
remove: true,
|
remove: true,
|
||||||
blocklist: false,
|
blocklist: false
|
||||||
skipRedownload: false
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,8 +33,7 @@ class RemoveQueueItemsModal extends Component {
|
|||||||
resetState = function() {
|
resetState = function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
remove: true,
|
remove: true,
|
||||||
blocklist: false,
|
blocklist: false
|
||||||
skipRedownload: false
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,10 +48,6 @@ class RemoveQueueItemsModal extends Component {
|
|||||||
this.setState({ blocklist: value });
|
this.setState({ blocklist: value });
|
||||||
};
|
};
|
||||||
|
|
||||||
onSkipRedownloadChange = ({ value }) => {
|
|
||||||
this.setState({ skipRedownload: value });
|
|
||||||
};
|
|
||||||
|
|
||||||
onRemoveConfirmed = () => {
|
onRemoveConfirmed = () => {
|
||||||
const state = this.state;
|
const state = this.state;
|
||||||
|
|
||||||
@@ -77,7 +71,7 @@ class RemoveQueueItemsModal extends Component {
|
|||||||
allPending
|
allPending
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const { remove, blocklist, skipRedownload } = this.state;
|
const { remove, blocklist } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
@@ -94,7 +88,7 @@ class RemoveQueueItemsModal extends Component {
|
|||||||
|
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<div className={styles.message}>
|
<div className={styles.message}>
|
||||||
{selectedCount > 1 ? translate('RemoveSelectedItemsQueueMessageText', { selectedCount }) : translate('RemoveSelectedItemQueueMessageText')}
|
{selectedCount > 1 ? translate('AreYouSureYouWantToRemoveSelectedItemsFromQueue', selectedCount) : translate('AreYouSureYouWantToRemoveSelectedItemFromQueue')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -123,25 +117,11 @@ class RemoveQueueItemsModal extends Component {
|
|||||||
type={inputTypes.CHECK}
|
type={inputTypes.CHECK}
|
||||||
name="blocklist"
|
name="blocklist"
|
||||||
value={blocklist}
|
value={blocklist}
|
||||||
helpText={translate('BlocklistReleaseHelpText')}
|
helpText={translate('BlocklistHelpText')}
|
||||||
onChange={this.onBlocklistChange}
|
onChange={this.onBlocklistChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
{
|
|
||||||
blocklist ?
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('SkipRedownload')}</FormLabel>
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.CHECK}
|
|
||||||
name="skipRedownload"
|
|
||||||
value={skipRedownload}
|
|
||||||
helpText={translate('SkipRedownloadHelpText')}
|
|
||||||
onChange={this.onSkipRedownloadChange}
|
|
||||||
/>
|
|
||||||
</FormGroup> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
@@ -153,7 +133,7 @@ class RemoveQueueItemsModal extends Component {
|
|||||||
kind={kinds.DANGER}
|
kind={kinds.DANGER}
|
||||||
onPress={this.onRemoveConfirmed}
|
onPress={this.onRemoveConfirmed}
|
||||||
>
|
>
|
||||||
{translate('Remove')}
|
Remove
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'timeleft': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -27,7 +27,7 @@ function TimeleftCell(props) {
|
|||||||
return (
|
return (
|
||||||
<TableRowCell
|
<TableRowCell
|
||||||
className={styles.timeleft}
|
className={styles.timeleft}
|
||||||
title={translate('DelayingDownloadUntil', { date, time })}
|
title={translate('DelayingDownloadUntilInterp', [date, time])}
|
||||||
>
|
>
|
||||||
-
|
-
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
@@ -41,7 +41,7 @@ function TimeleftCell(props) {
|
|||||||
return (
|
return (
|
||||||
<TableRowCell
|
<TableRowCell
|
||||||
className={styles.timeleft}
|
className={styles.timeleft}
|
||||||
title={translate('RetryingDownloadOn', { date, time })}
|
title={translate('RetryingDownloadInterp', [date, time])}
|
||||||
>
|
>
|
||||||
-
|
-
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'clearLookupButton': string;
|
|
||||||
'helpText': string;
|
|
||||||
'message': string;
|
|
||||||
'noMoviesText': string;
|
|
||||||
'noResults': string;
|
|
||||||
'searchContainer': string;
|
|
||||||
'searchIconContainer': string;
|
|
||||||
'searchInput': string;
|
|
||||||
'searchResults': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -155,7 +155,7 @@ class AddNewMovie extends Component {
|
|||||||
!isFetching && !error && !items.length && !!term &&
|
!isFetching && !error && !items.length && !!term &&
|
||||||
<div className={styles.message}>
|
<div className={styles.message}>
|
||||||
<div className={styles.noResults}>
|
<div className={styles.noResults}>
|
||||||
{translate('CouldNotFindResults', { term })}
|
{translate('CouldNotFindResults', [term])}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{translate('YouCanAlsoSearch')}
|
{translate('YouCanAlsoSearch')}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'addButton': string;
|
|
||||||
'container': string;
|
|
||||||
'info': string;
|
|
||||||
'labelIcon': string;
|
|
||||||
'modalFooter': string;
|
|
||||||
'overview': string;
|
|
||||||
'poster': string;
|
|
||||||
'searchForMissingMovieContainer': string;
|
|
||||||
'searchForMissingMovieInput': string;
|
|
||||||
'searchForMissingMovieLabel': string;
|
|
||||||
'searchForMissingMovieLabelContainer': string;
|
|
||||||
'year': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -20,10 +20,6 @@ class AddNewMovieModalContent extends Component {
|
|||||||
//
|
//
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
onQualityProfileIdChange = ({ value }) => {
|
|
||||||
this.props.onInputChange({ name: 'qualityProfileId', value: parseInt(value) });
|
|
||||||
};
|
|
||||||
|
|
||||||
onAddMoviePress = () => {
|
onAddMoviePress = () => {
|
||||||
this.props.onAddMoviePress();
|
this.props.onAddMoviePress();
|
||||||
};
|
};
|
||||||
@@ -40,7 +36,7 @@ class AddNewMovieModalContent extends Component {
|
|||||||
isAdding,
|
isAdding,
|
||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileIds,
|
||||||
minimumAvailability,
|
minimumAvailability,
|
||||||
searchForMovie,
|
searchForMovie,
|
||||||
folder,
|
folder,
|
||||||
@@ -130,9 +126,9 @@ class AddNewMovieModalContent extends Component {
|
|||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.QUALITY_PROFILE_SELECT}
|
type={inputTypes.QUALITY_PROFILE_SELECT}
|
||||||
name="qualityProfileId"
|
name="qualityProfileIds"
|
||||||
onChange={this.onQualityProfileIdChange}
|
onChange={onInputChange}
|
||||||
{...qualityProfileId}
|
{...qualityProfileIds}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
@@ -189,7 +185,7 @@ AddNewMovieModalContent.propTypes = {
|
|||||||
addError: PropTypes.object,
|
addError: PropTypes.object,
|
||||||
rootFolderPath: PropTypes.object,
|
rootFolderPath: PropTypes.object,
|
||||||
monitor: PropTypes.object.isRequired,
|
monitor: PropTypes.object.isRequired,
|
||||||
qualityProfileId: PropTypes.object,
|
qualityProfileIds: PropTypes.arrayOf(PropTypes.object),
|
||||||
minimumAvailability: PropTypes.object.isRequired,
|
minimumAvailability: PropTypes.object.isRequired,
|
||||||
searchForMovie: PropTypes.object.isRequired,
|
searchForMovie: PropTypes.object.isRequired,
|
||||||
folder: PropTypes.string.isRequired,
|
folder: PropTypes.string.isRequired,
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class AddNewMovieModalContentConnector extends Component {
|
|||||||
tmdbId,
|
tmdbId,
|
||||||
rootFolderPath,
|
rootFolderPath,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileIds,
|
||||||
minimumAvailability,
|
minimumAvailability,
|
||||||
searchForMovie,
|
searchForMovie,
|
||||||
tags
|
tags
|
||||||
@@ -68,7 +68,7 @@ class AddNewMovieModalContentConnector extends Component {
|
|||||||
tmdbId,
|
tmdbId,
|
||||||
rootFolderPath: rootFolderPath.value,
|
rootFolderPath: rootFolderPath.value,
|
||||||
monitor: monitor.value,
|
monitor: monitor.value,
|
||||||
qualityProfileId: qualityProfileId.value,
|
qualityProfileIds: qualityProfileIds.value,
|
||||||
minimumAvailability: minimumAvailability.value,
|
minimumAvailability: minimumAvailability.value,
|
||||||
searchForMovie: searchForMovie.value,
|
searchForMovie: searchForMovie.value,
|
||||||
tags: tags.value
|
tags: tags.value
|
||||||
@@ -93,7 +93,7 @@ AddNewMovieModalContentConnector.propTypes = {
|
|||||||
tmdbId: PropTypes.number.isRequired,
|
tmdbId: PropTypes.number.isRequired,
|
||||||
rootFolderPath: PropTypes.object,
|
rootFolderPath: PropTypes.object,
|
||||||
monitor: PropTypes.object.isRequired,
|
monitor: PropTypes.object.isRequired,
|
||||||
qualityProfileId: PropTypes.object,
|
qualityProfileIds: PropTypes.arrayOf(PropTypes.object),
|
||||||
minimumAvailability: PropTypes.object.isRequired,
|
minimumAvailability: PropTypes.object.isRequired,
|
||||||
searchForMovie: PropTypes.object.isRequired,
|
searchForMovie: PropTypes.object.isRequired,
|
||||||
tags: PropTypes.object.isRequired,
|
tags: PropTypes.object.isRequired,
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'alreadyExistsIcon': string;
|
|
||||||
'certification': string;
|
|
||||||
'content': string;
|
|
||||||
'exclusionIcon': string;
|
|
||||||
'icons': string;
|
|
||||||
'links': string;
|
|
||||||
'overlay': string;
|
|
||||||
'overview': string;
|
|
||||||
'poster': string;
|
|
||||||
'posterContainer': string;
|
|
||||||
'runtime': string;
|
|
||||||
'searchResult': string;
|
|
||||||
'statusContainer': string;
|
|
||||||
'title': string;
|
|
||||||
'titleContainer': string;
|
|
||||||
'titleRow': string;
|
|
||||||
'underlay': string;
|
|
||||||
'year': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -72,15 +72,19 @@ class AddNewMovieSearchResult extends Component {
|
|||||||
colorImpairedMode,
|
colorImpairedMode,
|
||||||
id,
|
id,
|
||||||
monitored,
|
monitored,
|
||||||
hasFile,
|
|
||||||
isAvailable,
|
isAvailable,
|
||||||
queueStatus,
|
queueStatus,
|
||||||
queueState,
|
queueState,
|
||||||
runtime,
|
runtime,
|
||||||
movieRuntimeFormat,
|
movieRuntimeFormat,
|
||||||
certification
|
certification,
|
||||||
|
statistics
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
movieFileCount
|
||||||
|
} = statistics;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isNewAddMovieModalOpen
|
isNewAddMovieModalOpen
|
||||||
} = this.state;
|
} = this.state;
|
||||||
@@ -113,7 +117,6 @@ class AddNewMovieSearchResult extends Component {
|
|||||||
images={images}
|
images={images}
|
||||||
size={250}
|
size={250}
|
||||||
overflow={true}
|
overflow={true}
|
||||||
lazy={false}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -121,9 +124,9 @@ class AddNewMovieSearchResult extends Component {
|
|||||||
isExistingMovie &&
|
isExistingMovie &&
|
||||||
<MovieIndexProgressBar
|
<MovieIndexProgressBar
|
||||||
monitored={monitored}
|
monitored={monitored}
|
||||||
hasFile={hasFile}
|
hasFile={movieFileCount > 0}
|
||||||
status={status}
|
status={status}
|
||||||
width={posterWidth}
|
posterWidth={posterWidth}
|
||||||
detailedProgressBar={true}
|
detailedProgressBar={true}
|
||||||
queueStatus={queueStatus}
|
queueStatus={queueStatus}
|
||||||
queueState={queueState}
|
queueState={queueState}
|
||||||
@@ -234,7 +237,7 @@ class AddNewMovieSearchResult extends Component {
|
|||||||
{
|
{
|
||||||
isExistingMovie && isSmallScreen &&
|
isExistingMovie && isSmallScreen &&
|
||||||
<MovieStatusLabel
|
<MovieStatusLabel
|
||||||
hasMovieFiles={hasFile}
|
hasMovieFiles={movieFileCount > 0}
|
||||||
monitored={monitored}
|
monitored={monitored}
|
||||||
isAvailable={isAvailable}
|
isAvailable={isAvailable}
|
||||||
id={id}
|
id={id}
|
||||||
@@ -291,7 +294,14 @@ AddNewMovieSearchResult.propTypes = {
|
|||||||
queueState: PropTypes.string,
|
queueState: PropTypes.string,
|
||||||
runtime: PropTypes.number.isRequired,
|
runtime: PropTypes.number.isRequired,
|
||||||
movieRuntimeFormat: PropTypes.string.isRequired,
|
movieRuntimeFormat: PropTypes.string.isRequired,
|
||||||
certification: PropTypes.string
|
certification: PropTypes.string,
|
||||||
|
statistics: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
AddNewMovieSearchResult.defaultProps = {
|
||||||
|
statistics: {
|
||||||
|
movieFileCount: 0
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AddNewMovieSearchResult;
|
export default AddNewMovieSearchResult;
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { reduce } from 'lodash';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Alert from 'Components/Alert';
|
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import { kinds } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
|
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||||
import selectAll from 'Utilities/Table/selectAll';
|
import selectAll from 'Utilities/Table/selectAll';
|
||||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||||
import ImportMovieFooterConnector from './ImportMovieFooterConnector';
|
import ImportMovieFooterConnector from './ImportMovieFooterConnector';
|
||||||
@@ -20,8 +18,6 @@ class ImportMovie extends Component {
|
|||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
||||||
this.scrollerRef = React.createRef();
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
allSelected: false,
|
allSelected: false,
|
||||||
allUnselected: false,
|
allUnselected: false,
|
||||||
@@ -31,21 +27,18 @@ class ImportMovie extends Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Control
|
||||||
|
|
||||||
|
setScrollerRef = (ref) => {
|
||||||
|
this.setState({ scroller: ref });
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
getSelectedIds = () => {
|
getSelectedIds = () => {
|
||||||
return reduce(
|
return getSelectedIds(this.state.selectedState, { parseIds: false });
|
||||||
this.state.selectedState,
|
|
||||||
(result, value, id) => {
|
|
||||||
if (value) {
|
|
||||||
result.push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onSelectAllChange = ({ value }) => {
|
onSelectAllChange = ({ value }) => {
|
||||||
@@ -95,21 +88,25 @@ class ImportMovie extends Component {
|
|||||||
const {
|
const {
|
||||||
allSelected,
|
allSelected,
|
||||||
allUnselected,
|
allUnselected,
|
||||||
selectedState
|
selectedState,
|
||||||
|
scroller
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('ImportMovies')}>
|
<PageContent title={translate('ImportMovies')}>
|
||||||
<PageContentBody ref={this.scrollerRef} >
|
<PageContentBody
|
||||||
|
registerScroller={this.setScrollerRef}
|
||||||
|
onScroll={this.onScroll}
|
||||||
|
>
|
||||||
{
|
{
|
||||||
rootFoldersFetching ? <LoadingIndicator /> : null
|
rootFoldersFetching ? <LoadingIndicator /> : null
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!rootFoldersFetching && !!rootFoldersError ?
|
!rootFoldersFetching && !!rootFoldersError ?
|
||||||
<Alert kind={kinds.DANGER}>
|
<div>
|
||||||
{translate('UnableToLoadRootFolders')}
|
{translate('UnableToLoadRootFolders')}
|
||||||
</Alert> :
|
</div> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,9 +115,9 @@ class ImportMovie extends Component {
|
|||||||
!rootFoldersFetching &&
|
!rootFoldersFetching &&
|
||||||
rootFoldersPopulated &&
|
rootFoldersPopulated &&
|
||||||
!unmappedFolders.length ?
|
!unmappedFolders.length ?
|
||||||
<Alert kind={kinds.INFO}>
|
<div>
|
||||||
{translate('AllMoviesInPathHaveBeenImported', { path })}
|
{translate('AllMoviesInPathHaveBeenImported', [path])}
|
||||||
</Alert> :
|
</div> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,14 +126,14 @@ class ImportMovie extends Component {
|
|||||||
!rootFoldersFetching &&
|
!rootFoldersFetching &&
|
||||||
rootFoldersPopulated &&
|
rootFoldersPopulated &&
|
||||||
!!unmappedFolders.length &&
|
!!unmappedFolders.length &&
|
||||||
this.scrollerRef.current ?
|
scroller ?
|
||||||
<ImportMovieTableConnector
|
<ImportMovieTableConnector
|
||||||
rootFolderId={rootFolderId}
|
rootFolderId={rootFolderId}
|
||||||
unmappedFolders={unmappedFolders}
|
unmappedFolders={unmappedFolders}
|
||||||
allSelected={allSelected}
|
allSelected={allSelected}
|
||||||
allUnselected={allUnselected}
|
allUnselected={allUnselected}
|
||||||
selectedState={selectedState}
|
selectedState={selectedState}
|
||||||
scroller={this.scrollerRef.current}
|
scroller={scroller}
|
||||||
onSelectAllChange={this.onSelectAllChange}
|
onSelectAllChange={this.onSelectAllChange}
|
||||||
onSelectedChange={this.onSelectedChange}
|
onSelectedChange={this.onSelectedChange}
|
||||||
onRemoveSelectedStateItem={this.onRemoveSelectedStateItem}
|
onRemoveSelectedStateItem={this.onRemoveSelectedStateItem}
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
.inputContainer {
|
.inputContainer {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
|
|
||||||
div {
|
|
||||||
margin-top: 10px;
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
@@ -43,17 +35,3 @@
|
|||||||
.importError {
|
.importError {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
|
||||||
.inputContainer {
|
|
||||||
margin-top: 10px;
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.importButtonContainer {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'importButton': string;
|
|
||||||
'importButtonContainer': string;
|
|
||||||
'importError': string;
|
|
||||||
'inputContainer': string;
|
|
||||||
'label': string;
|
|
||||||
'loading': string;
|
|
||||||
'loadingButton': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -25,13 +25,13 @@ class ImportMovieFooter extends Component {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileIds,
|
||||||
defaultMinimumAvailability
|
defaultMinimumAvailability
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId,
|
qualityProfileIds: defaultQualityProfileIds,
|
||||||
minimumAvailability: defaultMinimumAvailability
|
minimumAvailability: defaultMinimumAvailability
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -39,16 +39,16 @@ class ImportMovieFooter extends Component {
|
|||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
const {
|
const {
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileIds,
|
||||||
defaultMinimumAvailability,
|
defaultMinimumAvailability,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed,
|
isQualityProfileIdsMixed,
|
||||||
isMinimumAvailabilityMixed
|
isMinimumAvailabilityMixed
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileIds,
|
||||||
minimumAvailability
|
minimumAvailability
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
@@ -60,10 +60,10 @@ class ImportMovieFooter extends Component {
|
|||||||
newState.monitor = defaultMonitor;
|
newState.monitor = defaultMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isQualityProfileIdMixed && qualityProfileId !== MIXED) {
|
if (isQualityProfileIdsMixed && qualityProfileIds !== MIXED) {
|
||||||
newState.qualityProfileId = MIXED;
|
newState.qualityProfileIds = MIXED;
|
||||||
} else if (!isQualityProfileIdMixed && qualityProfileId !== defaultQualityProfileId) {
|
} else if (!isQualityProfileIdsMixed && qualityProfileIds !== defaultQualityProfileIds) {
|
||||||
newState.qualityProfileId = defaultQualityProfileId;
|
newState.qualityProfileIds = defaultQualityProfileIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMinimumAvailabilityMixed && minimumAvailability !== MIXED) {
|
if (isMinimumAvailabilityMixed && minimumAvailability !== MIXED) {
|
||||||
@@ -94,7 +94,7 @@ class ImportMovieFooter extends Component {
|
|||||||
isImporting,
|
isImporting,
|
||||||
isLookingUpMovie,
|
isLookingUpMovie,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed,
|
isQualityProfileIdsMixed,
|
||||||
isMinimumAvailabilityMixed,
|
isMinimumAvailabilityMixed,
|
||||||
hasUnsearchedItems,
|
hasUnsearchedItems,
|
||||||
importError,
|
importError,
|
||||||
@@ -105,7 +105,7 @@ class ImportMovieFooter extends Component {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileIds,
|
||||||
minimumAvailability
|
minimumAvailability
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
@@ -148,10 +148,10 @@ class ImportMovieFooter extends Component {
|
|||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.QUALITY_PROFILE_SELECT}
|
type={inputTypes.QUALITY_PROFILE_SELECT}
|
||||||
name="qualityProfileId"
|
name="qualityProfileIds"
|
||||||
value={qualityProfileId}
|
value={qualityProfileIds}
|
||||||
isDisabled={!selectedCount}
|
isDisabled={!selectedCount}
|
||||||
includeMixed={isQualityProfileIdMixed}
|
includeMixed={isQualityProfileIdsMixed}
|
||||||
onChange={this.onInputChange}
|
onChange={this.onInputChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -257,10 +257,10 @@ ImportMovieFooter.propTypes = {
|
|||||||
isImporting: PropTypes.bool.isRequired,
|
isImporting: PropTypes.bool.isRequired,
|
||||||
isLookingUpMovie: PropTypes.bool.isRequired,
|
isLookingUpMovie: PropTypes.bool.isRequired,
|
||||||
defaultMonitor: PropTypes.string.isRequired,
|
defaultMonitor: PropTypes.string.isRequired,
|
||||||
defaultQualityProfileId: PropTypes.number,
|
defaultQualityProfileIds: PropTypes.arrayOf(PropTypes.number),
|
||||||
defaultMinimumAvailability: PropTypes.string,
|
defaultMinimumAvailability: PropTypes.string,
|
||||||
isMonitorMixed: PropTypes.bool.isRequired,
|
isMonitorMixed: PropTypes.bool.isRequired,
|
||||||
isQualityProfileIdMixed: PropTypes.bool.isRequired,
|
isQualityProfileIdsMixed: PropTypes.bool.isRequired,
|
||||||
isMinimumAvailabilityMixed: PropTypes.bool.isRequired,
|
isMinimumAvailabilityMixed: PropTypes.bool.isRequired,
|
||||||
hasUnsearchedItems: PropTypes.bool.isRequired,
|
hasUnsearchedItems: PropTypes.bool.isRequired,
|
||||||
importError: PropTypes.object,
|
importError: PropTypes.object,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ function createMapStateToProps() {
|
|||||||
(addMovie, importMovie, selectedIds) => {
|
(addMovie, importMovie, selectedIds) => {
|
||||||
const {
|
const {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId,
|
qualityProfileIds: defaultQualityProfileIds,
|
||||||
minimumAvailability: defaultMinimumAvailability
|
minimumAvailability: defaultMinimumAvailability
|
||||||
} = addMovie.defaults;
|
} = addMovie.defaults;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ function createMapStateToProps() {
|
|||||||
} = importMovie;
|
} = importMovie;
|
||||||
|
|
||||||
const isMonitorMixed = isMixed(items, selectedIds, defaultMonitor, 'monitor');
|
const isMonitorMixed = isMixed(items, selectedIds, defaultMonitor, 'monitor');
|
||||||
const isQualityProfileIdMixed = isMixed(items, selectedIds, defaultQualityProfileId, 'qualityProfileId');
|
const isQualityProfileIdsMixed = isMixed(items, selectedIds, defaultQualityProfileIds, 'qualityProfileIds');
|
||||||
const isMinimumAvailabilityMixed = isMixed(items, selectedIds, defaultMinimumAvailability, 'minimumAvailability');
|
const isMinimumAvailabilityMixed = isMixed(items, selectedIds, defaultMinimumAvailability, 'minimumAvailability');
|
||||||
const hasUnsearchedItems = !isLookingUpMovie && items.some((item) => !item.isPopulated);
|
const hasUnsearchedItems = !isLookingUpMovie && items.some((item) => !item.isPopulated);
|
||||||
|
|
||||||
@@ -39,10 +39,10 @@ function createMapStateToProps() {
|
|||||||
isLookingUpMovie,
|
isLookingUpMovie,
|
||||||
isImporting,
|
isImporting,
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileIds,
|
||||||
defaultMinimumAvailability,
|
defaultMinimumAvailability,
|
||||||
isMonitorMixed,
|
isMonitorMixed,
|
||||||
isQualityProfileIdMixed,
|
isQualityProfileIdsMixed,
|
||||||
isMinimumAvailabilityMixed,
|
isMinimumAvailabilityMixed,
|
||||||
importError,
|
importError,
|
||||||
hasUnsearchedItems
|
hasUnsearchedItems
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'detailsIcon': string;
|
|
||||||
'folder': string;
|
|
||||||
'minimumAvailability': string;
|
|
||||||
'monitor': string;
|
|
||||||
'movie': string;
|
|
||||||
'qualityProfile': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'folder': string;
|
|
||||||
'minimumAvailability': string;
|
|
||||||
'monitor': string;
|
|
||||||
'movie': string;
|
|
||||||
'qualityProfile': string;
|
|
||||||
'selectInput': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -11,7 +11,7 @@ function ImportMovieRow(props) {
|
|||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
monitor,
|
monitor,
|
||||||
qualityProfileId,
|
qualityProfileIds,
|
||||||
minimumAvailability,
|
minimumAvailability,
|
||||||
selectedMovie,
|
selectedMovie,
|
||||||
isExistingMovie,
|
isExistingMovie,
|
||||||
@@ -62,8 +62,8 @@ function ImportMovieRow(props) {
|
|||||||
<VirtualTableRowCell className={styles.qualityProfile}>
|
<VirtualTableRowCell className={styles.qualityProfile}>
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.QUALITY_PROFILE_SELECT}
|
type={inputTypes.QUALITY_PROFILE_SELECT}
|
||||||
name="qualityProfileId"
|
name="qualityProfileIds"
|
||||||
value={qualityProfileId}
|
value={qualityProfileIds}
|
||||||
onChange={onInputChange}
|
onChange={onInputChange}
|
||||||
/>
|
/>
|
||||||
</VirtualTableRowCell>
|
</VirtualTableRowCell>
|
||||||
@@ -74,7 +74,7 @@ function ImportMovieRow(props) {
|
|||||||
ImportMovieRow.propTypes = {
|
ImportMovieRow.propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
monitor: PropTypes.string.isRequired,
|
monitor: PropTypes.string.isRequired,
|
||||||
qualityProfileId: PropTypes.number.isRequired,
|
qualityProfileIds: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||||
minimumAvailability: PropTypes.string.isRequired,
|
minimumAvailability: PropTypes.string.isRequired,
|
||||||
selectedMovie: PropTypes.object,
|
selectedMovie: PropTypes.object,
|
||||||
isExistingMovie: PropTypes.bool.isRequired,
|
isExistingMovie: PropTypes.bool.isRequired,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class ImportMovieTable extends Component {
|
|||||||
const {
|
const {
|
||||||
unmappedFolders,
|
unmappedFolders,
|
||||||
defaultMonitor,
|
defaultMonitor,
|
||||||
defaultQualityProfileId,
|
defaultQualityProfileIds,
|
||||||
defaultMinimumAvailability,
|
defaultMinimumAvailability,
|
||||||
onMovieLookup,
|
onMovieLookup,
|
||||||
onSetImportMovieValue
|
onSetImportMovieValue
|
||||||
@@ -23,7 +23,7 @@ class ImportMovieTable extends Component {
|
|||||||
|
|
||||||
const values = {
|
const values = {
|
||||||
monitor: defaultMonitor,
|
monitor: defaultMonitor,
|
||||||
qualityProfileId: defaultQualityProfileId,
|
qualityProfileIds: defaultQualityProfileIds,
|
||||||
minimumAvailability: defaultMinimumAvailability
|
minimumAvailability: defaultMinimumAvailability
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ ImportMovieTable.propTypes = {
|
|||||||
items: PropTypes.arrayOf(PropTypes.object),
|
items: PropTypes.arrayOf(PropTypes.object),
|
||||||
unmappedFolders: PropTypes.arrayOf(PropTypes.object),
|
unmappedFolders: PropTypes.arrayOf(PropTypes.object),
|
||||||
defaultMonitor: PropTypes.string.isRequired,
|
defaultMonitor: PropTypes.string.isRequired,
|
||||||
defaultQualityProfileId: PropTypes.number,
|
defaultQualityProfileIds: PropTypes.arrayOf(PropTypes.number),
|
||||||
defaultMinimumAvailability: PropTypes.string,
|
defaultMinimumAvailability: PropTypes.string,
|
||||||
allSelected: PropTypes.bool.isRequired,
|
allSelected: PropTypes.bool.isRequired,
|
||||||
allUnselected: PropTypes.bool.isRequired,
|
allUnselected: PropTypes.bool.isRequired,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ function createMapStateToProps() {
|
|||||||
(addMovie, importMovie, dimensions, allMovies) => {
|
(addMovie, importMovie, dimensions, allMovies) => {
|
||||||
return {
|
return {
|
||||||
defaultMonitor: addMovie.defaults.monitor,
|
defaultMonitor: addMovie.defaults.monitor,
|
||||||
defaultQualityProfileId: addMovie.defaults.qualityProfileId,
|
defaultQualityProfileIds: addMovie.defaults.qualityProfileIds,
|
||||||
defaultMinimumAvailability: addMovie.defaults.minimumAvailability,
|
defaultMinimumAvailability: addMovie.defaults.minimumAvailability,
|
||||||
items: importMovie.items,
|
items: importMovie.items,
|
||||||
isSmallScreen: dimensions.isSmallScreen,
|
isSmallScreen: dimensions.isSmallScreen,
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'container': string;
|
|
||||||
'movie': string;
|
|
||||||
'tmdbLink': string;
|
|
||||||
'tmdbLinkIcon': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'button': string;
|
|
||||||
'content': string;
|
|
||||||
'contentContainer': string;
|
|
||||||
'dropdownArrowContainer': string;
|
|
||||||
'existing': string;
|
|
||||||
'loading': string;
|
|
||||||
'searchContainer': string;
|
|
||||||
'searchIconContainer': string;
|
|
||||||
'searchInput': string;
|
|
||||||
'warningIcon': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -5,6 +5,7 @@ import FormInputButton from 'Components/Form/FormInputButton';
|
|||||||
import TextInput from 'Components/Form/TextInput';
|
import TextInput from 'Components/Form/TextInput';
|
||||||
import Icon from 'Components/Icon';
|
import Icon from 'Components/Icon';
|
||||||
import Link from 'Components/Link/Link';
|
import Link from 'Components/Link/Link';
|
||||||
|
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
import Portal from 'Components/Portal';
|
import Portal from 'Components/Portal';
|
||||||
import { icons, kinds } from 'Helpers/Props';
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
@@ -242,7 +243,7 @@ class ImportMovieSelectMovie extends Component {
|
|||||||
<FormInputButton
|
<FormInputButton
|
||||||
kind={kinds.DEFAULT}
|
kind={kinds.DEFAULT}
|
||||||
spinnerIcon={icons.REFRESH}
|
spinnerIcon={icons.REFRESH}
|
||||||
canSpin={true}
|
ButtonComponent={SpinnerButton}
|
||||||
isSpinning={isFetching}
|
isSpinning={isFetching}
|
||||||
onPress={this.onRefreshPress}
|
onPress={this.onRefreshPress}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'existing': string;
|
|
||||||
'title': string;
|
|
||||||
'titleContainer': string;
|
|
||||||
'year': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'actions': string;
|
|
||||||
'freeSpace': string;
|
|
||||||
'link': string;
|
|
||||||
'unmappedFolders': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
// This file is automatically generated.
|
|
||||||
// Please do not change this file!
|
|
||||||
interface CssExports {
|
|
||||||
'addErrorAlert': string;
|
|
||||||
'code': string;
|
|
||||||
'header': string;
|
|
||||||
'importButtonIcon': string;
|
|
||||||
'recentFolders': string;
|
|
||||||
'startImport': string;
|
|
||||||
'tip': string;
|
|
||||||
'tips': string;
|
|
||||||
}
|
|
||||||
export const cssExports: CssExports;
|
|
||||||
export default cssExports;
|
|
||||||
@@ -18,17 +18,17 @@ import styles from './ImportMovieSelectFolder.css';
|
|||||||
const rootFolderColumns = [
|
const rootFolderColumns = [
|
||||||
{
|
{
|
||||||
name: 'path',
|
name: 'path',
|
||||||
label: () => translate('Path'),
|
label: translate('Path'),
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'freeSpace',
|
name: 'freeSpace',
|
||||||
label: () => translate('FreeSpace'),
|
label: translate('FreeSpace'),
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'unmappedFolders',
|
name: 'unmappedFolders',
|
||||||
label: () => translate('UnmappedFolders'),
|
label: translate('UnmappedFolders'),
|
||||||
isVisible: true
|
isVisible: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -92,9 +92,9 @@ class ImportMovieSelectFolder extends Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
!isFetching && error ?
|
!isFetching && error ?
|
||||||
<Alert kind={kinds.DANGER}>
|
<div>
|
||||||
{translate('UnableToLoadRootFolders')}
|
{translate('UnableToLoadRootFolders')}
|
||||||
</Alert> :
|
</div> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import NotFound from 'Components/NotFound';
|
|||||||
import Switch from 'Components/Router/Switch';
|
import Switch from 'Components/Router/Switch';
|
||||||
import DiscoverMovieConnector from 'DiscoverMovie/DiscoverMovieConnector';
|
import DiscoverMovieConnector from 'DiscoverMovie/DiscoverMovieConnector';
|
||||||
import MovieDetailsPageConnector from 'Movie/Details/MovieDetailsPageConnector';
|
import MovieDetailsPageConnector from 'Movie/Details/MovieDetailsPageConnector';
|
||||||
import MovieIndex from 'Movie/Index/MovieIndex';
|
import MovieIndexConnector from 'Movie/Index/MovieIndexConnector';
|
||||||
import CustomFormatSettingsPage from 'Settings/CustomFormats/CustomFormatSettingsPage';
|
import CustomFormatSettingsConnector from 'Settings/CustomFormats/CustomFormatSettingsConnector';
|
||||||
import DownloadClientSettingsConnector from 'Settings/DownloadClients/DownloadClientSettingsConnector';
|
import DownloadClientSettingsConnector from 'Settings/DownloadClients/DownloadClientSettingsConnector';
|
||||||
import GeneralSettingsConnector from 'Settings/General/GeneralSettingsConnector';
|
import GeneralSettingsConnector from 'Settings/General/GeneralSettingsConnector';
|
||||||
import ImportListSettingsConnector from 'Settings/ImportLists/ImportListSettingsConnector';
|
import ImportListSettingsConnector from 'Settings/ImportLists/ImportListSettingsConnector';
|
||||||
@@ -48,7 +48,7 @@ function AppRoutes(props) {
|
|||||||
<Route
|
<Route
|
||||||
exact={true}
|
exact={true}
|
||||||
path="/"
|
path="/"
|
||||||
component={MovieIndex}
|
component={MovieIndexConnector}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -148,7 +148,7 @@ function AppRoutes(props) {
|
|||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="/settings/customformats"
|
path="/settings/customformats"
|
||||||
component={CustomFormatSettingsPage}
|
component={CustomFormatSettingsConnector}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
|
|||||||