diff --git a/apps/back-office/src/app/dashboard/dashboard-routing.module.ts b/apps/back-office/src/app/dashboard/dashboard-routing.module.ts index b6ac1f6829..22d05bdd3f 100644 --- a/apps/back-office/src/app/dashboard/dashboard-routing.module.ts +++ b/apps/back-office/src/app/dashboard/dashboard-routing.module.ts @@ -391,20 +391,6 @@ export const routes: Routes = [ }, canActivate: [PermissionGuard], }, - { - path: 'pulljobs', - loadChildren: () => - import('./pages/pull-jobs/pull-jobs.module').then( - (m) => m.PullJobsModule - ), - data: { - permission: { - action: 'read', - subject: 'PullJob', - }, - }, - canActivate: [PermissionGuard], - }, { path: '**', pathMatch: 'full', diff --git a/apps/back-office/src/app/dashboard/dashboard.component.ts b/apps/back-office/src/app/dashboard/dashboard.component.ts index f61ec39af5..902c21da42 100644 --- a/apps/back-office/src/app/dashboard/dashboard.component.ts +++ b/apps/back-office/src/app/dashboard/dashboard.component.ts @@ -109,13 +109,6 @@ export class DashboardComponent extends UnsubscribeComponent { icon: 'settings_input_composite', }); } - if (this.ability.can('read', 'PullJob')) { - administrationItems.push({ - name: this.translate.instant('common.pullJob.few'), - path: '/settings/pulljobs', - icon: 'cloud_download', - }); - } if (administrationItems.length > 0) { navGroups.push({ name: this.translate.instant('pages.administration.title'), diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.html b/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.html deleted file mode 100644 index eb2169a65e..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.html +++ /dev/null @@ -1,284 +0,0 @@ - - - -

- {{ - data.pullJob - ? ('models.pullJob.edit' | translate) - : ('models.pullJob.new' | translate) - }} -

-
- - - -
-
-
- -
- - -
- - -
- - - - - - -
-
- - - -
- - - -
-
- -
- - - -
- -
- - - -
-
-
- -
- - - -
- - -
- - - - {{ application.name }} - - {{ channel.title }} - - - -
-
- - - - {{ 'components.pullJob.modal.mapping' | translate }} - -
-
- - - {{ 'components.pullJob.modal.switch' | translate }} - -
- - -
- -
- -
- - -
- -
- - - - {{ field.name }} - - -
-
- - -
- - - - - {{ 'components.pullJob.modal.addMappingField' | translate }} - -
-
-
-
- -
- - - - {{ element.value }} - - -
-
- -
- - - {{ - 'common.close' | translate - }} - - {{ (data.pullJob ? 'common.update' : 'common.create') | translate }} - - -
- - - - - diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.scss b/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.spec.ts b/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.spec.ts deleted file mode 100644 index b43d4e05d6..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.spec.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { DialogRef, DIALOG_DATA, Dialog } from '@angular/cdk/dialog'; -import { EditPullJobModalComponent } from './edit-pull-job-modal.component'; -import { ApolloTestingModule } from 'apollo-angular/testing'; -import { - TranslateFakeLoader, - TranslateLoader, - TranslateModule, - TranslateService, -} from '@ngx-translate/core'; -import { - TooltipModule, - ButtonModule, - ExpansionPanelModule, - SelectMenuModule, - FormWrapperModule, - TextareaModule, - ChipModule, - GraphQLSelectModule, - IconModule, - DialogModule -} from '@oort-front/ui'; -import { - ReadableCronModule, - CronExpressionControlModule, -} from '@oort-front/shared'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - -describe('EditPullJobModalComponent', () => { - let component: EditPullJobModalComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - TooltipModule, - ButtonModule, - ExpansionPanelModule, - SelectMenuModule, - FormWrapperModule, - TextareaModule, - ChipModule, - GraphQLSelectModule, - IconModule, - EditPullJobModalComponent, - ApolloTestingModule, - DialogModule, - ReadableCronModule, - CronExpressionControlModule, - FormsModule, - ReactiveFormsModule, - BrowserAnimationsModule, - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateFakeLoader, - }, - }), - ], - providers: [ - TranslateService, - { - provide: DialogRef, - useValue: { - updateSize: jest.fn(), - }, - }, - { - provide: DIALOG_DATA, - useValue: {} - }, - { - provide: Dialog, - useValue: {} - } - ] - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(EditPullJobModalComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.ts b/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.ts deleted file mode 100644 index 85ce3316c1..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/components/edit-pull-job-modal/edit-pull-job-modal.component.ts +++ /dev/null @@ -1,486 +0,0 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { FormBuilder, UntypedFormArray, Validators } from '@angular/forms'; -import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog'; -import { - ApiConfiguration, - Application, - Channel, - Form, - PullJob, - status, - authType, - cronValidator, - ApplicationsApplicationNodesQueryResponse, - ApiConfigurationsQueryResponse, - FormQueryResponse, - FormsQueryResponse, - StatusOptionsComponent, - getCachedValues, - updateQueryUniqueValues, -} from '@oort-front/shared'; -import { Apollo, QueryRef } from 'apollo-angular'; -import { - GET_API_CONFIGURATIONS, - GET_SHORT_FORM_BY_ID, - GET_FORM_NAMES, - GET_ROUTING_KEYS, -} from '../../graphql/queries'; -import { - BehaviorSubject, - Observable, - Subscription, - debounceTime, - distinctUntilChanged, -} from 'rxjs'; -import get from 'lodash/get'; -import { CommonModule, DOCUMENT } from '@angular/common'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { TranslateModule } from '@ngx-translate/core'; -import { - ReadableCronModule, - CronExpressionControlModule, -} from '@oort-front/shared'; -import { - TooltipModule, - ButtonModule, - ExpansionPanelModule, - SelectMenuModule, - FormWrapperModule, - TextareaModule, - GraphQLSelectModule, - IconModule, -} from '@oort-front/ui'; -import { DialogModule } from '@oort-front/ui'; -import { MonacoEditorModule } from 'ngx-monaco-editor-v2'; - -/** Items per page for pagination */ -const ITEMS_PER_PAGE = 10; - -/** Default fields */ -const DEFAULT_FIELDS = ['createdBy']; - -/** Pull job modal component */ -@Component({ - standalone: true, - imports: [ - CommonModule, - FormsModule, - ReactiveFormsModule, - TranslateModule, - DialogModule, - GraphQLSelectModule, - ReadableCronModule, - TooltipModule, - ExpansionPanelModule, - CronExpressionControlModule, - IconModule, - TextareaModule, - ButtonModule, - SelectMenuModule, - FormWrapperModule, - StatusOptionsComponent, - MonacoEditorModule, - ], - selector: 'app-edit-pull-job-modal', - templateUrl: './edit-pull-job-modal.component.html', - styleUrls: ['./edit-pull-job-modal.component.scss'], -}) -export class EditPullJobModalComponent implements OnInit { - // === REACTIVE FORM === - /** Reactive form */ - public formGroup = this.fb.group({ - name: [get(this.data, 'pullJob.name', ''), Validators.required], - status: [get(this.data, 'pullJob.status', ''), Validators.required], - apiConfiguration: [ - get(this.data, 'pullJob.apiConfiguration.id', ''), - Validators.required, - ], - url: [get(this.data, 'pullJob.url', '')], - path: [get(this.data, 'pullJob.path', '')], - schedule: [ - get(this.data, 'pullJob.schedule', ''), - [Validators.required, cronValidator()], - ], - convertTo: [get(this.data, 'pullJob.convertTo.id', '')], - channel: [get(this.data, 'pullJob.channel.id', '')], - mapping: this.fb.array( - this.data.pullJob && this.data.pullJob.mapping - ? Object.keys(this.data.pullJob.mapping).map((x: any) => - this.fb.group({ - name: [x, Validators.required], - value: [this.data.pullJob?.mapping[x], Validators.required], - }) - ) - : [] - ), - rawMapping: [ - this.data.pullJob && this.data.pullJob.mapping - ? JSON.stringify(this.data.pullJob?.mapping, null, 2) - : '', - ], - uniqueIdentifiers: [get(this.data, 'pullJob.uniqueIdentifiers', [])], - }); - /** Is hardcoded */ - isHardcoded = true; - - // === FORMS === - /** Forms query */ - public formsQuery!: QueryRef; - - // === CHANNELS === - /** Applications loading state */ - private applicationsLoading = true; - /** Applications */ - public applications = new BehaviorSubject([]); - /** Applications observable */ - public applications$!: Observable; - /** Cached applications */ - private cachedApplications: Application[] = []; - /** Applications query */ - private applicationsQuery!: QueryRef; - /** Applications pagination info */ - private applicationsPageInfo = { - endCursor: '', - hasNextPage: true, - }; - - // === API === - /** Api configurations */ - public apiConfigurations: ApiConfiguration[] = []; - /** Api configurations query */ - public apiConfigurationsQuery!: QueryRef; - - // === DATA === - /** Status choices */ - public statusChoices = Object.values(status); - /** Fields array */ - public fields: any[] = []; - /** Forms subscription */ - private fieldsSubscription?: Subscription; - - // === RAW JSON UTILITY === - /** Open raw JSON */ - public openRawJSON = false; - - /** @returns pull job mapping as form array */ - get mappingArray(): UntypedFormArray { - return this.formGroup.get('mapping') as UntypedFormArray; - } - - /** @returns default API configuration */ - get defaultApiConfiguration(): ApiConfiguration | null { - return this.data.pullJob?.apiConfiguration || null; - } - - /** @returns default convert to form */ - get defaultForm(): Form | null { - return this.data.pullJob?.convertTo || null; - } - - /** @returns default channel */ - get defaultChannel(): Channel | null { - return this.data.pullJob?.channel || null; - } - - /** Monaco editor configuration, for raw edition */ - public editorOptions = { - theme: 'vs-dark', - language: 'json', - fixedOverflowWidgets: true, - }; - - /** - * Pull job modal component - * - * @param fb Angular form builder - * @param dialogRef Dialog ref - * @param apollo Apollo service - * @param document Document - * @param data Modal injected data - * @param data.channels list of available channels - * @param data.pullJob pull job - */ - constructor( - private fb: FormBuilder, - public dialogRef: DialogRef, - private apollo: Apollo, - @Inject(DOCUMENT) private document: Document, - @Inject(DIALOG_DATA) - public data: { - channels: Channel[]; - pullJob?: PullJob; - } - ) {} - - ngOnInit(): void { - this.formsQuery = this.apollo.watchQuery({ - query: GET_FORM_NAMES, - variables: { - first: ITEMS_PER_PAGE, - sortField: 'name', - }, - }); - - this.apiConfigurationsQuery = - this.apollo.watchQuery({ - query: GET_API_CONFIGURATIONS, - variables: { - first: ITEMS_PER_PAGE, - }, - }); - this.apiConfigurationsQuery.valueChanges.subscribe( - ({ data }) => - (this.apiConfigurations = data.apiConfigurations.edges.map( - (x) => x.node - )) - ); - - // Fetch form fields if any for mapping - if (this.data.pullJob?.convertTo?.id) { - this.getFields(this.data.pullJob?.convertTo.id); - } - this.formGroup.get('convertTo')?.valueChanges.subscribe((res) => { - if (res) { - this.getFields(res); - } - }); - - // Fetch the applications to get the channels - this.applicationsQuery = - this.apollo.watchQuery({ - query: GET_ROUTING_KEYS, - variables: { - first: ITEMS_PER_PAGE, - afterCursor: this.applicationsPageInfo.endCursor, - }, - }); - - // this.applications$ = this.applications.asObservable(); - this.applicationsQuery.valueChanges.subscribe(({ data, loading }) => { - this.updateValues(data, loading); - }); - - // Set boolean to allow additional fields if it's not isHardcoded - this.isHardcoded = !( - this.data.pullJob && - this.data.pullJob.apiConfiguration && - this.data.pullJob.apiConfiguration.authType && - this.data.pullJob.apiConfiguration.authType === authType.public - ); - this.formGroup - .get('apiConfiguration') - ?.valueChanges.subscribe((apiConfiguration: string | null) => { - if (apiConfiguration) { - const api = this.apiConfigurations.find( - (x) => x.id === apiConfiguration - ); - this.isHardcoded = !( - api && - api.authType && - api.authType === authType.public - ); - } - }); - - this.formGroup - .get('rawMapping') - ?.valueChanges.pipe(debounceTime(500), distinctUntilChanged()) - .subscribe((value: any) => { - const mapping = JSON.parse(value || '{}'); - this.formGroup.setControl( - 'mapping', - this.fb.array( - Object.keys(mapping).map((x: any) => - this.fb.group({ - name: [x, Validators.required], - value: [mapping[x], Validators.required], - }) - ) - ) - ); - }); - } - - /** - * Get fields from form id. - * - * @param id Id of selected form. - */ - private getFields(id: string): void { - if (this.fieldsSubscription) { - this.fieldsSubscription.unsubscribe(); - } - this.fieldsSubscription = this.apollo - .watchQuery({ - query: GET_SHORT_FORM_BY_ID, - variables: { - id, - }, - }) - .valueChanges.subscribe((resForm) => { - if (resForm.data.form) { - this.fields = resForm.data.form.fields || []; - this.fields = this.fields.concat( - DEFAULT_FIELDS.map((x) => ({ name: x })) - ); - } - }); - } - - /** - * Filters fields so we cannot add a multiple mapping for the same one. - * - * @param name Field name. - * @returns Filtered fields. - */ - public filteredFields(name: string): any[] { - return this.fields.filter( - (field) => - field.name === name || - !this.formGroup.value.mapping?.some((x: any) => x.name === field.name) - ); - } - - /** - * Removes element from the mapping - * - * @param index mapping element index. - */ - onDeleteElement(index: number): void { - this.mappingArray.removeAt(index); - } - - /** - * Adds new element to the mapping. - */ - onAddElement(): void { - this.mappingArray.push( - this.fb.group({ - name: ['', Validators.required], - value: ['', Validators.required], - }) - ); - } - - /** - * Toggles the edit mode and update form values accordingly. - */ - toggleRawJSON(): void { - this.synchronizeFormValueData(); - this.openRawJSON = !this.openRawJSON; - } - - /** - * Synchronize mapping of the form value to the raw mapping if user don't want to open raw JSON - */ - private synchronizeFormValueData() { - if (!this.openRawJSON) { - const mapping = this.formGroup - .get('mapping') - ?.value.reduce( - (o: any, field: any) => ({ ...o, [field.name]: field.value }), - {} - ); - this.formGroup - .get('rawMapping') - ?.setValue(JSON.stringify(mapping, null, 2)); - } - } - - /** - * Synchronizes mapping values on update button click. - * - * @returns Return form value. - */ - returnFormValue(): any { - this.synchronizeFormValueData(); - return this.formGroup.value; - } - - /** - * Adds scroll listener to channels select. - */ - onOpenApplicationSelect(): void { - const panel = this.document.getElementById('optionList'); - if (panel) { - panel.onscroll = (event: any) => this.loadOnScrollApplication(event); - } - } - - /** - * Fetches more channels on scroll. - * - * @param e scroll event. - */ - private loadOnScrollApplication(e: any): void { - if ( - e.target.scrollHeight - (e.target.clientHeight + e.target.scrollTop) < - 50 - ) { - if (!this.applicationsLoading && this.applicationsPageInfo.hasNextPage) { - this.applicationsLoading = true; - const variables = { - first: ITEMS_PER_PAGE, - afterCursor: this.applicationsPageInfo.endCursor, - }; - const cachedValues: ApplicationsApplicationNodesQueryResponse = - getCachedValues(this.apollo.client, GET_ROUTING_KEYS, variables); - if (cachedValues) { - this.updateValues(cachedValues, false); - } else { - this.applicationsQuery - .fetchMore({ - variables, - }) - .then((results) => - this.updateValues(results.data, results.loading) - ); - } - } - } - } - - /** - * Changes the query according to search text - * - * @param search Search text from the graphql select - */ - public onFormSearchChange(search: string): void { - const variables = this.formsQuery.variables; - this.formsQuery.refetch({ - ...variables, - filter: { - logic: 'and', - filters: [ - { - field: 'name', - operator: 'contains', - value: search, - }, - ], - }, - }); - } - - /** - * Update application data value - * - * @param data query response data - * @param loading loading status - */ - private updateValues( - data: ApplicationsApplicationNodesQueryResponse, - loading: boolean - ) { - const nodes = data.applications.edges - .map((x) => x.node) - .filter((x) => (x.channels ? x.channels.length > 0 : false)); - this.cachedApplications = updateQueryUniqueValues( - this.cachedApplications, - nodes - ); - this.applications.next(this.cachedApplications); - this.applicationsPageInfo = data.applications.pageInfo; - this.applicationsLoading = loading; - } -} diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/graphql/mutations.ts b/apps/back-office/src/app/dashboard/pages/pull-jobs/graphql/mutations.ts deleted file mode 100644 index 9b90bda6d4..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/graphql/mutations.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { gql } from 'apollo-angular'; - -// === EDIT PULL JOB === -/** Edit pull job gql mutation definition */ -export const EDIT_PULL_JOB = gql` - mutation editPullJob( - $id: ID! - $name: String - $status: Status - $apiConfiguration: ID - $url: String - $path: String - $schedule: String - $convertTo: ID - $mapping: JSON - $uniqueIdentifiers: [String] - $channel: ID - ) { - editPullJob( - id: $id - name: $name - status: $status - apiConfiguration: $apiConfiguration - url: $url - path: $path - schedule: $schedule - convertTo: $convertTo - mapping: $mapping - uniqueIdentifiers: $uniqueIdentifiers - channel: $channel - ) { - id - name - status - apiConfiguration { - id - name - } - schedule - convertTo { - id - name - } - mapping - uniqueIdentifiers - channel { - id - title - } - } - } -`; - -// === DELETE PULL JOB === -/** Delete pull job gql mutation definition */ -export const DELETE_PULL_JOB = gql` - mutation deletePullJob($id: ID!) { - deletePullJob(id: $id) { - id - } - } -`; - -// === ADD PULL JOB === -/** Add pull job gql mutation definition */ -export const ADD_PULL_JOB = gql` - mutation addPullJob( - $name: String! - $status: Status! - $apiConfiguration: ID! - $url: String - $path: String - $schedule: String - $convertTo: ID - $mapping: JSON - $uniqueIdentifiers: [String] - $channel: ID - ) { - addPullJob( - name: $name - status: $status - apiConfiguration: $apiConfiguration - url: $url - path: $path - schedule: $schedule - convertTo: $convertTo - mapping: $mapping - uniqueIdentifiers: $uniqueIdentifiers - channel: $channel - ) { - id - name - status - apiConfiguration { - id - name - } - schedule - convertTo { - id - name - } - mapping - uniqueIdentifiers - channel { - id - title - } - } - } -`; diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/graphql/queries.ts b/apps/back-office/src/app/dashboard/pages/pull-jobs/graphql/queries.ts deleted file mode 100644 index 076db903dd..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/graphql/queries.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { gql } from 'apollo-angular'; - -// === GET PULL JOBS === - -/** Graphql queryfor getting multiple pull job objects with a cursor */ -export const GET_PULL_JOBS = gql` - query GetPullJobs($first: Int, $afterCursor: ID) { - pullJobs(first: $first, afterCursor: $afterCursor) { - edges { - node { - id - name - status - apiConfiguration { - id - name - authType - } - url - path - schedule - convertTo { - id - name - } - mapping - uniqueIdentifiers - channel { - id - title - } - } - cursor - } - totalCount - pageInfo { - hasNextPage - endCursor - } - } - } -`; - -// === GET ROUTING KEYS === - -/** Graphql query for getting routing keys with a cursor */ -export const GET_ROUTING_KEYS = gql` - query GetRoutingKeys($first: Int, $afterCursor: ID) { - applications(first: $first, afterCursor: $afterCursor) { - edges { - node { - id - name - channels { - id - title - routingKey - } - } - cursor - } - totalCount - pageInfo { - hasNextPage - endCursor - } - } - } -`; - -// === GET FORMS === -/** Graphql query for getting form names */ -export const GET_FORM_NAMES = gql` - query GetFormNames( - $first: Int - $afterCursor: ID - $sortField: String - $filter: JSON - ) { - forms( - first: $first - afterCursor: $afterCursor - sortField: $sortField - filter: $filter - ) { - edges { - node { - id - name - } - cursor - } - totalCount - pageInfo { - hasNextPage - endCursor - } - } - } -`; - -// === GET FORM BY ID === -/** Graphql query for getting a form with minimum details by id */ -export const GET_SHORT_FORM_BY_ID = gql` - query GetShortFormById($id: ID!) { - form(id: $id) { - id - name - core - structure - fields - status - canCreateRecords - uniqueRecord { - id - modifiedAt - data - } - permissions { - canSee { - id - title - } - canUpdate { - id - title - } - canDelete { - id - title - } - } - canUpdate - } - } -`; - -// === GET API CONFIGURATIONS === - -/** Graphql query for getting multiple api configurations object with a cursor */ -export const GET_API_CONFIGURATIONS = gql` - query GetApiConfigurations($first: Int, $afterCursor: ID) { - apiConfigurations(first: $first, afterCursor: $afterCursor) { - edges { - node { - id - name - status - authType - endpoint - pingUrl - settings - permissions { - canSee { - id - title - } - canUpdate { - id - title - } - canDelete { - id - title - } - } - canSee - canUpdate - canDelete - } - cursor - } - totalCount - pageInfo { - hasNextPage - endCursor - } - } - } -`; diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs-routing.module.ts b/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs-routing.module.ts deleted file mode 100644 index 271025281b..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs-routing.module.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { PullJobsComponent } from './pull-jobs.component'; - -/** List of routes of Pull Jobs page module. */ -const routes: Routes = [ - { - path: '', - component: PullJobsComponent, - }, -]; - -/** Pull jobs page routing module. */ -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class PullJobsRoutingModule {} diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.html b/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.html deleted file mode 100644 index 514e6cf031..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.html +++ /dev/null @@ -1,130 +0,0 @@ - - -
- -
-
- - - {{ 'pages.pullJobs.create' | translate }} - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - -
- {{ 'common.name' | translate }} - - {{ element.name }} - - {{ 'common.status' | translate }} - - - - {{ 'models.pullJob.nextIteration' | translate }} - - {{ element.schedule | sharedCronParser | sharedDate : 'short' }} - - - - - - - - -
-
-
-
- - - - -
- - - - - - - - diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.scss b/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.spec.ts b/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.spec.ts deleted file mode 100644 index db6811d32b..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { DialogModule } from '@angular/cdk/dialog'; -import { PullJobsComponent } from './pull-jobs.component'; -import { ApolloTestingModule } from 'apollo-angular/testing'; -import { - TranslateFakeLoader, - TranslateLoader, - TranslateModule, - TranslateService, -} from '@ngx-translate/core'; -import { - ButtonModule, - PaginatorModule, -} from '@oort-front/ui'; -import { SkeletonTableModule } from '@oort-front/shared'; - -describe('PullJobsComponent', () => { - let component: PullJobsComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [PullJobsComponent], - imports: [ - DialogModule, - ApolloTestingModule, - ButtonModule, - PaginatorModule, - SkeletonTableModule, - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateFakeLoader, - }, - }), - ], - providers: [TranslateService] - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(PullJobsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.ts b/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.ts deleted file mode 100644 index a7c3834020..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.component.ts +++ /dev/null @@ -1,412 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { Dialog } from '@angular/cdk/dialog'; -import { - AddPullJobMutationResponse, - Channel, - DeletePullJobMutationResponse, - EditPullJobMutationResponse, - PullJob, - ConfirmService, - UnsubscribeComponent, - PullJobsNodesQueryResponse, - getCachedValues, - updateQueryUniqueValues, -} from '@oort-front/shared'; -import { Apollo, QueryRef } from 'apollo-angular'; -import { GET_PULL_JOBS } from './graphql/queries'; -import { - ADD_PULL_JOB, - DELETE_PULL_JOB, - EDIT_PULL_JOB, -} from './graphql/mutations'; -import { TranslateService } from '@ngx-translate/core'; -import { ApolloQueryResult } from '@apollo/client'; -import { takeUntil } from 'rxjs'; -import { SnackbarService, UIPageChangeEvent } from '@oort-front/ui'; - -/** - * Limit of pull jobs shown at once. - */ -const ITEMS_PER_PAGE = 10; - -/** - * Shows all pull-jobs available. - */ -@Component({ - selector: 'app-pull-jobs', - templateUrl: './pull-jobs.component.html', - styleUrls: ['./pull-jobs.component.scss'], -}) -export class PullJobsComponent extends UnsubscribeComponent implements OnInit { - // === DATA === - /** Loading state */ - public loading = true; - /** Pull jobs query */ - private pullJobsQuery!: QueryRef; - /** Pull jobs */ - public pullJobs = new Array(); - /** Cached pull jobs */ - public cachedPullJobs: PullJob[] = []; - - /** Columns to display */ - public displayedColumns: string[] = ['name', 'status', 'schedule', 'actions']; - - // === SUBSCRIPTIONS === - /** Channels */ - private channels: Channel[] = []; - - /** Page info */ - public pageInfo = { - pageIndex: 0, - pageSize: ITEMS_PER_PAGE, - length: 0, - endCursor: '', - }; - - /** - * PullJobsComponent constructor. - * - * @param dialog Used to show popup dialog. - * @param apollo Loads the pull jobs. - * @param snackBar Service used to show a snackbar. - * @param confirmService Shared confirm service - * @param translate Service used to get the translations. - */ - constructor( - public dialog: Dialog, - private apollo: Apollo, - private snackBar: SnackbarService, - private confirmService: ConfirmService, - private translate: TranslateService - ) { - super(); - } - - ngOnInit(): void { - this.pullJobsQuery = this.apollo.watchQuery({ - query: GET_PULL_JOBS, - variables: { - first: ITEMS_PER_PAGE, - afterCursor: this.pageInfo.endCursor, - }, - }); - - this.pullJobsQuery.valueChanges - .pipe(takeUntil(this.destroy$)) - .subscribe((results) => { - this.updateValues(results.data, results.loading); - }); - } - - /** - * Handles page event. - * - * @param e page event. - */ - onPage(e: UIPageChangeEvent): void { - this.pageInfo.pageIndex = e.pageIndex; - if ( - ((e.pageIndex > e.previousPageIndex && - e.pageIndex * this.pageInfo.pageSize >= this.cachedPullJobs.length) || - e.pageSize > this.pageInfo.pageSize) && - e.totalItems > this.cachedPullJobs.length - ) { - this.loading = true; - const variables = { - first: ITEMS_PER_PAGE, - afterCursor: this.pageInfo.endCursor, - }; - const cachedValues: PullJobsNodesQueryResponse = getCachedValues( - this.apollo.client, - GET_PULL_JOBS, - variables - ); - if (cachedValues) { - this.updateValues(cachedValues, false); - } else { - this.pullJobsQuery - .fetchMore({ variables }) - .then((results: ApolloQueryResult) => { - this.updateValues(results.data, results.loading); - }); - } - } else { - this.pullJobs = this.cachedPullJobs.slice( - ITEMS_PER_PAGE * this.pageInfo.pageIndex, - ITEMS_PER_PAGE * (this.pageInfo.pageIndex + 1) - ); - } - } - - /** - * Displays the AddSubscription modal. - * Creates the pull job on close. - */ - async onAdd(): Promise { - const { EditPullJobModalComponent } = await import( - './components/edit-pull-job-modal/edit-pull-job-modal.component' - ); - const dialogRef = this.dialog.open(EditPullJobModalComponent, { - autoFocus: false, - data: { - channels: this.channels, - }, - }); - dialogRef.closed.pipe(takeUntil(this.destroy$)).subscribe((value: any) => { - if (value) { - const variables = { - name: value.name, - status: value.status, - apiConfiguration: value.apiConfiguration, - }; - Object.assign( - variables, - value.url && { url: value.url }, - value.path && { path: value.path }, - value.schedule && { schedule: value.schedule }, - value.convertTo && { convertTo: value.convertTo }, - value.channel && { channel: value.channel }, - value.rawMapping && { mapping: JSON.parse(value.rawMapping) }, - value.uniqueIdentifiers && { - uniqueIdentifiers: value.uniqueIdentifiers, - } - ); - this.apollo - .mutate({ - mutation: ADD_PULL_JOB, - variables, - }) - .subscribe({ - next: ({ errors, data }) => { - if (errors) { - this.snackBar.openSnackBar( - this.translate.instant( - 'common.notifications.objectNotCreated', - { - type: this.translate - .instant('common.pullJob.one') - .toLowerCase(), - error: errors ? errors[0].message : '', - } - ), - { error: true } - ); - } else { - if (data?.addPullJob) { - this.snackBar.openSnackBar( - this.translate.instant( - 'common.notifications.objectCreated', - { - type: this.translate.instant('common.pullJob.one'), - value: value.name, - } - ) - ); - if (this.cachedPullJobs.length === this.pageInfo.length) { - this.cachedPullJobs = this.cachedPullJobs.concat([ - data?.addPullJob, - ]); - this.pullJobs = this.cachedPullJobs.slice( - ITEMS_PER_PAGE * this.pageInfo.pageIndex, - ITEMS_PER_PAGE * (this.pageInfo.pageIndex + 1) - ); - } - this.pageInfo.length += 1; - } - } - }, - error: (err) => { - this.snackBar.openSnackBar(err.message, { error: true }); - }, - }); - } - }); - } - - /** - * Deletes a pull job. - * - * @param element pull job to delete. - */ - onDelete(element: any): void { - if (element) { - const dialogRef = this.confirmService.openConfirmModal({ - title: this.translate.instant('components.pullJob.delete.title'), - content: this.translate.instant( - 'components.pullJob.delete.confirmationMessage', - { - name: element.name, - } - ), - confirmText: this.translate.instant('components.confirmModal.delete'), - confirmVariant: 'danger', - }); - dialogRef.closed - .pipe(takeUntil(this.destroy$)) - .subscribe((value: any) => { - if (value) { - this.apollo - .mutate({ - mutation: DELETE_PULL_JOB, - variables: { - id: element.id, - }, - }) - .subscribe({ - next: ({ errors, data }) => { - if (errors) { - this.snackBar.openSnackBar( - this.translate.instant( - 'common.notifications.objectNotDeleted', - { - value: this.translate.instant('common.pullJob.one'), - error: errors ? errors[0].message : '', - } - ), - { error: true } - ); - } else { - if (data?.deletePullJob) { - this.snackBar.openSnackBar( - this.translate.instant( - 'common.notifications.objectDeleted', - { - value: this.translate.instant('common.pullJob.one'), - } - ) - ); - this.cachedPullJobs = this.cachedPullJobs.filter( - (x) => x.id !== data?.deletePullJob.id - ); - this.pageInfo.length -= 1; - this.pullJobs = this.cachedPullJobs.slice( - ITEMS_PER_PAGE * this.pageInfo.pageIndex, - ITEMS_PER_PAGE * (this.pageInfo.pageIndex + 1) - ); - } - } - }, - error: (err) => { - this.snackBar.openSnackBar(err.message, { error: true }); - }, - }); - } - }); - } - } - - /** - * Edits a pull job. - * - * @param element pull job to edit. - */ - async onEdit(element: any): Promise { - const { EditPullJobModalComponent } = await import( - './components/edit-pull-job-modal/edit-pull-job-modal.component' - ); - const dialogRef = this.dialog.open(EditPullJobModalComponent, { - data: { - channels: this.channels, - pullJob: element, - }, - }); - dialogRef.closed.pipe(takeUntil(this.destroy$)).subscribe((value: any) => { - if (value) { - const variables = { - id: element.id, - }; - Object.assign( - variables, - value.name && { name: value.name }, - value.status && { status: value.status }, - value.apiConfiguration && { - apiConfiguration: value.apiConfiguration, - }, - value.url && { url: value.url }, - value.path && { path: value.path }, - value.schedule && { schedule: value.schedule }, - value.convertTo && { convertTo: value.convertTo }, - value.channel && { channel: value.channel }, - value.rawMapping && { mapping: JSON.parse(value.rawMapping) }, - value.uniqueIdentifiers && { - uniqueIdentifiers: value.uniqueIdentifiers, - } - ); - this.apollo - .mutate({ - mutation: EDIT_PULL_JOB, - variables, - }) - .subscribe({ - next: ({ errors, data }) => { - if (errors) { - this.snackBar.openSnackBar( - this.translate.instant( - 'common.notifications.objectNotUpdated', - { - value: this.translate.instant('common.pullJob.one'), - error: errors ? errors[0].message : '', - } - ), - { error: true } - ); - } else { - if (data?.editPullJob) { - this.snackBar.openSnackBar( - this.translate.instant( - 'common.notifications.objectUpdated', - { - type: this.translate - .instant('common.pullJob.one') - .toLowerCase(), - value: value.name, - } - ) - ); - this.cachedPullJobs = this.cachedPullJobs.map( - (pullJob: PullJob) => { - if (pullJob.id === data?.editPullJob.id) { - pullJob = data?.editPullJob || pullJob; - } - return pullJob; - } - ); - this.pullJobs = this.cachedPullJobs.slice( - ITEMS_PER_PAGE * this.pageInfo.pageIndex, - ITEMS_PER_PAGE * (this.pageInfo.pageIndex + 1) - ); - } - } - }, - error: (err) => { - this.snackBar.openSnackBar(err.message, { error: true }); - }, - }); - } - }); - } - - /** - * Updates local list with given data - * - * @param data New values to update forms - * @param loading Loading state - */ - private updateValues( - data: PullJobsNodesQueryResponse, - loading: boolean - ): void { - const mappedValues = data.pullJobs.edges.map((x) => x.node); - this.cachedPullJobs = updateQueryUniqueValues( - this.cachedPullJobs, - mappedValues - ); - this.pageInfo.length = data.pullJobs.totalCount; - this.pageInfo.endCursor = data.pullJobs.pageInfo.endCursor; - this.pullJobs = this.cachedPullJobs.slice( - ITEMS_PER_PAGE * this.pageInfo.pageIndex, - ITEMS_PER_PAGE * (this.pageInfo.pageIndex + 1) - ); - this.loading = loading; - } -} diff --git a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.module.ts b/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.module.ts deleted file mode 100644 index 085698795b..0000000000 --- a/apps/back-office/src/app/dashboard/pages/pull-jobs/pull-jobs.module.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { PullJobsRoutingModule } from './pull-jobs-routing.module'; -import { PullJobsComponent } from './pull-jobs.component'; -import { IconModule, TooltipModule } from '@oort-front/ui'; -import { - SkeletonTableModule, - CronParserModule, - DateModule, - StatusOptionsComponent, - EmptyModule, -} from '@oort-front/shared'; -import { TranslateModule } from '@ngx-translate/core'; -import { - DividerModule, - MenuModule, - ButtonModule, - TableModule, - PaginatorModule, -} from '@oort-front/ui'; - -/** Pull Jobs page module. */ -@NgModule({ - declarations: [PullJobsComponent], - imports: [ - CommonModule, - PullJobsRoutingModule, - IconModule, - MenuModule, - DividerModule, - PaginatorModule, - TranslateModule, - SkeletonTableModule, - CronParserModule, - DateModule, - ButtonModule, - TableModule, - StatusOptionsComponent, - EmptyModule, - TooltipModule, - ], -}) -export class PullJobsModule {} diff --git a/libs/shared/src/i18n/en.json b/libs/shared/src/i18n/en.json index 75b207a175..fcc27ed5e2 100644 --- a/libs/shared/src/i18n/en.json +++ b/libs/shared/src/i18n/en.json @@ -336,11 +336,6 @@ "preview": "Preview", "previous": "Previous", "publish": "Publish", - "pullJob": { - "few": "Pull jobs", - "none": "No pull job", - "one": "Pull job" - }, "record": { "few": "Records", "none": "No record", @@ -939,31 +934,16 @@ "title": "Preferences" }, "pullJob": { - "delete": { - "confirmationMessage": "Do you confirm the deletion of the pull job {{name}}?", - "title": "Delete pull job" - }, "modal": { - "addMappingField": "add a mapping field", "errors": { "schedule": "Enter a valid cron expression" }, "hint": { - "path": "Enter the path to extract data from response", - "schedule": "Enter the schedule time for this Pull job", - "url": "Enter the URL after the host to reach specific data" + "schedule": "Enter the schedule time for this Pull job" }, - "identifier": "Unique identifiers", - "mapping": "Mapping", "placeholder": { - "path": "Enter path...", - "schedule": "Enter schedule time...", - "url": "Enter URL..." - }, - "switch": "Switch mode" - }, - "paginator": { - "ariaLabel": "Select page of pull jobs" + "schedule": "Enter schedule time..." + } } }, "queryBuilder": { @@ -2214,12 +2194,7 @@ "new": "New position attribute" }, "pullJob": { - "edit": "Edit pull job", - "new": "New pull job", - "nextIteration": "Next iteration", - "path": "Path", - "schedule": "Schedule", - "url": "Url" + "schedule": "Schedule" }, "record": { "convert": "Convert", @@ -2430,9 +2405,6 @@ }, "title": "Your profile" }, - "pullJobs": { - "create": "Create a pull job" - }, "referenceData": { "csv": "CSV input", "fields": { diff --git a/libs/shared/src/i18n/fr.json b/libs/shared/src/i18n/fr.json index 01c9f1be63..8cf1833f2f 100644 --- a/libs/shared/src/i18n/fr.json +++ b/libs/shared/src/i18n/fr.json @@ -336,11 +336,6 @@ "preview": "Prévisualisation", "previous": "Précédent", "publish": "Publier", - "pullJob": { - "few": "Tâches planifiées", - "none": "Aucune tâche planifiée", - "one": "Tâche planifiée" - }, "record": { "few": "Enregistrements", "none": "Pas d'enregistrement", @@ -950,31 +945,16 @@ "title": "Préférences" }, "pullJob": { - "delete": { - "confirmationMessage": "Voulez-vous vraiment supprimer la tâche {{name}} ?", - "title": "Supprimer la tâche" - }, "modal": { - "addMappingField": "ajouter un champ de correspondance", "errors": { "schedule": "Entrez une expression cron valide" }, "hint": { - "path": "Entrer le chemin pour extraire la donnée de la réponse", - "schedule": "Entrez une expression CRON pour planifier la tâche", - "url": "Entrez l'URL après l'hôte pour atteindre la donnée spécifique" + "schedule": "Entrez une expression CRON pour planifier la tâche" }, - "identifier": "Identificateurs uniques", - "mapping": "Correspondance", "placeholder": { - "path": "Entrez le chemin d'accès...", - "schedule": "Entrez l'horaire planifié...", - "url": "Entrer l'URL..." - }, - "switch": "Changer de mode" - }, - "paginator": { - "ariaLabel": "Sélectionez la page de tâches programmées" + "schedule": "Entrez l'horaire planifié..." + } } }, "queryBuilder": { @@ -2228,12 +2208,7 @@ "new": "Nouvel attribut de position" }, "pullJob": { - "edit": "Modifier une tâche planifiée", - "new": "Nouvelle tâche planifiée", - "nextIteration": "Prochaine exécution", - "path": "Chemin", - "schedule": "Horaire planifié", - "url": "Url" + "schedule": "Horaire planifié" }, "record": { "convert": "Convertir", @@ -2444,9 +2419,6 @@ }, "title": "Votre profil" }, - "pullJobs": { - "create": "Créer une tâche planifiée" - }, "referenceData": { "csv": "Fichier CSV d'entrée", "fields": { diff --git a/libs/shared/src/i18n/test.json b/libs/shared/src/i18n/test.json index bc96d1097a..7ee545bee0 100644 --- a/libs/shared/src/i18n/test.json +++ b/libs/shared/src/i18n/test.json @@ -336,11 +336,6 @@ "preview": "******", "previous": "******", "publish": "******", - "pullJob": { - "few": "******", - "none": "******", - "one": "******" - }, "record": { "few": "******", "none": "******", @@ -939,31 +934,16 @@ "title": "******" }, "pullJob": { - "delete": { - "confirmationMessage": "****** {{name}} ******", - "title": "******" - }, "modal": { - "addMappingField": "******", "errors": { "schedule": "******" }, "hint": { - "path": "******", - "schedule": "******", - "url": "******" + "schedule": "******" }, - "identifier": "******", - "mapping": "******", "placeholder": { - "path": "******", - "schedule": "******", - "url": "******" - }, - "switch": "******" - }, - "paginator": { - "ariaLabel": "******" + "schedule": "******" + } } }, "queryBuilder": { @@ -2214,12 +2194,7 @@ "new": "******" }, "pullJob": { - "edit": "******", - "new": "******", - "nextIteration": "******", - "path": "******", - "schedule": "******", - "url": "******" + "schedule": "******" }, "record": { "convert": "******", @@ -2430,9 +2405,6 @@ }, "title": "******" }, - "pullJobs": { - "create": "******" - }, "referenceData": { "csv": "******", "fields": { diff --git a/libs/shared/src/index.ts b/libs/shared/src/index.ts index ea4818238b..a4413f5de0 100644 --- a/libs/shared/src/index.ts +++ b/libs/shared/src/index.ts @@ -48,7 +48,6 @@ export * from './lib/models/subscription.model'; export * from './lib/models/position-attribute-category.model'; export * from './lib/models/position-attribute.model'; export * from './lib/models/api-configuration.model'; -export * from './lib/models/pullJob.model'; export * from './lib/models/layout.model'; export * from './lib/models/aggregation.model'; export * from './lib/models/reference-data.model'; diff --git a/libs/shared/src/lib/models/pullJob.model.ts b/libs/shared/src/lib/models/pullJob.model.ts deleted file mode 100644 index 53acf34c6c..0000000000 --- a/libs/shared/src/lib/models/pullJob.model.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ApiConfiguration } from './api-configuration.model'; -import { status } from './form.model'; -import { Channel } from './channel.model'; -import { Form } from './form.model'; -import { GraphqlNodesResponse } from './graphql-query.model'; - -/** Model for PullJob object. */ -export interface PullJob { - id?: string; - name?: string; - status?: status; - apiConfiguration?: ApiConfiguration; - url?: string; - path?: string; - schedule?: string; - convertTo?: Form; - mapping?: any; - uniqueIdentifiers?: string[]; - channel?: Channel; -} - -/** Model for add pull job graphql mutation response */ -export interface AddPullJobMutationResponse { - addPullJob: PullJob; -} - -/** Model for edit pull job graphql mutation response */ -export interface EditPullJobMutationResponse { - editPullJob: PullJob; -} - -/** Model for delete pull job graphql mutation response */ -export interface DeletePullJobMutationResponse { - deletePullJob: PullJob; -} - -/** Model for pull job nodes graphql query response */ -export interface PullJobsNodesQueryResponse { - pullJobs: GraphqlNodesResponse; -} diff --git a/libs/shared/src/lib/services/auth/auth.service.ts b/libs/shared/src/lib/services/auth/auth.service.ts index da0760ff43..b13c10fe2a 100644 --- a/libs/shared/src/lib/services/auth/auth.service.ts +++ b/libs/shared/src/lib/services/auth/auth.service.ts @@ -48,7 +48,6 @@ type Subjects = | 'DistributionList' | 'Record' | 'Role' - | 'PullJob' | 'Group' | 'CustomNotification' | 'Form'; @@ -381,11 +380,11 @@ export class AuthService { can(['create', 'read', 'update', 'delete'], 'User'); } - // === API Configuration / Pull Job === + // === API Configuration === if (globalPermissions.includes('can_manage_api_configurations')) { can( ['create', 'read', 'update', 'delete'], - ['ApiConfiguration', 'PullJob', 'ReferenceData'] + ['ApiConfiguration', 'ReferenceData'] ); }