mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-24 23:15:23 -07:00
fixes
This commit is contained in:
parent
906ee83c6e
commit
7b418673c8
7 changed files with 131 additions and 68 deletions
|
@ -76,3 +76,16 @@
|
||||||
<button *ngIf="!request.denied" mat-raised-button color="danger" (click)="deny(request);">{{ 'Requests.Deny' | translate }}</button>
|
<button *ngIf="!request.denied" mat-raised-button color="danger" (click)="deny(request);">{{ 'Requests.Deny' | translate }}</button>
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
|
<button *ngIf="!tv.fullyAvailable && requestable" mat-fab color="accent" id="addFabBtn" class="floating-fab" [matMenuTriggerFor]="aboveMenu">
|
||||||
|
<i class="fas fa-plus fa-lg"></i>
|
||||||
|
<mat-menu #aboveMenu="matMenu" yPosition="above">
|
||||||
|
<button id="requestAll" mat-menu-item (click)="requestAllSeasons()">{{ 'Search.TvShows.AllSeasons' | translate }}</button>
|
||||||
|
|
||||||
|
<button id="requestFirst" mat-menu-item (click)="requestFirstSeason()">{{ 'Search.TvShows.FirstSeason' | translate }}</button>
|
||||||
|
|
||||||
|
<button id="requestLatest" mat-menu-item (click)="requestLatestSeason()">{{ 'Search.TvShows.LatestSeason' | translate }}</button>
|
||||||
|
|
||||||
|
<button id="requestSelected" mat-menu-item (click)="submitRequests()">{{ 'Common.Request' | translate }}</button>
|
||||||
|
</mat-menu>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
|
@ -192,11 +192,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-md-10">
|
<div class="col-12 col-md-10">
|
||||||
@defer (on viewport; prefetch on idle) {
|
<tv-request-grid
|
||||||
<tv-request-grid id="requests-grid" [tvRequest]="tvRequest" [isAdmin]="isAdmin" [tv]="tv"></tv-request-grid>
|
id="requests-grid"
|
||||||
} @placeholder {
|
[tvRequest]="tvRequest"
|
||||||
<p-skeleton height="2rem" styleClass="mb-2"></p-skeleton>
|
[isAdmin]="isAdmin"
|
||||||
}
|
[tv]="tv">
|
||||||
|
</tv-request-grid>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-md-2">
|
<div class="col-12 col-md-2">
|
||||||
|
@ -229,17 +231,6 @@
|
||||||
</mat-accordion>
|
</mat-accordion>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- FAB Button moved outside of deferred components so it's always visible -->
|
|
||||||
<button *ngIf="!tv.fullyAvailable && (!tv.partlyAvailable || tv.partlyAvailable)" mat-fab color="accent" id="addFabBtn" class="floating-fab" [matMenuTriggerFor]="aboveMenu">
|
|
||||||
<i class="fas fa-plus fa-lg"></i>
|
|
||||||
<mat-menu #aboveMenu="matMenu" yPosition="above">
|
|
||||||
<button id="requestAll" mat-menu-item (click)="requestAllSeasons()">{{ 'Search.TvShows.AllSeasons' | translate }}</button>
|
|
||||||
<button id="requestFirst" mat-menu-item (click)="requestFirstSeason()">{{ 'Search.TvShows.FirstSeason' | translate }}</button>
|
|
||||||
<button id="requestLatest" mat-menu-item (click)="requestLatestSeason()">{{ 'Search.TvShows.LatestSeason' | translate }}</button>
|
|
||||||
<button id="requestSelected" mat-menu-item (click)="submitRequests()">{{ 'Common.Request' | translate }}</button>
|
|
||||||
</mat-menu>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bottom-page-gap"></div>
|
<div class="bottom-page-gap"></div>
|
||||||
|
|
|
@ -13,7 +13,6 @@ import { TvAdvancedOptionsComponent } from "./panels/tv-advanced-options/tv-adva
|
||||||
import { RequestServiceV2 } from "../../../services/requestV2.service";
|
import { RequestServiceV2 } from "../../../services/requestV2.service";
|
||||||
import { forkJoin } from "rxjs";
|
import { forkJoin } from "rxjs";
|
||||||
import { SonarrFacade } from "app/state/sonarr";
|
import { SonarrFacade } from "app/state/sonarr";
|
||||||
import { ITvRequestViewModelV2 } from "../../../interfaces/ISearchTvResult";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
standalone: false,
|
standalone: false,
|
||||||
|
@ -136,57 +135,6 @@ export class TvDetailsComponent implements OnInit {
|
||||||
return this.tv.seasonRequests.every(e => e.episodes.every(x => x.available || x.approved || x.requested));
|
return this.tv.seasonRequests.every(e => e.episodes.every(x => x.available || x.approved || x.requested));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FAB Button methods moved from tv-request-grid component
|
|
||||||
public requestAllSeasons() {
|
|
||||||
this.tv.requestAll = true;
|
|
||||||
this.tv.firstSeason = false;
|
|
||||||
this.tv.latestSeason = false;
|
|
||||||
this.submitRequests();
|
|
||||||
}
|
|
||||||
|
|
||||||
public requestFirstSeason() {
|
|
||||||
this.tv.requestAll = false;
|
|
||||||
this.tv.firstSeason = true;
|
|
||||||
this.tv.latestSeason = false;
|
|
||||||
this.submitRequests();
|
|
||||||
}
|
|
||||||
|
|
||||||
public requestLatestSeason() {
|
|
||||||
this.tv.requestAll = false;
|
|
||||||
this.tv.firstSeason = false;
|
|
||||||
this.tv.latestSeason = true;
|
|
||||||
this.submitRequests();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async submitRequests() {
|
|
||||||
// Make sure something has been selected
|
|
||||||
if (!this.tv.requestAll && !this.tv.firstSeason && !this.tv.latestSeason) {
|
|
||||||
this.messageService.send('You need to select some episodes!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tv.requested = true;
|
|
||||||
|
|
||||||
const viewModel = <ITvRequestViewModelV2>{
|
|
||||||
firstSeason: this.tv.firstSeason,
|
|
||||||
latestSeason: this.tv.latestSeason,
|
|
||||||
requestAll: this.tv.requestAll,
|
|
||||||
theMovieDbId: this.tv.id,
|
|
||||||
requestOnBehalf: null,
|
|
||||||
languageCode: 'en' // Default language, can be enhanced later
|
|
||||||
};
|
|
||||||
viewModel.seasons = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.requestService2.requestTv(viewModel).toPromise();
|
|
||||||
this.messageService.send(`Request for ${this.tv.title} has been added successfully`);
|
|
||||||
// Refresh the data
|
|
||||||
await this.load();
|
|
||||||
} catch (error) {
|
|
||||||
this.messageService.send('Failed to submit request');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkPoster() {
|
private checkPoster() {
|
||||||
if (this.tv.images.original == null) {
|
if (this.tv.images.original == null) {
|
||||||
this.tv.images.original = "../../../images/default_movie_poster.png";
|
this.tv.images.original = "../../../images/default_movie_poster.png";
|
||||||
|
|
|
@ -35,6 +35,8 @@ export default defineConfig({
|
||||||
// Project configuration
|
// Project configuration
|
||||||
projectId: 'o5451s',
|
projectId: 'o5451s',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
e2e: {
|
e2e: {
|
||||||
// Setup node events
|
// Setup node events
|
||||||
async setupNodeEvents(
|
async setupNodeEvents(
|
||||||
|
|
22
tests/cypress/fixtures/wizard-config.json
Normal file
22
tests/cypress/fixtures/wizard-config.json
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"database": {
|
||||||
|
"type": "sqlite",
|
||||||
|
"connectionString": "Data Source=Ombi.db"
|
||||||
|
},
|
||||||
|
"mediaServer": {
|
||||||
|
"type": "plex",
|
||||||
|
"host": "http://localhost:32400",
|
||||||
|
"token": "test-token"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "admin123",
|
||||||
|
"claims": ["Admin"]
|
||||||
|
},
|
||||||
|
"ombiConfig": {
|
||||||
|
"landingPage": "discover",
|
||||||
|
"autoApprove": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,5 +21,8 @@ import './mock-data.commands';
|
||||||
import "cypress-real-events/support";
|
import "cypress-real-events/support";
|
||||||
import '@bahmutov/cy-api/support';
|
import '@bahmutov/cy-api/support';
|
||||||
|
|
||||||
|
// Import our setup utilities
|
||||||
|
import './setup';
|
||||||
|
|
||||||
// Alternatively you can use CommonJS syntax:
|
// Alternatively you can use CommonJS syntax:
|
||||||
// require('./commands')
|
// require('./commands')
|
||||||
|
|
84
tests/cypress/support/setup.ts
Normal file
84
tests/cypress/support/setup.ts
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// Test setup and initialization utilities
|
||||||
|
import './commands';
|
||||||
|
|
||||||
|
// Global setup that runs before all tests
|
||||||
|
beforeEach(() => {
|
||||||
|
// Check if application is already set up
|
||||||
|
cy.checkApplicationSetup();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if the application is already configured
|
||||||
|
Cypress.Commands.add('checkApplicationSetup', () => {
|
||||||
|
cy.log('Checking application setup status...');
|
||||||
|
|
||||||
|
// Try to access the application to see if it's already configured
|
||||||
|
cy.request({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/api/v1/status',
|
||||||
|
failOnStatusCode: false,
|
||||||
|
timeout: 10000
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
// Application is running and configured
|
||||||
|
cy.log('Application is already configured, skipping wizard');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we're on the wizard page
|
||||||
|
cy.visit('/').then(() => {
|
||||||
|
cy.url().then((url) => {
|
||||||
|
if (url.includes('/wizard') || url.includes('/setup')) {
|
||||||
|
cy.log('Wizard detected, running setup...');
|
||||||
|
cy.runWizardSetup();
|
||||||
|
} else {
|
||||||
|
cy.log('Application appears to be configured');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run the wizard setup
|
||||||
|
Cypress.Commands.add('runWizardSetup', () => {
|
||||||
|
cy.log('Running wizard setup...');
|
||||||
|
|
||||||
|
// Import wizard page object
|
||||||
|
cy.fixture('wizard-config').then((config) => {
|
||||||
|
// Run through wizard steps
|
||||||
|
cy.get('[data-test="wizard-welcome-next"]').click();
|
||||||
|
cy.get('[data-test="wizard-database-next"]').click();
|
||||||
|
cy.get('[data-test="wizard-media-server-next"]').click();
|
||||||
|
|
||||||
|
// Create local user
|
||||||
|
cy.get('[data-test="wizard-username"]').type(Cypress.env('username'));
|
||||||
|
cy.get('[data-test="wizard-password"]').type(Cypress.env('password'));
|
||||||
|
cy.get('[data-test="wizard-user-next"]').click();
|
||||||
|
|
||||||
|
// Complete configuration
|
||||||
|
cy.get('[data-test="wizard-config-next"]').click();
|
||||||
|
cy.get('[data-test="wizard-finish"]').click();
|
||||||
|
|
||||||
|
// Wait for setup to complete
|
||||||
|
cy.url().should('not.include', '/wizard');
|
||||||
|
cy.log('Wizard setup completed successfully');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if we need to run setup for this test run
|
||||||
|
Cypress.Commands.add('ensureApplicationSetup', () => {
|
||||||
|
// This command can be called explicitly in tests that need setup
|
||||||
|
cy.checkApplicationSetup();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add to global commands interface
|
||||||
|
declare global {
|
||||||
|
namespace Cypress {
|
||||||
|
interface Chainable {
|
||||||
|
checkApplicationSetup(): Chainable<void>;
|
||||||
|
runWizardSetup(): Chainable<void>;
|
||||||
|
ensureApplicationSetup(): Chainable<void>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue