mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-05 20:51:13 -07:00
feat: added the watchlist notification
This commit is contained in:
commit
ea0b690c18
20 changed files with 1210 additions and 2545 deletions
2309
src/.idea/.idea.Ombi/.idea/contentModel.xml
generated
2309
src/.idea/.idea.Ombi/.idea/contentModel.xml
generated
File diff suppressed because it is too large
Load diff
440
src/.idea/.idea.Ombi/.idea/dbnavigator.xml
generated
Normal file
440
src/.idea/.idea.Ombi/.idea/dbnavigator.xml
generated
Normal file
|
@ -0,0 +1,440 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DBNavigator.Project.DDLFileAttachmentManager">
|
||||||
|
<mappings />
|
||||||
|
<preferences />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatabaseAssistantManager">
|
||||||
|
<assistants />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatabaseBrowserManager">
|
||||||
|
<autoscroll-to-editor value="false" />
|
||||||
|
<autoscroll-from-editor value="true" />
|
||||||
|
<show-object-properties value="true" />
|
||||||
|
<loaded-nodes />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatabaseFileManager">
|
||||||
|
<open-files />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.ExecutionManager">
|
||||||
|
<retain-sticky-names value="false" />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.ParserDiagnosticsManager">
|
||||||
|
<diagnostics-history />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.Settings">
|
||||||
|
<connections />
|
||||||
|
<browser-settings>
|
||||||
|
<general>
|
||||||
|
<display-mode value="TABBED" />
|
||||||
|
<navigation-history-size value="100" />
|
||||||
|
<show-object-details value="false" />
|
||||||
|
<enable-sticky-paths value="true" />
|
||||||
|
</general>
|
||||||
|
<filters>
|
||||||
|
<object-type-filter>
|
||||||
|
<object-type name="SCHEMA" enabled="true" />
|
||||||
|
<object-type name="USER" enabled="true" />
|
||||||
|
<object-type name="ROLE" enabled="true" />
|
||||||
|
<object-type name="PRIVILEGE" enabled="true" />
|
||||||
|
<object-type name="CHARSET" enabled="true" />
|
||||||
|
<object-type name="TABLE" enabled="true" />
|
||||||
|
<object-type name="VIEW" enabled="true" />
|
||||||
|
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||||
|
<object-type name="NESTED_TABLE" enabled="true" />
|
||||||
|
<object-type name="COLUMN" enabled="true" />
|
||||||
|
<object-type name="INDEX" enabled="true" />
|
||||||
|
<object-type name="CONSTRAINT" enabled="true" />
|
||||||
|
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||||
|
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||||
|
<object-type name="SYNONYM" enabled="true" />
|
||||||
|
<object-type name="SEQUENCE" enabled="true" />
|
||||||
|
<object-type name="PROCEDURE" enabled="true" />
|
||||||
|
<object-type name="FUNCTION" enabled="true" />
|
||||||
|
<object-type name="PACKAGE" enabled="true" />
|
||||||
|
<object-type name="TYPE" enabled="true" />
|
||||||
|
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||||
|
<object-type name="ARGUMENT" enabled="true" />
|
||||||
|
<object-type name="JAVA_CLASS" enabled="true" />
|
||||||
|
<object-type name="JAVA_INNER_CLASS" enabled="true" />
|
||||||
|
<object-type name="JAVA_FIELD" enabled="true" />
|
||||||
|
<object-type name="JAVA_METHOD" enabled="true" />
|
||||||
|
<object-type name="DIMENSION" enabled="true" />
|
||||||
|
<object-type name="CLUSTER" enabled="true" />
|
||||||
|
<object-type name="DBLINK" enabled="true" />
|
||||||
|
<object-type name="CREDENTIAL" enabled="true" />
|
||||||
|
<object-type name="AI_PROFILE" enabled="true" />
|
||||||
|
</object-type-filter>
|
||||||
|
</filters>
|
||||||
|
<sorting>
|
||||||
|
<object-type name="COLUMN" sorting-type="NAME" />
|
||||||
|
<object-type name="FUNCTION" sorting-type="NAME" />
|
||||||
|
<object-type name="PROCEDURE" sorting-type="NAME" />
|
||||||
|
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
||||||
|
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
|
||||||
|
</sorting>
|
||||||
|
<default-editors>
|
||||||
|
<object-type name="VIEW" editor-type="SELECTION" />
|
||||||
|
<object-type name="PACKAGE" editor-type="SELECTION" />
|
||||||
|
<object-type name="TYPE" editor-type="SELECTION" />
|
||||||
|
</default-editors>
|
||||||
|
</browser-settings>
|
||||||
|
<navigation-settings>
|
||||||
|
<lookup-filters>
|
||||||
|
<lookup-objects>
|
||||||
|
<object-type name="SCHEMA" enabled="true" />
|
||||||
|
<object-type name="USER" enabled="false" />
|
||||||
|
<object-type name="ROLE" enabled="false" />
|
||||||
|
<object-type name="PRIVILEGE" enabled="false" />
|
||||||
|
<object-type name="CHARSET" enabled="false" />
|
||||||
|
<object-type name="TABLE" enabled="true" />
|
||||||
|
<object-type name="VIEW" enabled="true" />
|
||||||
|
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
||||||
|
<object-type name="INDEX" enabled="true" />
|
||||||
|
<object-type name="CONSTRAINT" enabled="true" />
|
||||||
|
<object-type name="DATASET TRIGGER" enabled="true" />
|
||||||
|
<object-type name="DATABASE TRIGGER" enabled="true" />
|
||||||
|
<object-type name="SYNONYM" enabled="false" />
|
||||||
|
<object-type name="SEQUENCE" enabled="true" />
|
||||||
|
<object-type name="PROCEDURE" enabled="true" />
|
||||||
|
<object-type name="FUNCTION" enabled="true" />
|
||||||
|
<object-type name="PACKAGE" enabled="true" />
|
||||||
|
<object-type name="TYPE" enabled="true" />
|
||||||
|
<object-type name="JAVA CLASS" enabled="true" />
|
||||||
|
<object-type name="INNER CLASS" enabled="true" />
|
||||||
|
<object-type name="JAVA FIELD" enabled="true" />
|
||||||
|
<object-type name="JAVA METHOD" enabled="true" />
|
||||||
|
<object-type name="JAVA PARAMETER" enabled="true" />
|
||||||
|
<object-type name="DIMENSION" enabled="false" />
|
||||||
|
<object-type name="CLUSTER" enabled="false" />
|
||||||
|
<object-type name="DBLINK" enabled="false" />
|
||||||
|
<object-type name="CREDENTIAL" enabled="false" />
|
||||||
|
</lookup-objects>
|
||||||
|
<force-database-load value="false" />
|
||||||
|
<prompt-connection-selection value="true" />
|
||||||
|
<prompt-schema-selection value="true" />
|
||||||
|
</lookup-filters>
|
||||||
|
</navigation-settings>
|
||||||
|
<dataset-grid-settings>
|
||||||
|
<general>
|
||||||
|
<enable-zooming value="true" />
|
||||||
|
<enable-column-tooltip value="true" />
|
||||||
|
</general>
|
||||||
|
<sorting>
|
||||||
|
<nulls-first value="true" />
|
||||||
|
<max-sorting-columns value="4" />
|
||||||
|
</sorting>
|
||||||
|
<audit-columns>
|
||||||
|
<column-names value="" />
|
||||||
|
<visible value="true" />
|
||||||
|
<editable value="false" />
|
||||||
|
</audit-columns>
|
||||||
|
</dataset-grid-settings>
|
||||||
|
<dataset-editor-settings>
|
||||||
|
<text-editor-popup>
|
||||||
|
<active value="false" />
|
||||||
|
<active-if-empty value="false" />
|
||||||
|
<data-length-threshold value="100" />
|
||||||
|
<popup-delay value="1000" />
|
||||||
|
</text-editor-popup>
|
||||||
|
<values-actions-popup>
|
||||||
|
<show-popup-button value="true" />
|
||||||
|
<element-count-threshold value="1000" />
|
||||||
|
<data-length-threshold value="250" />
|
||||||
|
</values-actions-popup>
|
||||||
|
<general>
|
||||||
|
<fetch-block-size value="100" />
|
||||||
|
<fetch-timeout value="30" />
|
||||||
|
<trim-whitespaces value="true" />
|
||||||
|
<convert-empty-strings-to-null value="true" />
|
||||||
|
<select-content-on-cell-edit value="true" />
|
||||||
|
<large-value-preview-active value="true" />
|
||||||
|
</general>
|
||||||
|
<filters>
|
||||||
|
<prompt-filter-dialog value="true" />
|
||||||
|
<default-filter-type value="BASIC" />
|
||||||
|
</filters>
|
||||||
|
<qualified-text-editor text-length-threshold="300">
|
||||||
|
<content-types>
|
||||||
|
<content-type name="Text" enabled="true" />
|
||||||
|
<content-type name="Properties" enabled="true" />
|
||||||
|
<content-type name="XML" enabled="true" />
|
||||||
|
<content-type name="DTD" enabled="true" />
|
||||||
|
<content-type name="HTML" enabled="true" />
|
||||||
|
<content-type name="XHTML" enabled="true" />
|
||||||
|
<content-type name="CSS" enabled="true" />
|
||||||
|
<content-type name="SQL" enabled="true" />
|
||||||
|
<content-type name="PL/SQL" enabled="true" />
|
||||||
|
<content-type name="JavaScript" enabled="true" />
|
||||||
|
<content-type name="JSON" enabled="true" />
|
||||||
|
<content-type name="JSON5" enabled="true" />
|
||||||
|
<content-type name="YAML" enabled="true" />
|
||||||
|
<content-type name="C#" enabled="true" />
|
||||||
|
</content-types>
|
||||||
|
</qualified-text-editor>
|
||||||
|
<record-navigation>
|
||||||
|
<navigation-target value="VIEWER" />
|
||||||
|
</record-navigation>
|
||||||
|
</dataset-editor-settings>
|
||||||
|
<code-editor-settings>
|
||||||
|
<general>
|
||||||
|
<show-object-navigation-gutter value="false" />
|
||||||
|
<show-spec-declaration-navigation-gutter value="true" />
|
||||||
|
<enable-spellchecking value="true" />
|
||||||
|
<enable-reference-spellchecking value="false" />
|
||||||
|
</general>
|
||||||
|
<confirmations>
|
||||||
|
<save-changes value="false" />
|
||||||
|
<revert-changes value="true" />
|
||||||
|
<exit-on-changes value="ASK" />
|
||||||
|
</confirmations>
|
||||||
|
</code-editor-settings>
|
||||||
|
<code-completion-settings>
|
||||||
|
<filters>
|
||||||
|
<basic-filter>
|
||||||
|
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="role" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="user" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||||
|
<user-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</user-schema>
|
||||||
|
<public-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="false" />
|
||||||
|
</public-schema>
|
||||||
|
<any-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</any-schema>
|
||||||
|
</basic-filter>
|
||||||
|
<extended-filter>
|
||||||
|
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="user" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="role" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||||
|
<user-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</user-schema>
|
||||||
|
<public-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</public-schema>
|
||||||
|
<any-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</any-schema>
|
||||||
|
</extended-filter>
|
||||||
|
</filters>
|
||||||
|
<sorting enabled="true">
|
||||||
|
<sorting-element type="RESERVED_WORD" id="keyword" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="datatype" />
|
||||||
|
<sorting-element type="OBJECT" id="column" />
|
||||||
|
<sorting-element type="OBJECT" id="table" />
|
||||||
|
<sorting-element type="OBJECT" id="view" />
|
||||||
|
<sorting-element type="OBJECT" id="materialized view" />
|
||||||
|
<sorting-element type="OBJECT" id="index" />
|
||||||
|
<sorting-element type="OBJECT" id="constraint" />
|
||||||
|
<sorting-element type="OBJECT" id="trigger" />
|
||||||
|
<sorting-element type="OBJECT" id="synonym" />
|
||||||
|
<sorting-element type="OBJECT" id="sequence" />
|
||||||
|
<sorting-element type="OBJECT" id="procedure" />
|
||||||
|
<sorting-element type="OBJECT" id="function" />
|
||||||
|
<sorting-element type="OBJECT" id="package" />
|
||||||
|
<sorting-element type="OBJECT" id="type" />
|
||||||
|
<sorting-element type="OBJECT" id="dimension" />
|
||||||
|
<sorting-element type="OBJECT" id="cluster" />
|
||||||
|
<sorting-element type="OBJECT" id="dblink" />
|
||||||
|
<sorting-element type="OBJECT" id="schema" />
|
||||||
|
<sorting-element type="OBJECT" id="role" />
|
||||||
|
<sorting-element type="OBJECT" id="user" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="function" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="parameter" />
|
||||||
|
</sorting>
|
||||||
|
<format>
|
||||||
|
<enforce-code-style-case value="true" />
|
||||||
|
</format>
|
||||||
|
</code-completion-settings>
|
||||||
|
<execution-engine-settings>
|
||||||
|
<statement-execution>
|
||||||
|
<fetch-block-size value="100" />
|
||||||
|
<execution-timeout value="20" />
|
||||||
|
<debug-execution-timeout value="600" />
|
||||||
|
<focus-result value="false" />
|
||||||
|
<prompt-execution value="false" />
|
||||||
|
</statement-execution>
|
||||||
|
<script-execution>
|
||||||
|
<command-line-interfaces />
|
||||||
|
<execution-timeout value="300" />
|
||||||
|
</script-execution>
|
||||||
|
<method-execution>
|
||||||
|
<execution-timeout value="30" />
|
||||||
|
<debug-execution-timeout value="600" />
|
||||||
|
<parameter-history-size value="10" />
|
||||||
|
</method-execution>
|
||||||
|
</execution-engine-settings>
|
||||||
|
<operation-settings>
|
||||||
|
<transactions>
|
||||||
|
<uncommitted-changes>
|
||||||
|
<on-project-close value="ASK" />
|
||||||
|
<on-disconnect value="ASK" />
|
||||||
|
<on-autocommit-toggle value="ASK" />
|
||||||
|
</uncommitted-changes>
|
||||||
|
<multiple-uncommitted-changes>
|
||||||
|
<on-commit value="ASK" />
|
||||||
|
<on-rollback value="ASK" />
|
||||||
|
</multiple-uncommitted-changes>
|
||||||
|
</transactions>
|
||||||
|
<session-browser>
|
||||||
|
<disconnect-session value="ASK" />
|
||||||
|
<kill-session value="ASK" />
|
||||||
|
<reload-on-filter-change value="false" />
|
||||||
|
</session-browser>
|
||||||
|
<compiler>
|
||||||
|
<compile-type value="KEEP" />
|
||||||
|
<compile-dependencies value="ASK" />
|
||||||
|
<always-show-controls value="false" />
|
||||||
|
</compiler>
|
||||||
|
</operation-settings>
|
||||||
|
<ddl-file-settings>
|
||||||
|
<extensions>
|
||||||
|
<mapping file-type-id="VIEW" extensions="vw" />
|
||||||
|
<mapping file-type-id="TRIGGER" extensions="trg" />
|
||||||
|
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
||||||
|
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
||||||
|
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
||||||
|
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
||||||
|
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
||||||
|
<mapping file-type-id="TYPE" extensions="tpe" />
|
||||||
|
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
||||||
|
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
||||||
|
<mapping file-type-id="JAVA_SOURCE" extensions="sql" />
|
||||||
|
</extensions>
|
||||||
|
<general>
|
||||||
|
<lookup-ddl-files value="true" />
|
||||||
|
<create-ddl-files value="false" />
|
||||||
|
<synchronize-ddl-files value="true" />
|
||||||
|
<use-qualified-names value="false" />
|
||||||
|
<make-scripts-rerunnable value="true" />
|
||||||
|
</general>
|
||||||
|
</ddl-file-settings>
|
||||||
|
<assistant-settings>
|
||||||
|
<credential-settings>
|
||||||
|
<credentials />
|
||||||
|
</credential-settings>
|
||||||
|
</assistant-settings>
|
||||||
|
<general-settings>
|
||||||
|
<regional-settings>
|
||||||
|
<date-format value="MEDIUM" />
|
||||||
|
<number-format value="UNGROUPED" />
|
||||||
|
<locale value="SYSTEM_DEFAULT" />
|
||||||
|
<use-custom-formats value="false" />
|
||||||
|
</regional-settings>
|
||||||
|
<environment>
|
||||||
|
<environment-types>
|
||||||
|
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
||||||
|
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
||||||
|
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
||||||
|
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
||||||
|
</environment-types>
|
||||||
|
<visibility-settings>
|
||||||
|
<connection-tabs value="true" />
|
||||||
|
<dialog-headers value="true" />
|
||||||
|
<object-editor-tabs value="true" />
|
||||||
|
<script-editor-tabs value="false" />
|
||||||
|
<execution-result-tabs value="true" />
|
||||||
|
</visibility-settings>
|
||||||
|
</environment>
|
||||||
|
</general-settings>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
src/.idea/.idea.Ombi/.idea/modules.xml
generated
8
src/.idea/.idea.Ombi/.idea/modules.xml
generated
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/.idea.Ombi/riderModule.iml" filepath="$PROJECT_DIR$/.idea/.idea.Ombi/riderModule.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
7
src/.idea/.idea.Ombi/.idea/projectSettingsUpdater.xml
generated
Normal file
7
src/.idea/.idea.Ombi/.idea/projectSettingsUpdater.xml
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RiderProjectSettingsUpdater">
|
||||||
|
<option name="singleClickDiffPreview" value="1" />
|
||||||
|
<option name="vcsConfiguration" value="3" />
|
||||||
|
</component>
|
||||||
|
</project>
|
106
src/.idea/.idea.Ombi/.idea/workspace.xml
generated
106
src/.idea/.idea.Ombi/.idea/workspace.xml
generated
|
@ -5,9 +5,7 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="57001998-efde-494a-80b3-d7acfc91f770" name="Default Changelist" comment="">
|
<list default="true" id="57001998-efde-494a-80b3-d7acfc91f770" name="Default Changelist" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.Ombi/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Ombi/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Ombi/ClientApp/src/app/settings/plex/plex.component.html" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi/ClientApp/src/app/settings/plex/plex.component.html" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.html" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.html" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Ombi/Controllers/V2/WizardController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Ombi/Controllers/V2/WizardController.cs" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
@ -234,6 +232,12 @@
|
||||||
<component name="Git.Settings">
|
<component name="Git.Settings">
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="GitHubPullRequestSearchHistory">{
|
||||||
|
"lastFilter": {
|
||||||
|
"state": "OPEN",
|
||||||
|
"assignee": "tidusjar"
|
||||||
|
}
|
||||||
|
}</component>
|
||||||
<component name="GitToolBoxStore">
|
<component name="GitToolBoxStore">
|
||||||
<option name="recentBranches">
|
<option name="recentBranches">
|
||||||
<RecentBranches>
|
<RecentBranches>
|
||||||
|
@ -267,6 +271,12 @@
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="GithubPullRequestsUISettings">{
|
||||||
|
"selectedUrlAndAccountId": {
|
||||||
|
"url": "https://github.com/ombi-app/ombi",
|
||||||
|
"accountId": "22dd09fe-fb9e-48a4-bfcc-3c152edf3f25"
|
||||||
|
}
|
||||||
|
}</component>
|
||||||
<component name="HighlightingSettingsPerFile">
|
<component name="HighlightingSettingsPerFile">
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/990126b794024fe2bd16aebdd37eba1d7b600/93/25662f04/ServerVersion.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/990126b794024fe2bd16aebdd37eba1d7b600/93/25662f04/ServerVersion.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/3bd4df5aff92cabbc4d630be64227073db1b8539b3a1e47786b4b189d7cdb7/DbContext.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/3bd4df5aff92cabbc4d630be64227073db1b8539b3a1e47786b4b189d7cdb7/DbContext.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
@ -308,12 +318,17 @@
|
||||||
<component name="PackageJsonUpdateNotifier">
|
<component name="PackageJsonUpdateNotifier">
|
||||||
<dismissed value="$PROJECT_DIR$/Ombi/ClientApp/package.json" />
|
<dismissed value="$PROJECT_DIR$/Ombi/ClientApp/package.json" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="ProjectColorInfo">{
|
||||||
|
"customColor": "",
|
||||||
|
"associatedIndex": 0
|
||||||
|
}</component>
|
||||||
<component name="ProjectFrameBounds" extendedState="6">
|
<component name="ProjectFrameBounds" extendedState="6">
|
||||||
<option name="x" value="1087" />
|
<option name="x" value="1087" />
|
||||||
<option name="y" value="-1113" />
|
<option name="y" value="-1113" />
|
||||||
<option name="width" value="1400" />
|
<option name="width" value="1400" />
|
||||||
<option name="height" value="1000" />
|
<option name="height" value="1000" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="ProjectId" id="2wGwbN5gDqLwyiO1WJdlwJzZ5M9" />
|
||||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
|
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
|
||||||
<ConfirmationsSetting value="2" id="Add" />
|
<ConfirmationsSetting value="2" id="Add" />
|
||||||
</component>
|
</component>
|
||||||
|
@ -376,11 +391,23 @@
|
||||||
<pane id="FileSystemExplorer" />
|
<pane id="FileSystemExplorer" />
|
||||||
</panes>
|
</panes>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="ProjectViewState">
|
||||||
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
|
<option name="showLibraryContents" value="true" />
|
||||||
|
</component>
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
".NET Launch Settings Profile.Ombi.executor": "Run",
|
".NET Launch Settings Profile.Ombi.Schedule.Tests.executor": "Run",
|
||||||
"git-widget-placeholder": "#5208 on wizard-database",
|
".NET Launch Settings Profile.Ombi.executor": "Debug",
|
||||||
"node.js.selected.package.tslint": "(autodetect)"
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
|
"fb34c741-04ca-4b4f-8ea1-651a011b42c8.executor": "Debug",
|
||||||
|
"git-widget-placeholder": "watchlist-expired-notification",
|
||||||
|
"node.js.detected.package.eslint": "true",
|
||||||
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
|
"nodejs_package_manager_path": "yarn",
|
||||||
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}]]></component>
|
}]]></component>
|
||||||
<component name="RunManager" selected=".NET Launch Settings Profile.Ombi">
|
<component name="RunManager" selected=".NET Launch Settings Profile.Ombi">
|
||||||
|
@ -460,6 +487,7 @@
|
||||||
</method>
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||||
<component name="TaskManager">
|
<component name="TaskManager">
|
||||||
<task active="true" id="Default" summary="Default task">
|
<task active="true" id="Default" summary="Default task">
|
||||||
<changelist id="57001998-efde-494a-80b3-d7acfc91f770" name="Default Changelist" comment="" />
|
<changelist id="57001998-efde-494a-80b3-d7acfc91f770" name="Default Changelist" comment="" />
|
||||||
|
@ -468,6 +496,9 @@
|
||||||
<option name="presentableId" value="Default" />
|
<option name="presentableId" value="Default" />
|
||||||
<updated>1563957157468</updated>
|
<updated>1563957157468</updated>
|
||||||
<workItem from="1563957162999" duration="5401000" />
|
<workItem from="1563957162999" duration="5401000" />
|
||||||
|
<workItem from="1745681294313" duration="1814000" />
|
||||||
|
<workItem from="1747080279165" duration="838000" />
|
||||||
|
<workItem from="1747082180432" duration="1994000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
@ -512,7 +543,13 @@
|
||||||
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="4" weight="0.25" />
|
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="4" weight="0.25" />
|
||||||
</layout>
|
</layout>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="3" />
|
||||||
|
</component>
|
||||||
<component name="UnityProjectConfiguration" hasMinimizedUI="false" />
|
<component name="UnityProjectConfiguration" hasMinimizedUI="false" />
|
||||||
|
<component name="VcsManagerConfiguration">
|
||||||
|
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
|
||||||
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
<breakpoints>
|
<breakpoints>
|
||||||
|
@ -536,12 +573,12 @@
|
||||||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||||
<url>file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs</url>
|
<url>file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs</url>
|
||||||
<line>59</line>
|
<line>59</line>
|
||||||
<properties documentPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs">
|
<properties documentPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs" containingFunctionPresentation="Method 'MultiSearch'">
|
||||||
<startOffsets>
|
<startOffsets>
|
||||||
<option value="2276" />
|
<option value="2369" />
|
||||||
</startOffsets>
|
</startOffsets>
|
||||||
<endOffsets>
|
<endOffsets>
|
||||||
<option value="2316" />
|
<option value="2576" />
|
||||||
</endOffsets>
|
</endOffsets>
|
||||||
</properties>
|
</properties>
|
||||||
<option name="timeStamp" value="4" />
|
<option name="timeStamp" value="4" />
|
||||||
|
@ -549,12 +586,12 @@
|
||||||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||||
<url>file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs</url>
|
<url>file://$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs</url>
|
||||||
<line>49</line>
|
<line>49</line>
|
||||||
<properties documentPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs">
|
<properties documentPath="$PROJECT_DIR$/Ombi.Core/Engine/V2/MultiSearchEngine.cs" containingFunctionPresentation="Method 'MultiSearch'">
|
||||||
<startOffsets>
|
<startOffsets>
|
||||||
<option value="2001" />
|
<option value="1903" />
|
||||||
</startOffsets>
|
</startOffsets>
|
||||||
<endOffsets>
|
<endOffsets>
|
||||||
<option value="2002" />
|
<option value="1945" />
|
||||||
</endOffsets>
|
</endOffsets>
|
||||||
</properties>
|
</properties>
|
||||||
<option name="timeStamp" value="5" />
|
<option name="timeStamp" value="5" />
|
||||||
|
@ -562,16 +599,55 @@
|
||||||
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||||
<url>file://$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs</url>
|
<url>file://$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs</url>
|
||||||
<line>30</line>
|
<line>30</line>
|
||||||
<properties documentPath="$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs">
|
<properties documentPath="$PROJECT_DIR$/Ombi.Api.MusicBrainz/MusicBrainzApi.cs" containingFunctionPresentation="Method 'SearchArtist'">
|
||||||
<startOffsets>
|
<startOffsets>
|
||||||
<option value="917" />
|
<option value="833" />
|
||||||
</startOffsets>
|
</startOffsets>
|
||||||
<endOffsets>
|
<endOffsets>
|
||||||
<option value="1016" />
|
<option value="834" />
|
||||||
</endOffsets>
|
</endOffsets>
|
||||||
</properties>
|
</properties>
|
||||||
<option name="timeStamp" value="7" />
|
<option name="timeStamp" value="7" />
|
||||||
</line-breakpoint>
|
</line-breakpoint>
|
||||||
|
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||||
|
<url>file://$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs</url>
|
||||||
|
<line>110</line>
|
||||||
|
<properties documentPath="$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs" containingFunctionPresentation="Method 'Execute'">
|
||||||
|
<startOffsets>
|
||||||
|
<option value="5123" />
|
||||||
|
</startOffsets>
|
||||||
|
<endOffsets>
|
||||||
|
<option value="5206" />
|
||||||
|
</endOffsets>
|
||||||
|
</properties>
|
||||||
|
<option name="timeStamp" value="10" />
|
||||||
|
</line-breakpoint>
|
||||||
|
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||||
|
<url>file://$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs</url>
|
||||||
|
<line>77</line>
|
||||||
|
<properties documentPath="$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs" containingFunctionPresentation="Method 'Execute'">
|
||||||
|
<startOffsets>
|
||||||
|
<option value="3324" />
|
||||||
|
</startOffsets>
|
||||||
|
<endOffsets>
|
||||||
|
<option value="3365" />
|
||||||
|
</endOffsets>
|
||||||
|
</properties>
|
||||||
|
<option name="timeStamp" value="11" />
|
||||||
|
</line-breakpoint>
|
||||||
|
<line-breakpoint enabled="true" type="DotNet Breakpoints">
|
||||||
|
<url>file://$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs</url>
|
||||||
|
<line>100</line>
|
||||||
|
<properties documentPath="$PROJECT_DIR$/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs" containingFunctionPresentation="Method 'Execute'">
|
||||||
|
<startOffsets>
|
||||||
|
<option value="4602" />
|
||||||
|
</startOffsets>
|
||||||
|
<endOffsets>
|
||||||
|
<option value="4636" />
|
||||||
|
</endOffsets>
|
||||||
|
</properties>
|
||||||
|
<option name="timeStamp" value="12" />
|
||||||
|
</line-breakpoint>
|
||||||
</breakpoints>
|
</breakpoints>
|
||||||
</breakpoint-manager>
|
</breakpoint-manager>
|
||||||
<watches-manager>
|
<watches-manager>
|
||||||
|
|
14
src/.idea/.idea.Ombi/riderModule.iml
generated
14
src/.idea/.idea.Ombi/riderModule.iml
generated
|
@ -1,14 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="RIDER_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$USER_HOME$/.nuget/packages/microsoft.net.test.sdk/16.0.1/build/netcoreapp1.0" />
|
|
||||||
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.13.0/build/netcoreapp1.0/NUnit3.TestAdapter.dll" />
|
|
||||||
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.13.0/build/netcoreapp1.0/NUnit3.TestAdapter.pdb" />
|
|
||||||
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.13.0/build/netcoreapp1.0/nunit.engine.netstandard.dll" />
|
|
||||||
<content url="file://$MODULE_DIR$/../../../CHANGELOG.md" />
|
|
||||||
<content url="file://$MODULE_DIR$/../../../appveyor.yml" />
|
|
||||||
<content url="file://$MODULE_DIR$/../../../build.cake" />
|
|
||||||
<content url="file://$MODULE_DIR$/../.." />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
25
src/.vscode/tasks.json
vendored
25
src/.vscode/tasks.json
vendored
|
@ -1,22 +1,31 @@
|
||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "2.0.0",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"isShellCommand": true,
|
|
||||||
"args": [],
|
"args": [],
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"taskName": "build",
|
"label": "build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
"build",
|
||||||
"${workspaceRoot}/Ombi/Ombi.csproj"
|
"${workspaceRoot}/Ombi/Ombi.csproj"
|
||||||
],
|
],
|
||||||
"isBuildCommand": true,
|
"problemMatcher": "$msCompile",
|
||||||
"problemMatcher": "$msCompile"
|
"group": {
|
||||||
|
"_id": "build",
|
||||||
|
"isDefault": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"taskName": "lint",
|
"label": "lint",
|
||||||
|
"type": "shell",
|
||||||
"command": "npm",
|
"command": "npm",
|
||||||
"isShellCommand": true,
|
"args": [
|
||||||
"args": ["run", "lint"]
|
"run",
|
||||||
|
"lint"
|
||||||
|
],
|
||||||
|
"problemMatcher": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -14,6 +14,7 @@
|
||||||
IssueResolved = 9,
|
IssueResolved = 9,
|
||||||
IssueComment = 10,
|
IssueComment = 10,
|
||||||
Newsletter = 11,
|
Newsletter = 11,
|
||||||
PartiallyAvailable = 12
|
PartiallyAvailable = 12,
|
||||||
|
PlexWatchlistTokenExpired = 13
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
|
||||||
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
<Configurations>Debug;Release;NonUiBuild</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -13,7 +16,7 @@
|
||||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
|
||||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.15.2" />
|
<PackageReference Include="NUnit.ConsoleRunner" Version="3.15.2" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"></packagereference>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -20,6 +20,10 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Ombi.Notifications.Models;
|
||||||
|
using Ombi.Core.Notifications;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
using Ombi.Core;
|
||||||
|
|
||||||
namespace Ombi.Schedule.Tests
|
namespace Ombi.Schedule.Tests
|
||||||
{
|
{
|
||||||
|
@ -35,12 +39,13 @@ namespace Ombi.Schedule.Tests
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_mocker = new AutoMocker();
|
_mocker = new AutoMocker();
|
||||||
var um = MockHelper.MockUserManager(new List<OmbiUser> { new OmbiUser { Id = "abc", UserType = UserType.PlexUser, MediaServerToken = "token1", UserName = "abc", NormalizedUserName = "ABC" } });
|
var um = MockHelper.MockUserManager(new List<OmbiUser> { new OmbiUser { Id = "abc", Email = "email@email.com", UserType = UserType.PlexUser, MediaServerToken = "token1", UserName = "abc", NormalizedUserName = "ABC" } });
|
||||||
_mocker.Use(um);
|
_mocker.Use(um);
|
||||||
_context = _mocker.GetMock<IJobExecutionContext>();
|
_context = _mocker.GetMock<IJobExecutionContext>();
|
||||||
_context.Setup(x => x.CancellationToken).Returns(CancellationToken.None);
|
_context.Setup(x => x.CancellationToken).Returns(CancellationToken.None);
|
||||||
_subject = _mocker.CreateInstance<PlexWatchlistImport>();
|
_subject = _mocker.CreateInstance<PlexWatchlistImport>();
|
||||||
_mocker.Setup<IRepository<PlexWatchlistUserError>, IQueryable<PlexWatchlistUserError>>(x => x.GetAll()).Returns(new List<PlexWatchlistUserError>().AsQueryable().BuildMock());
|
_mocker.Setup<IRepository<PlexWatchlistUserError>, IQueryable<PlexWatchlistUserError>>(x => x.GetAll()).Returns(new List<PlexWatchlistUserError>().AsQueryable().BuildMock());
|
||||||
|
_mocker.Setup<INotificationHelper>(x => x.Notify(It.IsAny<NotificationOptions>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -777,5 +782,61 @@ namespace Ombi.Schedule.Tests
|
||||||
_mocker.Verify<IExternalRepository<PlexWatchlistHistory>>(x => x.GetAll(), Times.Once);
|
_mocker.Verify<IExternalRepository<PlexWatchlistHistory>>(x => x.GetAll(), Times.Once);
|
||||||
_mocker.Verify<IExternalRepository<PlexWatchlistHistory>>(x => x.Add(It.IsAny<PlexWatchlistHistory>()), Times.Once);
|
_mocker.Verify<IExternalRepository<PlexWatchlistHistory>>(x => x.Add(It.IsAny<PlexWatchlistHistory>()), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task AuthenticationError_NotificationsEnabled_WithEmail_SendsNotification()
|
||||||
|
{
|
||||||
|
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync())
|
||||||
|
.ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true, NotifyOnWatchlistTokenExpiration = true });
|
||||||
|
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||||
|
.ReturnsAsync(new PlexWatchlistContainer { AuthError = true });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await _subject.Execute(_context.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_mocker.Verify<INotificationHelper>(x => x.Notify(It.Is<NotificationOptions>(n =>
|
||||||
|
n.NotificationType == NotificationType.PlexWatchlistTokenExpired &&
|
||||||
|
n.Recipient == "email@email.com" &&
|
||||||
|
n.Substitutes["UserName"] == "abc"
|
||||||
|
)), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task AuthenticationError_NotificationsDisabled_WithEmail_DoesNotSendNotification()
|
||||||
|
{
|
||||||
|
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync())
|
||||||
|
.ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true, NotifyOnWatchlistTokenExpiration = false });
|
||||||
|
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||||
|
.ReturnsAsync(new PlexWatchlistContainer { AuthError = true });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await _subject.Execute(_context.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_mocker.Verify<INotificationHelper>(x => x.Notify(It.IsAny<NotificationOptions>()), Times.Never);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task AuthenticationError_NotificationsEnabled_NoEmail_DoesNotSendNotification()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var user = new OmbiUser { Id = "abc", UserType = UserType.PlexUser, MediaServerToken = "token1", UserName = "abc", NormalizedUserName = "ABC" };
|
||||||
|
var um = MockHelper.MockUserManager(new List<OmbiUser> { user });
|
||||||
|
_mocker.Use(um);
|
||||||
|
|
||||||
|
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync())
|
||||||
|
.ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true, NotifyOnWatchlistTokenExpiration = true });
|
||||||
|
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||||
|
.ReturnsAsync(new PlexWatchlistContainer { AuthError = true });
|
||||||
|
|
||||||
|
_subject = _mocker.CreateInstance<PlexWatchlistImport>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await _subject.Execute(_context.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_mocker.Verify<INotificationHelper>(x => x.Notify(It.IsAny<NotificationOptions>()), Times.Never);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:62604/",
|
|
||||||
"sslPort": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Ombi.Schedule.Tests": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
},
|
|
||||||
"applicationUrl": "http://localhost:62605/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,6 +22,11 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Ombi.Notifications.Models;
|
||||||
|
using Ombi.Core.Notifications;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Ombi.Store.Repository.Requests;
|
||||||
|
using Ombi.Core;
|
||||||
|
|
||||||
namespace Ombi.Schedule.Jobs.Plex
|
namespace Ombi.Schedule.Jobs.Plex
|
||||||
{
|
{
|
||||||
|
@ -37,11 +42,12 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
private readonly IExternalRepository<PlexWatchlistHistory> _watchlistRepo;
|
private readonly IExternalRepository<PlexWatchlistHistory> _watchlistRepo;
|
||||||
private readonly IRepository<PlexWatchlistUserError> _userError;
|
private readonly IRepository<PlexWatchlistUserError> _userError;
|
||||||
private readonly IMovieDbApi _movieDbApi;
|
private readonly IMovieDbApi _movieDbApi;
|
||||||
|
private readonly INotificationHelper _notificationHelper;
|
||||||
|
|
||||||
public PlexWatchlistImport(IPlexApi plexApi, ISettingsService<PlexSettings> settings, OmbiUserManager ombiUserManager,
|
public PlexWatchlistImport(IPlexApi plexApi, ISettingsService<PlexSettings> settings, OmbiUserManager ombiUserManager,
|
||||||
IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine, INotificationHubService notificationHubService,
|
IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine, INotificationHubService notificationHubService,
|
||||||
ILogger<PlexWatchlistImport> logger, IExternalRepository<PlexWatchlistHistory> watchlistRepo, IRepository<PlexWatchlistUserError> userError,
|
ILogger<PlexWatchlistImport> logger, IExternalRepository<PlexWatchlistHistory> watchlistRepo, IRepository<PlexWatchlistUserError> userError,
|
||||||
IMovieDbApi movieDbApi)
|
IMovieDbApi movieDbApi, INotificationHelper notificationHelper)
|
||||||
{
|
{
|
||||||
_plexApi = plexApi;
|
_plexApi = plexApi;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
@ -53,6 +59,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
_watchlistRepo = watchlistRepo;
|
_watchlistRepo = watchlistRepo;
|
||||||
_userError = userError;
|
_userError = userError;
|
||||||
_movieDbApi = movieDbApi;
|
_movieDbApi = movieDbApi;
|
||||||
|
_notificationHelper = notificationHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Execute(IJobExecutionContext context)
|
public async Task Execute(IJobExecutionContext context)
|
||||||
|
@ -99,6 +106,22 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
MediaServerToken = user.MediaServerToken,
|
MediaServerToken = user.MediaServerToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Send notification to user about token expiration
|
||||||
|
if (settings.NotifyOnWatchlistTokenExpiration && !string.IsNullOrEmpty(user.Email))
|
||||||
|
{
|
||||||
|
var notificationModel = new NotificationOptions
|
||||||
|
{
|
||||||
|
NotificationType = NotificationType.PlexWatchlistTokenExpired,
|
||||||
|
Recipient = user.Email,
|
||||||
|
DateTime = DateTime.Now,
|
||||||
|
Substitutes = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "UserName", user.UserName }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
await _notificationHelper.Notify(notificationModel);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (watchlist == null || !(watchlist.MediaContainer?.Metadata?.Any() ?? false))
|
if (watchlist == null || !(watchlist.MediaContainer?.Metadata?.Any() ?? false))
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace Ombi.Core.Settings.Models.External
|
||||||
public bool Enable { get; set; }
|
public bool Enable { get; set; }
|
||||||
public bool EnableWatchlistImport { get; set; }
|
public bool EnableWatchlistImport { get; set; }
|
||||||
public bool MonitorAll { get; set; }
|
public bool MonitorAll { get; set; }
|
||||||
|
public bool NotifyOnWatchlistTokenExpiration { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the ClientId for OAuth
|
/// This is the ClientId for OAuth
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -217,6 +217,16 @@ namespace Ombi.Store.Context
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
case NotificationType.PlexWatchlistTokenExpired:
|
||||||
|
notificationToAdd = new NotificationTemplates
|
||||||
|
{
|
||||||
|
NotificationType = notificationType,
|
||||||
|
Message = "Hello {UserName}! Your Plex watchlist token has expired. Please re-authenticate with Ombi to continue using the watchlist feature.",
|
||||||
|
Subject = "Plex Watchlist Token Expired",
|
||||||
|
Agent = agent,
|
||||||
|
Enabled = true,
|
||||||
|
};
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ export enum NotificationType {
|
||||||
IssueComment = 10,
|
IssueComment = 10,
|
||||||
Newsletter = 11,
|
Newsletter = 11,
|
||||||
PartiallyAvailable = 12,
|
PartiallyAvailable = 12,
|
||||||
|
PlexWatchlistTokenExpired = 13
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDiscordNotifcationSettings extends INotificationSettings {
|
export interface IDiscordNotifcationSettings extends INotificationSettings {
|
||||||
|
|
|
@ -114,6 +114,7 @@ export interface IPlexSettings extends ISettings {
|
||||||
enable: boolean;
|
enable: boolean;
|
||||||
enableWatchlistImport: boolean;
|
enableWatchlistImport: boolean;
|
||||||
monitorAll: boolean;
|
monitorAll: boolean;
|
||||||
|
notifyOnWatchlistTokenExpiration: boolean;
|
||||||
servers: IPlexServer[];
|
servers: IPlexServer[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,40 @@
|
||||||
<div class="small-middle-container">
|
<div class="watchlist-dialog-container">
|
||||||
<fieldset style="fieldset">
|
<mat-card class="watchlist-dialog-card">
|
||||||
<legend mat-dialog-title>Watchlist User Errors</legend>
|
<mat-card-header>
|
||||||
<div mat-dialog-content>
|
<mat-card-title>Watchlist User Errors</mat-card-title>
|
||||||
<p>
|
</mat-card-header>
|
||||||
If there is an authentication error, this is because of an authentication issue with Plex (Token has expired).
|
<mat-card-content>
|
||||||
If this happens the user needs to re-login to Ombi.
|
<div class="watchlist-info-section">
|
||||||
</p>
|
<mat-icon color="warn" class="info-icon">error_outline</mat-icon>
|
||||||
<p>
|
<span>
|
||||||
<em class="fa-solid fa-check key"></em> Successfully syncing the watchlist
|
If there is an authentication error, this is because of an authentication issue with Plex (Token has expired).
|
||||||
<br>
|
If this happens the user needs to re-login to Ombi.
|
||||||
<em class="fa-solid fa-times key"></em> Authentication error syncing the watchlist
|
</span>
|
||||||
<br>
|
</div>
|
||||||
<em class="fas fa-user-alt-slash key"></em> Not enabled for user (They need to log into Ombi via Plex)
|
<div class="watchlist-legend">
|
||||||
</p>
|
<span><mat-icon color="primary">check_circle</mat-icon> Successfully syncing the watchlist</span>
|
||||||
<table mat-table *ngIf="dataSource" [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
<span><mat-icon color="warn">cancel</mat-icon> Authentication error syncing the watchlist</span>
|
||||||
<ng-container matColumnDef="userName">
|
<span><mat-icon color="accent">person_off</mat-icon> Not enabled for user (They need to log into Ombi via Plex)</span>
|
||||||
<th mat-header-cell *matHeaderCellDef> Username </th>
|
</div>
|
||||||
<td mat-cell *matCellDef="let element"> {{element.userName}} </td>
|
<table mat-table *ngIf="dataSource" [dataSource]="dataSource" matSort class="mat-elevation-z8 modern-table">
|
||||||
</ng-container>
|
<ng-container matColumnDef="userName">
|
||||||
<ng-container matColumnDef="syncStatus">
|
<th mat-header-cell *matHeaderCellDef> Username </th>
|
||||||
<th mat-header-cell *matHeaderCellDef> Watchlist Sync Result </th>
|
<td mat-cell *matCellDef="let element"> {{element.userName}} </td>
|
||||||
<td mat-cell *matCellDef="let element">
|
</ng-container>
|
||||||
<em *ngIf="element.syncStatus === WatchlistSyncStatus.Successful" class="fa-solid fa-check"></em>
|
<ng-container matColumnDef="syncStatus">
|
||||||
<em *ngIf="element.syncStatus === WatchlistSyncStatus.Failed" class="fa-solid fa-times"></em>
|
<th mat-header-cell *matHeaderCellDef> Watchlist Sync Result </th>
|
||||||
<em *ngIf="element.syncStatus === WatchlistSyncStatus.NotEnabled" class="fas fa-user-alt-slash"></em>
|
<td mat-cell *matCellDef="let element">
|
||||||
</td>
|
<mat-icon *ngIf="element.syncStatus === WatchlistSyncStatus.Successful" color="primary">check_circle</mat-icon>
|
||||||
</ng-container>
|
<mat-icon *ngIf="element.syncStatus === WatchlistSyncStatus.Failed" color="warn">cancel</mat-icon>
|
||||||
|
<mat-icon *ngIf="element.syncStatus === WatchlistSyncStatus.NotEnabled" color="accent">person_off</mat-icon>
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
</td>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
</ng-container>
|
||||||
</table>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
</div>
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
<mat-dialog-actions align="end">
|
</table>
|
||||||
<button mat-button mat-dialog-close>Close</button>
|
</mat-card-content>
|
||||||
</mat-dialog-actions>
|
<mat-card-actions align="end">
|
||||||
</fieldset>
|
<button mat-stroked-button mat-dialog-close color="accent">Close</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
||||||
</div>
|
</div>
|
|
@ -10,4 +10,96 @@
|
||||||
|
|
||||||
.key {
|
.key {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.watchlist-dialog-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.watchlist-dialog-card {
|
||||||
|
background: #23272f;
|
||||||
|
color: #f1f3f6;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid #353a45;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.25);
|
||||||
|
min-width: 420px;
|
||||||
|
max-width: 600px;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 70vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-card-content {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow-y: auto;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-card-header {
|
||||||
|
border-bottom: 1px solid #353a45;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-card-title {
|
||||||
|
color: #fff !important;
|
||||||
|
font-weight: 700 !important;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.watchlist-info-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #23272f;
|
||||||
|
color: #e0e3ea;
|
||||||
|
padding: 12px 0 8px 0;
|
||||||
|
font-size: 15px;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #ffb300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.watchlist-legend {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #b0b6c3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.watchlist-legend mat-icon {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modern-table {
|
||||||
|
background: transparent;
|
||||||
|
color: #f1f3f6;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modern-table th, .modern-table td {
|
||||||
|
color: #f1f3f6;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-card-actions {
|
||||||
|
padding-top: 16px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
background: #23272f;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[mat-stroked-button] {
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 6px;
|
||||||
}
|
}
|
|
@ -1,137 +1,179 @@
|
||||||
<settings-menu></settings-menu>
|
<settings-menu></settings-menu>
|
||||||
<div class="small-middle-container" *ngIf="settings">
|
|
||||||
<fieldset style="width:100%;">
|
<div class="plex-settings-container" *ngIf="settings">
|
||||||
<legend>Plex Configuration</legend>
|
<mat-card class="settings-card">
|
||||||
<div class="col-12">
|
<mat-card-header>
|
||||||
<div class="md-form-field align-right">
|
<mat-card-title>Plex Configuration</mat-card-title>
|
||||||
<button (click)="openWatchlistUserLog()" type="button" class="mat-focus-indicator mat-flat-button mat-button-base mat-accent">Watchlist User Errors</button>
|
</mat-card-header>
|
||||||
|
|
||||||
|
<mat-card-content>
|
||||||
|
<!-- Watchlist Settings Section -->
|
||||||
|
<div class="settings-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<h2>Watchlist Settings</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="settings-grid">
|
||||||
|
<mat-card class="setting-card">
|
||||||
|
<mat-card-content>
|
||||||
|
<div class="setting-header">
|
||||||
|
<h3>Enable Plex</h3>
|
||||||
|
<mat-slide-toggle [id]="'enable'" [(ngModel)]="settings.enable"></mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
|
<mat-card class="setting-card">
|
||||||
|
<mat-card-content>
|
||||||
|
<div class="setting-header">
|
||||||
|
<h3>Enable User Watchlist Requests</h3>
|
||||||
|
<mat-slide-toggle [id]="'enableWatchlistImport'" [(ngModel)]="settings.enableWatchlistImport"></mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
<p class="setting-description">
|
||||||
|
When a Plex User adds something to their watchlist in Plex, it will turn up in Ombi as a Request if enabled.
|
||||||
|
This <strong>only</strong> applies to users that are logging in with their Plex Account.
|
||||||
|
<br>Request limits if set are all still applied
|
||||||
|
</p>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
|
<mat-card class="setting-card" [class.disabled]="!settings.enableWatchlistImport">
|
||||||
|
<mat-card-content>
|
||||||
|
<div class="setting-header">
|
||||||
|
<h3>Request Whole Show</h3>
|
||||||
|
<mat-slide-toggle [id]="'monitorAll'" [(ngModel)]="settings.monitorAll" [disabled]="!settings.enableWatchlistImport"></mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
<p class="setting-description">
|
||||||
|
If enabled then watchlist requests for TV Shows will request the <strong>whole</strong> show.
|
||||||
|
If not enabled it will only request the latest season.
|
||||||
|
</p>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
|
<mat-card class="setting-card" [class.disabled]="!settings.enableWatchlistImport">
|
||||||
|
<mat-card-content>
|
||||||
|
<div class="setting-header">
|
||||||
|
<h3>Notify on Token Expiration</h3>
|
||||||
|
<mat-slide-toggle [id]="'notifyOnWatchlistTokenExpiration'" [(ngModel)]="settings.notifyOnWatchlistTokenExpiration" [disabled]="!settings.enableWatchlistImport"></mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
<p class="setting-description">
|
||||||
|
When enabled, users will receive a notification if their Plex watchlist token expires and they need to log into Ombi again to continue using the watchlist feature.
|
||||||
|
<br><strong>Note:</strong> This requires email notifications to be configured in the notification settings, and users must have an email address set on their account to receive these notifications.
|
||||||
|
</p>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
<mat-card class="info-banner">
|
||||||
|
<mat-icon color="primary" style="margin-right: 12px;">info</mat-icon>
|
||||||
|
<span style="flex:1;">
|
||||||
|
Some users may need to re-log in to use the watchlist feature.
|
||||||
|
</span>
|
||||||
|
<button mat-button color="accent" (click)="openWatchlistUserLog()">
|
||||||
|
View Users
|
||||||
|
</button>
|
||||||
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
<!-- Main Content Area -->
|
||||||
<settings-plex-form-field [label]="'Enable'" [type]="'checkbox'" [id]="'enable'" [(value)]="settings.enable"></settings-plex-form-field>
|
<div class="main-content">
|
||||||
|
<!-- Left Column - Servers and Actions -->
|
||||||
|
<div class="content-column">
|
||||||
|
<!-- Servers Section -->
|
||||||
|
<div class="settings-section">
|
||||||
|
<h2>Plex Servers</h2>
|
||||||
|
<div class="servers-grid">
|
||||||
|
<mat-card class="server-card" *ngFor="let server of settings.servers">
|
||||||
|
<mat-card-content>
|
||||||
|
<button mat-button (click)="edit(server)" [id]="server.name + '-button'">
|
||||||
|
<mat-icon>dns</mat-icon>
|
||||||
|
<span>{{server.name}}</span>
|
||||||
|
</button>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
<settings-plex-form-field [label]="'Enable User Watchlist Requests'" [type]="'checkbox'" [id]="'enableWatchlistImport'" [(value)]="settings.enableWatchlistImport">
|
<mat-card class="server-card new-server">
|
||||||
<small bottom>When a Plex User adds something to their watchlist in Plex, it will turn up in Ombi as a Request if enabled. This <b>only</b> applies to users that are logging in with their Plex Account
|
<mat-card-content>
|
||||||
<br>Request limits if set are all still applied
|
<button mat-button (click)="newServer()" id="newServer">
|
||||||
</small>
|
<mat-icon>add_circle</mat-icon>
|
||||||
</settings-plex-form-field>
|
<span>Add Server</span>
|
||||||
|
</button>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<settings-plex-form-field [disabled]="!settings.enableWatchlistImport" [label]="'Watchlist - Request Whole Show'" disabled [type]="'checkbox'" [id]="'monitorAll'" [(value)]="settings.monitorAll">
|
<!-- Sync Actions Section -->
|
||||||
<small bottom>If enabled then watchlist requests for TV Shows will request the <strong><em>whole</em></strong> show. If not enabled it will only request the latest season.
|
<div class="settings-section">
|
||||||
</small>
|
<h2>Sync Actions</h2>
|
||||||
</settings-plex-form-field>
|
<div class="sync-actions-grid">
|
||||||
|
<button mat-stroked-button (click)="runSync(PlexSyncType.Full)" id="fullSync">
|
||||||
|
<mat-icon>sync</mat-icon>
|
||||||
|
Full Sync
|
||||||
|
</button>
|
||||||
|
<button mat-stroked-button (click)="runSync(PlexSyncType.RecentlyAdded)" id="recentlyAddedSync">
|
||||||
|
<mat-icon>update</mat-icon>
|
||||||
|
Partial Sync
|
||||||
|
</button>
|
||||||
|
<button mat-stroked-button (click)="runSync(PlexSyncType.ClearAndReSync)" id="clearData">
|
||||||
|
<mat-icon>cleaning_services</mat-icon>
|
||||||
|
Clear & Resync
|
||||||
|
</button>
|
||||||
|
<button mat-stroked-button (click)="runSync(PlexSyncType.WatchlistImport)" id="watchlistImport">
|
||||||
|
<mat-icon>playlist_add</mat-icon>
|
||||||
|
Run Watchlist Import
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right Column - Plex Credentials -->
|
||||||
|
<div class="content-column">
|
||||||
|
<div class="settings-section">
|
||||||
|
<h2>Plex Credentials</h2>
|
||||||
|
<mat-card class="credentials-card">
|
||||||
|
<mat-card-content>
|
||||||
|
<p class="credentials-description">
|
||||||
|
These fields are optional to automatically fill in your Plex server settings.
|
||||||
|
<br>This will pass your username and password to the Plex.tv API to grab the servers associated with this user.
|
||||||
|
<br>If you have 2FA enabled on your account, you need to append the 2FA code to the end of your password.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline" class="full-width">
|
||||||
|
<mat-label>Username</mat-label>
|
||||||
|
<input matInput [id]="'username'" [(ngModel)]="username">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<hr>
|
<mat-form-field appearance="outline" class="full-width">
|
||||||
|
<mat-label>Password</mat-label>
|
||||||
|
<input matInput [id]="'password'" type="password" [(ngModel)]="password">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<div class="row">
|
<button mat-raised-button color="primary" id="loadServers" (click)="requestServers()" class="full-width">
|
||||||
<div class="col-md-7">
|
<mat-icon>key</mat-icon>
|
||||||
<h2 style="margin: 1em 0 0 0;">Servers</h2>
|
Load Servers
|
||||||
<mat-list style="display:flex; flex-flow: wrap;">
|
</button>
|
||||||
<mat-card class="server-card" *ngFor="let server of settings.servers">
|
|
||||||
<button mat-button (click)="edit(server)" id="{{server.name}}-button">
|
|
||||||
<h3>{{server.name}}</h3>
|
|
||||||
</button>
|
|
||||||
</mat-card>
|
|
||||||
|
|
||||||
<mat-card class="server-card new-server-card">
|
<mat-form-field appearance="outline" class="full-width mt-3">
|
||||||
<button mat-button (click)="newServer()" id="newServer">
|
<mat-label>Select Server</mat-label>
|
||||||
<i class="fas fa-plus fa-xl"></i>
|
<mat-select [id]="'servers'" *ngIf="loadedServers">
|
||||||
<h3>Manually Add Server</h3>
|
<mat-option (click)="selectServer(s)" *ngFor="let s of loadedServers.servers.server" [value]="s.server">
|
||||||
</button>
|
{{s.name}}
|
||||||
</mat-card>
|
</mat-option>
|
||||||
</mat-list>
|
</mat-select>
|
||||||
|
<input matInput disabled placeholder="No Servers Loaded" *ngIf="!loadedServers">
|
||||||
|
</mat-form-field>
|
||||||
<div class="row">
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
<br />
|
|
||||||
<div class="form-group col-2">
|
|
||||||
<button mat-raised-button (click)="runSync(PlexSyncType.Full)" type="button" id="fullSync"
|
|
||||||
class="mat-focus-indicator mat-stroked-button mat-button-base">Full
|
|
||||||
Sync</button><br />
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-2">
|
|
||||||
<button mat-raised-button (click)="runSync(PlexSyncType.RecentlyAdded)" type="button" id="recentlyAddedSync"
|
|
||||||
class="mat-focus-indicator mat-stroked-button mat-button-base">Partial Sync</button>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-2">
|
|
||||||
<button mat-raised-button (click)="runSync(PlexSyncType.ClearAndReSync)" type="button" id="clearData"
|
|
||||||
class="mat-focus-indicator mat-stroked-button mat-button-base">
|
|
||||||
Clear Data And Resync
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-12">
|
|
||||||
<button mat-raised-button (click)="runSync(PlexSyncType.WatchlistImport)" type="button" id="watchlistImport"
|
|
||||||
class="mat-focus-indicator mat-stroked-button mat-button-base">
|
|
||||||
Run Watchlist Import
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<div>
|
|
||||||
<button mat-raised-button (click)="save()" type="submit" id="save"
|
|
||||||
class="mat-focus-indicator mat-raised-button mat-button-base mat-accent">Submit</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</mat-card-content>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-5">
|
<mat-card-actions align="end">
|
||||||
<div class="md-form-field">
|
<button mat-raised-button color="accent" (click)="save()" id="save">
|
||||||
<label for="username" class="control-label">
|
<mat-icon>save</mat-icon>
|
||||||
<h3>Plex Credentials</h3>
|
Save Changes
|
||||||
<small>These fields are optional to automatically fill in your Plex server settings. <br>
|
</button>
|
||||||
This will pass your username and password to the Plex.tv API to grab the servers associated with this user.
|
</mat-card-actions>
|
||||||
<br>
|
</mat-card>
|
||||||
If you have 2FA enabled on your account, you need to append the 2FA code to the end of your password.</small>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<settings-plex-form-field [label]="'Username'" [id]="'username'" [(value)]="username"></settings-plex-form-field>
|
|
||||||
<settings-plex-form-field [label]="'Password'" [id]="'password'" [type]="'password'" [(value)]="password"></settings-plex-form-field>
|
|
||||||
|
|
||||||
<div class="md-form-field">
|
|
||||||
<div class="right">
|
|
||||||
<button mat-raised-button id="loadServers" (click)="requestServers()"
|
|
||||||
class="mat-stroked-button">Load Servers
|
|
||||||
<i class="fas fa-key"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-2 align-self-center">
|
|
||||||
Please select the server:
|
|
||||||
</div>
|
|
||||||
<div class="md-form-field col-10">
|
|
||||||
<div *ngIf="!loadedServers">
|
|
||||||
<mat-form-field appearance="outline" floatLabel=auto>
|
|
||||||
<input disabled matInput placeholder="No Servers Loaded" id="servers">
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="loadedServers">
|
|
||||||
<mat-form-field appearance="outline">
|
|
||||||
<mat-select placeholder="Servers Loaded! Please Select" id="servers">
|
|
||||||
<mat-option (click)="selectServer(s)"
|
|
||||||
*ngFor="let s of loadedServers.servers.server" [value]="s.server">
|
|
||||||
{{s.name}}</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
<!--(){{settings|json}}-->
|
|
||||||
|
|
|
@ -43,4 +43,258 @@
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.plex-settings-container {
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-card {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.25);
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid #353a45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
||||||
|
gap: 24px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-card {
|
||||||
|
height: 100%;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #353a45;
|
||||||
|
box-shadow: 0 1px 6px 0 rgba(0,0,0,0.18);
|
||||||
|
color: #f1f3f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-card.disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-description {
|
||||||
|
color: #e0e3ea;
|
||||||
|
font-size: 15px;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 36px;
|
||||||
|
margin-top: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.servers-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-card {
|
||||||
|
text-align: center;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #353a45;
|
||||||
|
box-shadow: 0 1px 6px 0 rgba(0,0,0,0.18);
|
||||||
|
color: #f1f3f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-card button {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 24px;
|
||||||
|
color: #f1f3f6;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-card mat-icon {
|
||||||
|
font-size: 32px;
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: #90caf9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sync-actions-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sync-actions-grid button {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24px;
|
||||||
|
color: #f1f3f6;
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid #353a45;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
box-shadow: 0 1px 6px 0 rgba(0,0,0,0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sync-actions-grid mat-icon {
|
||||||
|
font-size: 32px;
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: #90caf9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credentials-card {
|
||||||
|
padding: 24px;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #353a45;
|
||||||
|
box-shadow: 0 1px 6px 0 rgba(0,0,0,0.18);
|
||||||
|
color: #f1f3f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credentials-description {
|
||||||
|
color: #e0e3ea;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-card-title, h2, h3 {
|
||||||
|
color: #fff !important;
|
||||||
|
font-weight: 700 !important;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-card-header {
|
||||||
|
border-bottom: 1px solid #353a45;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-form-field {
|
||||||
|
color: #f1f3f6 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-label, .mat-form-field-label {
|
||||||
|
color: #b0b6c3 !important;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[matInput], .mat-input-element {
|
||||||
|
color: #f1f3f6 !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-select {
|
||||||
|
color: #f1f3f6 !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-3 {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-slide-toggle.mat-checked .mat-slide-toggle-bar {
|
||||||
|
background-color: #90caf9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-slide-toggle-thumb {
|
||||||
|
background-color: #2196f3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[mat-flat-button], button[mat-raised-button], button[mat-stroked-button], button[mat-button] {
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
|
color: #f1f3f6;
|
||||||
|
background: #2196f3;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 1px 4px 0 rgba(0,0,0,0.12);
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
button[mat-flat-button]:hover, button[mat-raised-button]:hover, button[mat-stroked-button]:hover, button[mat-button]:hover {
|
||||||
|
background: #42a5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.main-content {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.settings-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.servers-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sync-actions-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.watchlist-errors-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-banner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #23272f;
|
||||||
|
color: #e0e3ea;
|
||||||
|
border: 1px solid #1976d2;
|
||||||
|
box-shadow: 0 1px 6px 0 rgba(0,0,0,0.12);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
margin-top: 18px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-banner mat-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #42a5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-banner button[mat-button] {
|
||||||
|
margin-left: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue