Skip to content

Commit

Permalink
added importer to organization settings
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregor Vostrak authored and Gregor Vostrak committed Apr 13, 2024
1 parent 8d46b3c commit ac0485b
Show file tree
Hide file tree
Showing 8 changed files with 442 additions and 24 deletions.
11 changes: 10 additions & 1 deletion app/Http/Controllers/Api/V1/ImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,25 @@ class ImportController extends Controller
* Import data into the organization
*
* @throws AuthorizationException
*
* @operationId importData
*/
public function import(Organization $organization, ImportRequest $request, ImportService $importService): JsonResponse
{
$this->checkPermission($organization, 'import');

try {
$importData = base64_decode($request->input('data'), true);
if ($importData === false) {
return new JsonResponse([
'message' => 'Invalid base64 encoded data',
], 400);
}

$report = $importService->import(
$organization,
$request->input('type'),
$request->input('data')
$importData
);

return new JsonResponse([
Expand Down
6 changes: 3 additions & 3 deletions e2e/organization.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ test('test that organization name can be updated', async ({ page }) => {
await page.getByLabel('Team Name').fill('NEW ORG NAME');
await page.getByLabel('Team Name').press('Enter');
await page.getByLabel('Team Name').press('Meta+r');
await expect(page.locator('[data-testid="organization_switcher"]:visible')).toContainText(
'NEW ORG NAME'
);
await expect(
page.locator('[data-testid="organization_switcher"]:visible')
).toContainText('NEW ORG NAME');
});

test('test that new manager can be invited', async ({ page }) => {
Expand Down
280 changes: 271 additions & 9 deletions openapi.json.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,44 @@ const ClientResource = z
})
.passthrough();
const ClientCollection = z.array(ClientResource);
const v1_import_import_Body = z
const importData_Body = z
.object({ type: z.string(), data: z.string() })
.passthrough();
const InvitationResource = z
.object({ id: z.string(), user_id: z.string(), name: z.string() })
.passthrough();
const Role = z.enum(['owner', 'admin', 'manager', 'employee', 'placeholder']);
const invite_Body = z
.object({ email: z.string().email(), role: Role })
.passthrough();
const MemberPivotResource = z
.object({
id: z.string(),
user_id: z.string(),
name: z.string(),
email: z.string(),
role: z.string(),
is_placeholder: z.boolean(),
billable_rate: z.union([z.number(), z.null()]),
})
.passthrough();
const updateMember_Body = z
.object({
billable_rate: z.union([z.number(), z.null()]).optional(),
role: Role,
})
.passthrough();
const MemberResource = z
.object({
id: z.string(),
user_id: z.string(),
name: z.string(),
email: z.string(),
role: z.string(),
is_placeholder: z.boolean(),
billable_rate: z.union([z.number(), z.null()]),
})
.passthrough();
const MemberCollection = z.array(MemberResource);
const OrganizationResource = z
.object({
id: z.string(),
Expand Down Expand Up @@ -137,9 +161,13 @@ const updateTimeEntry_Body = z
export const schemas = {
ClientResource,
ClientCollection,
v1_import_import_Body,
importData_Body,
InvitationResource,
Role,
invite_Body,
MemberPivotResource,
updateMember_Body,
MemberResource,
MemberCollection,
OrganizationResource,
v1_organizations_update_Body,
ProjectResource,
Expand Down Expand Up @@ -378,13 +406,13 @@ const endpoints = makeApi([
{
method: 'post',
path: '/v1/organizations/:organization/import',
alias: 'v1.import.import',
alias: 'importData',
requestFormat: 'json',
parameters: [
{
name: 'body',
type: 'Body',
schema: v1_import_import_Body,
schema: importData_Body,
},
{
name: 'organization',
Expand Down Expand Up @@ -445,6 +473,115 @@ const endpoints = makeApi([
},
],
},
{
method: 'get',
path: '/v1/organizations/:organization/invitations',
alias: 'getInvitations',
requestFormat: 'json',
parameters: [
{
name: 'organization',
type: 'Path',
schema: z.string().uuid(),
},
],
response: z
.object({
data: z.array(InvitationResource),
links: z
.object({
first: z.union([z.string(), z.null()]),
last: z.union([z.string(), z.null()]),
prev: z.union([z.string(), z.null()]),
next: z.union([z.string(), z.null()]),
})
.passthrough(),
meta: z
.object({
current_page: z.number().int(),
from: z.union([z.number(), z.null()]),
last_page: z.number().int(),
links: z.array(
z
.object({
url: z.union([z.string(), z.null()]),
label: z.string(),
active: z.boolean(),
})
.passthrough()
),
path: z.union([z.string(), z.null()]),
per_page: z.number().int(),
to: z.union([z.number(), z.null()]),
total: z.number().int(),
})
.passthrough(),
})
.passthrough(),
errors: [
{
status: 403,
description: `Authorization error`,
schema: z.object({ message: z.string() }).passthrough(),
},
{
status: 404,
description: `Not found`,
schema: z.object({ message: z.string() }).passthrough(),
},
{
status: 422,
description: `Validation error`,
schema: z
.object({
message: z.string(),
errors: z.record(z.array(z.string())),
})
.passthrough(),
},
],
},
{
method: 'post',
path: '/v1/organizations/:organization/invitations',
alias: 'invite',
requestFormat: 'json',
parameters: [
{
name: 'body',
type: 'Body',
schema: invite_Body,
},
{
name: 'organization',
type: 'Path',
schema: z.string().uuid(),
},
],
response: z.null(),
errors: [
{
status: 403,
description: `Authorization error`,
schema: z.object({ message: z.string() }).passthrough(),
},
{
status: 404,
description: `Not found`,
schema: z.object({ message: z.string() }).passthrough(),
},
{
status: 422,
description: `Validation error`,
schema: z
.object({
message: z.string(),
errors: z.record(z.array(z.string())),
})
.passthrough(),
},
],
},
{
method: 'get',
path: '/v1/organizations/:organization/members',
Expand All @@ -457,7 +594,85 @@ const endpoints = makeApi([
schema: z.string().uuid(),
},
],
response: z.object({ data: MemberCollection }).passthrough(),
response: z
.object({
data: z.array(MemberPivotResource),
links: z
.object({
first: z.union([z.string(), z.null()]),
last: z.union([z.string(), z.null()]),
prev: z.union([z.string(), z.null()]),
next: z.union([z.string(), z.null()]),
})
.passthrough(),
meta: z
.object({
current_page: z.number().int(),
from: z.union([z.number(), z.null()]),
last_page: z.number().int(),
links: z.array(
z
.object({
url: z.union([z.string(), z.null()]),
label: z.string(),
active: z.boolean(),
})
.passthrough()
),
path: z.union([z.string(), z.null()]),
per_page: z.number().int(),
to: z.union([z.number(), z.null()]),
total: z.number().int(),
})
.passthrough(),
})
.passthrough(),
errors: [
{
status: 403,
description: `Authorization error`,
schema: z.object({ message: z.string() }).passthrough(),
},
{
status: 404,
description: `Not found`,
schema: z.object({ message: z.string() }).passthrough(),
},
{
status: 422,
description: `Validation error`,
schema: z
.object({
message: z.string(),
errors: z.record(z.array(z.string())),
})
.passthrough(),
},
],
},
{
method: 'put',
path: '/v1/organizations/:organization/members/:membership',
alias: 'updateMember',
requestFormat: 'json',
parameters: [
{
name: 'body',
type: 'Body',
schema: updateMember_Body,
},
{
name: 'organization',
type: 'Path',
schema: z.string().uuid(),
},
{
name: 'membership',
type: 'Path',
schema: z.string().uuid(),
},
],
response: z.object({ data: MemberResource }).passthrough(),
errors: [
{
status: 403,
Expand All @@ -481,9 +696,45 @@ const endpoints = makeApi([
},
],
},
{
method: 'delete',
path: '/v1/organizations/:organization/members/:membership',
alias: 'removeMember',
requestFormat: 'json',
parameters: [
{
name: 'body',
type: 'Body',
schema: z.object({}).partial().passthrough(),
},
{
name: 'organization',
type: 'Path',
schema: z.string().uuid(),
},
{
name: 'membership',
type: 'Path',
schema: z.string().uuid(),
},
],
response: z.null(),
errors: [
{
status: 403,
description: `Authorization error`,
schema: z.object({ message: z.string() }).passthrough(),
},
{
status: 404,
description: `Not found`,
schema: z.object({ message: z.string() }).passthrough(),
},
],
},
{
method: 'post',
path: '/v1/organizations/:organization/members/:user/invite-placeholder',
path: '/v1/organizations/:organization/members/:membership/invite-placeholder',
alias: 'invitePlaceholder',
requestFormat: 'json',
parameters: [
Expand All @@ -498,7 +749,7 @@ const endpoints = makeApi([
schema: z.string().uuid(),
},
{
name: 'user',
name: 'membership',
type: 'Path',
schema: z.string().uuid(),
},
Expand Down Expand Up @@ -909,6 +1160,17 @@ const endpoints = makeApi([
],
response: z.object({ data: ProjectMemberResource }).passthrough(),
errors: [
{
status: 400,
description: `API exception`,
schema: z
.object({
error: z.boolean(),
key: z.string(),
message: z.string(),
})
.passthrough(),
},
{
status: 403,
description: `Authorization error`,
Expand Down
Loading

0 comments on commit ac0485b

Please sign in to comment.