Skip to content

Commit

Permalink
Improve jobs preview
Browse files Browse the repository at this point in the history
  • Loading branch information
ggodlewski committed Dec 19, 2023
1 parent fd56ff8 commit 69c8a75
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 63 deletions.
50 changes: 23 additions & 27 deletions apps/ui/src/components/ChangesViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
Jobs
</div>
<div class="card-body">

<div class="row py-1 align-items-center" v-if="last_job.dateStr">
<div class="col-8">
<span v-if="last_job.kind === 'full'" class="fw-bold">Last full sync </span>
Expand All @@ -64,40 +63,26 @@
</div>
</div>

<table class="table table-bordered jobs-list mt-3" v-if="active_jobs.length > 0">
<table class="table table-bordered jobs-list mt-3">
<thead>
<th>Job</th>
<th>Progress</th>
<tr>
<th>Job</th>
<th>Started</th>
<th>Finished</th>
</tr>
</thead>
<tbody>
<tr v-for="(job, idx) of active_jobs" :key="idx" class="jobs-list__item" :class="{ active: 'running' === job.state }">

<tbody v-if="active_jobs_reverse.length > 0">
<tr v-for="(job, idx) of active_jobs_reverse" :key="idx" class="jobs-list__item" :class="{ active: 'running' === job.state }">
<td>{{ job.title }}</td>
<td>{{ job.startedStr || job.state }}</td>
<td>
<span v-if="job.progress && job.progress.total > job.progress.completed">&nbsp;{{ job.progress.completed }} / {{ job.progress.total }}</span>
<span v-else>{{ job.state }}</span>
<a v-if="job.id && job.started" class="btn float-end" :href="'#drive_logs:job-' + job.id" @click.prevent="showLogs(job)">Logs</a>
</td>
</tr>
</tbody>
</table>

<div v-if="active_jobs.length === 0" class="mt-3">
No active jobs
</div>

</div>
</div>

<div class="card mt-3" v-if="archive.length > 0">
<div class="card-header">
Jobs done
</div>
<div class="card-body">
<table class="table table-bordered jobs-list mt-3">
<thead>
<th>Job</th>
<th>Started</th>
<th>Finished</th>
</thead>
<tbody>
<tr v-for="(job, idx) of archive" :key="idx" class="jobs-list__item" :class="{ active: 'running' === job.state, 'text-danger': 'failed' === job.state, 'text-warning': job.progress && job.progress.warnings > 0 }">
<td>{{ job.title }}</td>
Expand All @@ -111,7 +96,6 @@
</tbody>
</table>
</div>

</div>

</div>
Expand All @@ -133,6 +117,18 @@ export default {
},
components: {StatusToolBar},
computed: {
active_jobs_reverse() {
return [].concat(this.active_jobs)
.map(a => {
return {
...a,
finishedStr: a.finished ? new Date(a.finished).toISOString() : undefined,
startedStr: a.started ? new Date(a.started).toISOString() : undefined,
durationStr: a.started && a.finished ? Math.round((+new Date(a.finished) - +new Date(a.started)) / 100)/10 + 's' : undefined
};
})
.reverse();
},
fileChanges() {
return this.changes.filter(change => change.mimeType !== 'application/vnd.google-apps.folder');
},
Expand Down
31 changes: 28 additions & 3 deletions apps/ui/src/components/JobLogsViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,22 @@ export default {
},
contentDir: {
type: String
},
autoRefresh: {
type: Boolean
}
},
data() {
return {
errorsOnly: false,
logs: []
logs: [],
intervalHandle: null
};
},
computed: {
currentJob() {
return this.$root.jobs.find(job => 'job-' + job.id === this.jobId);
},
absPath() {
return '/drive/' + this.driveId + this.contentDir;
},
Expand All @@ -63,13 +70,19 @@ export default {
}
const jobId = this.jobId.substring('job-'.length);
const response = await this.authenticatedClient.fetchApi(`/api/logs/${this.driveId}?order=asc&jobId=` + (jobId));
const response = await this.authenticatedClient.fetchApi(`/api/logs/${this.driveId}?order=asc&jobId=` + (jobId) + '&offset=' + this.logs.length);
const logs = await response.json();
if (this.intervalHandle && this.currentJob && this.currentJob.finished) {
clearInterval(this.intervalHandle);
this.intervalHandle = null;
}
if (logs.length === 0) {
return;
}
this.logs = logs;
this.logs = this.logs.concat(logs);
if (logs.length > 0) {
this.handleScroll();
Expand Down Expand Up @@ -139,6 +152,18 @@ export default {
this.handleScroll();
// Prism.highlightElement(this.$refs.code);
if (!this.intervalHandle && this.currentJob && !this.currentJob.finished) {
this.intervalHandle = setInterval(() => {
this.fetch();
}, 1000);
}
},
beforeUnmount() {
if (!this.intervalHandle) {
return;
}
clearInterval(this.intervalHandle);
this.intervalHandle = null;
}
};
</script>
57 changes: 29 additions & 28 deletions src/containers/server/ServerContainer.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import {Container, ContainerConfig, ContainerEngine} from '../../ContainerEngine';
import type {Express, NextFunction, Request, Response} from 'express';
import express from 'express';
import http from 'http';
import {WebSocketServer} from 'ws';
import winston from 'winston';
import path from 'path';
import {FileId} from '../../model/model';
import {saveRunningInstance} from './loadRunningInstance';
import {urlToFolderId} from '../../utils/idParsers';
import {GoogleDriveService} from '../../google/GoogleDriveService';
import {FolderRegistryContainer} from '../folder_registry/FolderRegistryContainer';
import {DriveJobsMap, initJob, JobManagerContainer} from '../job/JobManagerContainer';
import {fileURLToPath} from 'url';
import GitController from './routes/GitController';
import FolderController from './routes/FolderController';
import {ConfigController} from './routes/ConfigController';
import {DriveController} from './routes/DriveController';
import {BackLinksController} from './routes/BackLinksController';
import {GoogleDriveController} from './routes/GoogleDriveController';
import {LogsController} from './routes/LogsController';
import {PreviewController} from './routes/PreviewController';
import cookieParser from 'cookie-parser';
import rateLimit from 'express-rate-limit';
import compress from 'compression';

import {SocketManager} from './SocketManager';
import {Container, ContainerConfig, ContainerEngine} from '../../ContainerEngine.ts';
import {FileId} from '../../model/model.ts';
import {saveRunningInstance} from './loadRunningInstance.ts';
import {urlToFolderId} from '../../utils/idParsers.ts';
import {GoogleDriveService} from '../../google/GoogleDriveService.ts';
import {FolderRegistryContainer} from '../folder_registry/FolderRegistryContainer.ts';
import {DriveJobsMap, initJob, JobManagerContainer} from '../job/JobManagerContainer.ts';
import GitController from './routes/GitController.ts';
import FolderController from './routes/FolderController.ts';
import {ConfigController} from './routes/ConfigController.ts';
import {DriveController} from './routes/DriveController.ts';
import {BackLinksController} from './routes/BackLinksController.ts';
import {GoogleDriveController} from './routes/GoogleDriveController.ts';
import {LogsController} from './routes/LogsController.ts';
import {PreviewController} from './routes/PreviewController.ts';

import {SocketManager} from './SocketManager.ts';

import {
authenticate,
Expand All @@ -32,18 +34,17 @@ import {
authenticateOptionally,
validateGetAuthState,
handleDriveUiInstall, handleShare, handlePopupClose, redirError
} from './auth';
import {filterParams} from '../../google/driveFetch';
import {SearchController} from './routes/SearchController';
import {DriveUiController} from './routes/DriveUiController';
import {GoogleApiContainer} from '../google_api/GoogleApiContainer';
import {UserAuthClient} from '../../google/AuthClient';
import {getTokenInfo} from '../../google/GoogleAuthService';
import {GoogleTreeProcessor} from '../google_folder/GoogleTreeProcessor';
import compress from 'compression';
import {initStaticDistPages} from './static';
import {initUiServer} from './vuejs';
import {initErrorHandler} from './error';
} from './auth.ts';
import {filterParams} from '../../google/driveFetch.ts';
import {SearchController} from './routes/SearchController.ts';
import {DriveUiController} from './routes/DriveUiController.ts';
import {GoogleApiContainer} from '../google_api/GoogleApiContainer.ts';
import {UserAuthClient} from '../../google/AuthClient.ts';
import {getTokenInfo} from '../../google/GoogleAuthService.ts';
import {GoogleTreeProcessor} from '../google_folder/GoogleTreeProcessor.ts';
import {initStaticDistPages} from './static.ts';
import {initUiServer} from './vuejs.ts';
import {initErrorHandler} from './error.ts';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand Down
11 changes: 6 additions & 5 deletions src/containers/server/routes/LogsController.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Controller, RouteGet, RouteParamPath, RouteParamQuery} from './Controller';
import {Logger, QueryOptions} from 'winston';
import {Controller, RouteGet, RouteParamPath, RouteParamQuery} from './Controller.ts';
import {Logger} from 'winston';

export class LogsController extends Controller {

Expand All @@ -12,7 +12,8 @@ export class LogsController extends Controller {
@RouteParamQuery('from') from?: number,
@RouteParamQuery('until') until?: number,
@RouteParamQuery('jobId') jobId?: string,
@RouteParamQuery('order') order?: 'desc' | 'asc'
@RouteParamQuery('order') order?: 'desc' | 'asc',
@RouteParamQuery('offset') offset?: number
) {

if (!until && !from) {
Expand Down Expand Up @@ -44,10 +45,10 @@ export class LogsController extends Controller {
}));

if (jobId) {
return results['jobLogFile'];
return results['jobLogFile'].slice(offset || 0);
}

return results['dailyRotateFile'].reverse();
return results['dailyRotateFile'].reverse().slice(offset || 0);
}

}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"module": "node16",
"moduleResolution": "node16",
"target": "es2022",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"sourceMap": true,
Expand Down

0 comments on commit 69c8a75

Please sign in to comment.