Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use GraphQL mutations for FLEx metadata updates #973

Merged
merged 4 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions backend/LexBoxApi/Controllers/ProjectController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,26 +232,6 @@ private async Task StreamHttpResponse(HttpContent hgResult)
await hgResult.CopyToAsync(writer.AsStream());
}

[HttpPost("updateLexEntryCount/{code}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task<ActionResult<int>> UpdateLexEntryCount(string code)
{
var result = await projectService.UpdateLexEntryCount(code);
return result is null ? NotFound() : result;
}

[HttpPost("updateLanguageList/{code}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task UpdateLanguageList(string code)
{
var projectId = await projectService.LookupProjectId(code);
await projectService.UpdateProjectLangTags(projectId);
}

[HttpPost("updateMissingLanguageList")]
public async Task<ActionResult<string[]>> UpdateMissingLanguageList(int limit = 10)
rmunn marked this conversation as resolved.
Show resolved Hide resolved
{
Expand Down
58 changes: 58 additions & 0 deletions backend/LexBoxApi/GraphQL/ProjectMutations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,64 @@ public async Task<IQueryable<Project>> SetRetentionPolicy(
return dbContext.Projects.Where(p => p.Id == input.ProjectId);
}

[Error<NotFoundException>]
[Error<DbError>]
[Error<UnauthorizedAccessException>]
[UseMutationConvention]
[UseFirstOrDefault]
[UseProjection]
public async Task<IQueryable<Project>> UpdateProjectLexEntryCount(string code,
IPermissionService permissionService,
[Service] ProjectService projectService,
LexBoxDbContext dbContext)
{
var projectId = await projectService.LookupProjectId(code);
await permissionService.AssertCanManageProject(projectId);
var project = await dbContext.Projects.FindAsync(projectId);
NotFoundException.ThrowIfNull(project);
var result = await projectService.UpdateLexEntryCount(code);
return dbContext.Projects.Where(p => p.Id == projectId);
}

[Error<NotFoundException>]
[Error<DbError>]
[Error<UnauthorizedAccessException>]
[UseMutationConvention]
[UseFirstOrDefault]
[UseProjection]
public async Task<IQueryable<Project>> UpdateProjectLanguageList(string code,
IPermissionService permissionService,
[Service] ProjectService projectService,
LexBoxDbContext dbContext)
{
var projectId = await projectService.LookupProjectId(code);
await permissionService.AssertCanManageProject(projectId);
var project = await dbContext.Projects.FindAsync(projectId);
NotFoundException.ThrowIfNull(project);
await projectService.UpdateProjectLangTags(projectId);
return dbContext.Projects.Where(p => p.Id == projectId);
}

[Error<NotFoundException>]
[Error<DbError>]
[Error<UnauthorizedAccessException>]
[UseMutationConvention]
[UseFirstOrDefault]
[UseProjection]
public async Task<IQueryable<Project>> UpdateLangProjectId(string code,
IPermissionService permissionService,
[Service] ProjectService projectService,
[Service] IHgService hgService,
LexBoxDbContext dbContext)
{
var projectId = await projectService.LookupProjectId(code);
await permissionService.AssertCanManageProject(projectId);
var project = await dbContext.Projects.FindAsync(projectId);
NotFoundException.ThrowIfNull(project);
await hgService.GetProjectIdOfFlexProject(code);
return dbContext.Projects.Where(p => p.Id == projectId);
}

[Error<NotFoundException>]
[Error<LastMemberCantLeaveException>]
[UseMutationConvention]
Expand Down
38 changes: 37 additions & 1 deletion frontend/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ type Mutation {
changeProjectDescription(input: ChangeProjectDescriptionInput!): ChangeProjectDescriptionPayload!
setProjectConfidentiality(input: SetProjectConfidentialityInput!): SetProjectConfidentialityPayload!
setRetentionPolicy(input: SetRetentionPolicyInput!): SetRetentionPolicyPayload!
updateProjectLexEntryCount(input: UpdateProjectLexEntryCountInput!): UpdateProjectLexEntryCountPayload!
updateProjectLanguageList(input: UpdateProjectLanguageListInput!): UpdateProjectLanguageListPayload!
updateLangProjectId(input: UpdateLangProjectIdInput!): UpdateLangProjectIdPayload!
leaveProject(input: LeaveProjectInput!): LeaveProjectPayload!
removeProjectMember(input: RemoveProjectMemberInput!): RemoveProjectMemberPayload!
deleteDraftProject(input: DeleteDraftProjectInput!): DeleteDraftProjectPayload! @authorize(policy: "AdminRequiredPolicy")
Expand Down Expand Up @@ -466,6 +469,21 @@ type UniqueValueError implements Error {
message: String!
}

type UpdateLangProjectIdPayload {
project: Project
errors: [UpdateLangProjectIdError!]
}

type UpdateProjectLanguageListPayload {
project: Project
errors: [UpdateProjectLanguageListError!]
}

type UpdateProjectLexEntryCountPayload {
project: Project
errors: [UpdateProjectLexEntryCountError!]
}

type User {
email: String @authorize(policy: "AdminRequiredPolicy")
emailVerified: Boolean! @authorize(policy: "AdminRequiredPolicy")
Expand Down Expand Up @@ -550,6 +568,12 @@ union SetUserLockedError = NotFoundError

union SoftDeleteProjectError = NotFoundError | DbError

union UpdateLangProjectIdError = NotFoundError | DbError | UnauthorizedAccessError

union UpdateProjectLanguageListError = NotFoundError | DbError | UnauthorizedAccessError

union UpdateProjectLexEntryCountError = NotFoundError | DbError | UnauthorizedAccessError

input AddProjectMemberInput {
projectId: UUID!
usernameOrEmail: String!
Expand Down Expand Up @@ -983,6 +1007,18 @@ input StringOperationFilterInput {
ieq: String
}

input UpdateLangProjectIdInput {
code: String!
}

input UpdateProjectLanguageListInput {
code: String!
}

input UpdateProjectLexEntryCountInput {
code: String!
}

input UserFilterInput {
and: [UserFilterInput!]
or: [UserFilterInput!]
Expand Down Expand Up @@ -1133,4 +1169,4 @@ scalar UUID

scalar timestamptz @specifiedBy(url: "https:\/\/www.graphql-scalars.com\/date-time")

scalar uuid
scalar uuid
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
_deleteProjectUser,
_leaveProject,
_removeProjectFromOrg,
_updateProjectLanguageList,
_updateProjectLexEntryCount,
type ProjectUser,
} from './+page';
import AddProjectMember from './AddProjectMember.svelte';
Expand All @@ -26,7 +28,7 @@
import Dropdown from '$lib/components/Dropdown.svelte';
import ConfirmDeleteModal from '$lib/components/modals/ConfirmDeleteModal.svelte';
import {_deleteProject} from '$lib/gql/mutations';
import { goto, invalidate } from '$app/navigation';
import { goto } from '$app/navigation';
import MoreSettings from '$lib/components/MoreSettings.svelte';
import { AdminContent, PageBreadcrumb } from '$lib/layout';
import Markdown from 'svelte-exmarkdown';
Expand Down Expand Up @@ -65,7 +67,6 @@
return a.user.name.localeCompare(b.user.name);
});

let lexEntryCount: number | string | null | undefined = undefined;
$: lexEntryCount = project.flexProjectMetadata?.lexEntryCount;
$: vernacularLangTags = project.flexProjectMetadata?.writingSystems?.vernacularWss;
$: analysisLangTags = project.flexProjectMetadata?.writingSystems?.analysisWss;
Expand All @@ -77,17 +78,15 @@
let loadingEntryCount = false;
async function updateEntryCount(): Promise<void> {
loadingEntryCount = true;
const response = await fetch(`/api/project/updateLexEntryCount/${project.code}`, {method: 'POST'});
lexEntryCount = await response.text();
await _updateProjectLexEntryCount(project.code);
loadingEntryCount = false;
}

let loadingLanguageList = false;
async function updateLanguageList(): Promise<void> {
loadingLanguageList = true;
await fetch(`/api/project/updateLanguageList/${project.code}`, {method: 'POST'});
await _updateProjectLanguageList(project.code);
loadingLanguageList = false;
await invalidate(`project:${project.code}`);
}

let resetProjectModal: ResetProjectModal;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import type {
SetProjectConfidentialityMutation,
SetRetentionPolicyInput,
SetRetentionPolicyMutation,
UpdateLangProjectIdMutation,
UpdateProjectLanguageListMutation,
UpdateProjectLexEntryCountMutation,
} from '$lib/gql/types';
import { getClient, graphql } from '$lib/gql';

Expand Down Expand Up @@ -274,6 +277,98 @@ export async function _bulkAddProjectMembers(input: BulkAddProjectMembersInput):
return result;
}

export async function _updateProjectLexEntryCount(code: string): $OpResult<UpdateProjectLexEntryCountMutation> {
//language=GraphQL
const result = await getClient()
.mutation(
graphql(`
mutation UpdateProjectLexEntryCount($input: UpdateProjectLexEntryCountInput!) {
updateProjectLexEntryCount(input: $input) {
project {
id
flexProjectMetadata {
lexEntryCount
}
}
errors {
__typename
... on Error {
message
}
}
}
}
`),
{ input: { code } },
);
return result;
}

export async function _updateLangProjectId(code: string): $OpResult<UpdateLangProjectIdMutation> {
//language=GraphQL
const result = await getClient()
.mutation(
graphql(`
mutation UpdateLangProjectId($input: UpdateLangProjectIdInput!) {
updateLangProjectId(input: $input) {
project {
id
flexProjectMetadata {
langProjectId
}
}
errors {
__typename
... on Error {
message
}
}
}
}
`),
{ input: { code } },
);
return result;
}

export async function _updateProjectLanguageList(code: string): $OpResult<UpdateProjectLanguageListMutation> {
//language=GraphQL
const result = await getClient()
.mutation(
graphql(`
mutation UpdateProjectLanguageList($input: UpdateProjectLanguageListInput!) {
updateProjectLanguageList(input: $input) {
project {
id
flexProjectMetadata {
writingSystems {
analysisWss {
tag
isActive
isDefault
}
vernacularWss {
tag
isActive
isDefault
}
}
}
}
errors {
__typename
... on Error {
message
}
}
}
}
`),
{ input: { code } },
);
return result;
}

export async function _changeProjectMemberRole(input: ChangeProjectMemberRoleInput): $OpResult<ChangeProjectMemberRoleMutation> {
//language=GraphQL
const result = await getClient()
Expand Down
Loading