Skip to content

Commit

Permalink
Merge pull request #832 from digirati-co-uk/feature/manifest-claim-st…
Browse files Browse the repository at this point in the history
…atus

Fixed manifest claim status when creating a canvas claim
  • Loading branch information
stephenwf authored May 14, 2024
2 parents a9a1f38 + c07eb29 commit e5e324d
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 29 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed
-->

### Fixed
- Adding Manifests to projects with large amounts of content
- Fixed status of Manifest task after submission
- Fixed "Hide completed" on very large collections


## [v2.2.3](https://github.com/digirati-co-uk/madoc-platform/compare/v2.2.2...v2.2.3) - 13/05/2024

### Added
Expand Down
12 changes: 12 additions & 0 deletions services/madoc-ts/src/gateway/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,18 @@ export class ApiClient {
}

async getCollectionById(id: number, page = 0, type?: 'manifest' | 'collection', excluded?: number[]) {
if (excluded && excluded.length) {
return this.request<CollectionFull>(
`/api/madoc/iiif/collections-bulk/${id}${page || type ? `?${stringify({ type, page })}` : ''}`,
{
body: {
excluded,
},
method: 'POST',
}
);
}

return this.request<CollectionFull>(
`/api/madoc/iiif/collections/${id}${page || type || excluded ? `?${stringify({ type, page, excluded })}` : ''}`
);
Expand Down
7 changes: 4 additions & 3 deletions services/madoc-ts/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { getAutomatedUsers } from './routes/manage-site/get-automated-users';
import { createProjectExport } from './routes/projects/create-project-export';
import { getProjectFromTask } from './routes/projects/get-project-from-task';
import { getProjectRawData } from './routes/projects/get-project-raw-data';
import { listProjectEmails } from "./routes/projects/list-project-emails";
import { listProjectEmails } from './routes/projects/list-project-emails';
import { listProjectModelEntityAutocomplete } from './routes/projects/list-project-model-entity-autocomplete';
import { addProjectFeedback, listProjectFeedback, removeProjectFeedback } from './routes/projects/project-feedback';
import {
Expand All @@ -49,7 +49,7 @@ import {
} from './routes/projects/project-updates';
import { svgFromCrowdsourcingTask } from './routes/projects/svg-from-crowdsourcing-task';
import { updateProjectAnnotationStyle } from './routes/projects/update-project-annotation-style';
import { updateProjectBanner } from "./routes/projects/update-project-banner";
import { updateProjectBanner } from './routes/projects/update-project-banner';
import { updateProjectDuration } from './routes/projects/update-project-duration';
import { siteRoot } from './routes/root';
import {
Expand Down Expand Up @@ -164,7 +164,7 @@ import { updateProjectStatus } from './routes/projects/update-project-status';
import { siteManifestTasks } from './routes/site/site-manifest-tasks';
import { getStaticPage, sitePages } from './routes/site/site-pages';
import { listProjectsAutocomplete } from './routes/projects/list-projects-autocomplete';
import { siteProjectMembers } from "./routes/site/site-project-members";
import { siteProjectMembers } from './routes/site/site-project-members';
import { siteProjectRecent } from './routes/site/site-project-recent';
import { siteProjectUpdates } from './routes/site/site-project-updates';
import { siteTaskMetadata } from './routes/site/site-task-metadata';
Expand Down Expand Up @@ -399,6 +399,7 @@ export const router = new TypedRouter({
// Collection API.
'list-collections': [TypedRouter.GET, '/api/madoc/iiif/collections', listCollections],
'get-collection': [TypedRouter.GET, '/api/madoc/iiif/collections/:id', getCollection],
'get-collection-bulk': [TypedRouter.POST, '/api/madoc/iiif/collections-bulk/:id', getCollection],
'create-collection': [
TypedRouter.POST,
'/api/madoc/iiif/collections',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { optionalUserWithScope } from '../../../utility/user-with-scope';

export const getCollectionAutocomplete: RouteMiddleware = async context => {
const { siteId } = optionalUserWithScope(context, ['site.admin']);
const { q, project_id, blacklist_ids, page } = context.query;
const { q, project_id, blacklist_ids = '', page } = context.query;
const { projectId, projectSlug } = parseProjectId(project_id);

const blackListIds = (blacklist_ids || '')
Expand Down
24 changes: 17 additions & 7 deletions services/madoc-ts/src/routes/iiif/collections/get-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ export const getCollection: RouteMiddleware<{ id: number }> = async context => {

const manifestsPerPage = 24;
const excludeManifests = context.query.excluded;
const excluded = Array.isArray(excludeManifests)
let excluded = Array.isArray(excludeManifests)
? excludeManifests
: excludeManifests
? excludeManifests.split(',')
: undefined;
? excludeManifests.split(',')
: undefined;

if (context.requestBody && context.requestBody.excluded) {
excluded = Array.isArray(context.requestBody.excluded)
? context.requestBody.excluded
: context.requestBody.excluded.split(',');
}

const { total = 0 } = (await context.connection.maybeOne(getResourceCount(collectionId, siteId))) || { total: 0 };
const adjustedTotal = excluded ? total - excluded.length : total;
const totalPages = Math.ceil(adjustedTotal / manifestsPerPage) || 1;
Expand Down Expand Up @@ -48,10 +55,13 @@ export const getCollection: RouteMiddleware<{ id: number }> = async context => {

const totals = await context.connection.any(getResourceCount([collectionId], siteId));

const totalsIdMap = totals.reduce((state, row) => {
state[row.resource_id] = row.total;
return state;
}, {} as { [id: string]: number });
const totalsIdMap = totals.reduce(
(state, row) => {
state[row.resource_id] = row.total;
return state;
},
{} as { [id: string]: number }
);

const returnCollections = [];
const collection = table.collections[`${collectionId}`] || {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { userWithScope } from '../../../utility/user-with-scope';

export const getManifestAutocomplete: RouteMiddleware<{}, { blacklist_ids?: number[] }> = async context => {
const { siteId } = userWithScope(context, ['site.admin']);
const { q, project_id, blacklist_ids = [], page } = context.query;
const { q, project_id, blacklist_ids = '', page } = context.query;
const { projectId, projectSlug } = parseProjectId(project_id);

const blackListIds = (blacklist_ids || '')
Expand Down
78 changes: 62 additions & 16 deletions services/madoc-ts/src/routes/projects/create-resource-claim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,10 +361,10 @@ async function upsertCaptureModelForResource(
const mainTarget = claim.canvasId
? { type: 'Canvas', id: `urn:madoc:canvas:${claim.canvasId}` }
: claim.manifestId
? { type: 'Manifest', id: `urn:madoc:manifest:${claim.manifestId}` }
: claim.collectionId
? { type: 'Collection', id: `urn:madoc:collection:${claim.collectionId}` }
: undefined;
? { type: 'Manifest', id: `urn:madoc:manifest:${claim.manifestId}` }
: claim.collectionId
? { type: 'Collection', id: `urn:madoc:collection:${claim.collectionId}` }
: undefined;

if (mainTarget && capture_model_id) {
const existingModel = await userApi.getAllCaptureModels({
Expand Down Expand Up @@ -573,13 +573,10 @@ export const createResourceClaim: RouteMiddleware<{ id: string }, ResourceClaim>

// Check for existing claim
const [canvasClaim, manifestClaim] = await getTaskFromClaim({ userId: userId, parent, claim });

const resourceClaim = manifestOnly && !canvasClaim ? manifestClaim : canvasClaim;

if (resourceClaim) {
if (!resourceClaim.state.revisionId && claim.revisionId) {
if (canvasClaim) {
if (!canvasClaim.state.revisionId && claim.revisionId) {
context.response.body = {
claim: await userApi.updateTask(resourceClaim.id, {
claim: await userApi.updateTask(canvasClaim.id, {
state: {
revisionId: claim.revisionId,
},
Expand All @@ -592,26 +589,26 @@ export const createResourceClaim: RouteMiddleware<{ id: string }, ResourceClaim>

// @todo this should ALWAYS be false.
const revisionDontMatch =
resourceClaim.state.revisionId && claim.revisionId && resourceClaim.state.revisionId !== claim.revisionId;
canvasClaim.state.revisionId && claim.revisionId && canvasClaim.state.revisionId !== claim.revisionId;
const revisionExistsAndMatch = !revisionDontMatch;

if (config.modelPageOptions?.preventMultipleUserSubmissionsPerResource && revisionDontMatch) {
throw new Error('Can only submit one revision per resource');
}

if (revisionExistsAndMatch) {
if (typeof claim.status !== 'undefined' && claim.status !== resourceClaim.status) {
if (typeof claim.status !== 'undefined' && claim.status !== canvasClaim.status) {
if (
config.modelPageOptions?.preventContributionAfterSubmission &&
resourceClaim.status === 2 &&
canvasClaim.status === 2 &&
(claim.status === 0 || claim.status === 1) &&
resourceClaim.state.revisionId
canvasClaim.state.revisionId
) {
throw new Error('Cannot update task in review');
}

context.response.body = {
claim: await userApi.updateTask(resourceClaim.id, {
claim: await userApi.updateTask(canvasClaim.id, {
status: claim.status,
status_text: statusToClaimMap[claim.status as any] || 'in progress',
}),
Expand All @@ -620,14 +617,63 @@ export const createResourceClaim: RouteMiddleware<{ id: string }, ResourceClaim>
}

context.response.body = {
claim: await userApi.getTaskById(resourceClaim.id as string, true, 0, undefined, undefined, true),
claim: await userApi.getTaskById(canvasClaim.id as string, true, 0, undefined, undefined, true),
};
return;
}
}

// Can't claim a canvas is you've already claimed the manifest.
if (manifestClaim) {
if (manifestOnly) {
if (!manifestClaim.state.revisionId && claim.revisionId) {
context.response.body = {
claim: await userApi.updateTask(manifestClaim.id, {
state: {
revisionId: claim.revisionId,
},
status: claim.status,
status_text: statusToClaimMap[claim.status as any] || 'in progress',
}),
};
return;
}

// @todo this should ALWAYS be false.
const revisionDontMatch =
manifestClaim.state.revisionId && claim.revisionId && manifestClaim.state.revisionId !== claim.revisionId;
const revisionExistsAndMatch = !revisionDontMatch;

if (config.modelPageOptions?.preventMultipleUserSubmissionsPerResource && revisionDontMatch) {
throw new Error('Can only submit one revision per resource');
}

if (revisionExistsAndMatch) {
if (typeof claim.status !== 'undefined' && claim.status !== manifestClaim.status) {
if (
config.modelPageOptions?.preventContributionAfterSubmission &&
manifestClaim.status === 2 &&
(claim.status === 0 || claim.status === 1) &&
manifestClaim.state.revisionId
) {
throw new Error('Cannot update task in review');
}

context.response.body = {
claim: await userApi.updateTask(manifestClaim.id, {
status: claim.status,
status_text: statusToClaimMap[claim.status as any] || 'in progress',
}),
};
return;
}

context.response.body = {
claim: await userApi.getTaskById(manifestClaim.id as string, true, 0, undefined, undefined, true),
};
return;
}
}
// The normal path.
context.response.body = {
claim: await userApi.getTaskById(manifestClaim.id as string, true, 0, undefined, undefined, true),
Expand Down
2 changes: 1 addition & 1 deletion services/madoc-ts/src/utility/gen-rsa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ export async function genRSA(force = false) {
// When this function is called dynamically, it's likely to cause some disruption.
// And all users will be logged out. This is only temporary, the service will be
// restarted (without downtime)
require('../gateway/api.server').api.invalidateJwt();
(await import('../gateway/api.server')).api.invalidateJwt();
}

0 comments on commit e5e324d

Please sign in to comment.