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

feat(editor-tools): default tools added to user tools, global "underscore" options in models #94

Merged
merged 8 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
22 changes: 22 additions & 0 deletions migrations/tenant/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

-- Adds "editor_tools" column at "users" if not exists
DO $$
BEGIN
IF NOT EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='users' and column_name='editor_tools')
THEN
ALTER TABLE "public"."users" ADD COLUMN "editor_tools" jsonb;
END IF;
END $$;

-- Removes "extensions" column at "users" if exists
DO $$
BEGIN
IF EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='users' and column_name='extensions')
THEN
ALTER TABLE "public"."users" DROP COLUMN "extensions";
END IF;
END $$;
33 changes: 33 additions & 0 deletions migrations/tenant/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- "editor_tools" table:

-- Rename column "isDefault" to "is_default" if "isDefault" exists and "is_default" not exists
DO $$
BEGIN
IF EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='editor_tools' and column_name='isDefault')
THEN
IF NOT EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='editor_tools' and column_name='is_default')
THEN
ALTER TABLE "public"."editor_tools" RENAME COLUMN "isDefault" TO "is_default";
END IF;
END IF;
END $$;

-- Rename column "exportName" to "export_name" if "exportName" exists and "export_name" not exists
DO $$
BEGIN
IF EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='editor_tools' and column_name='exportName')
THEN
IF NOT EXISTS(SELECT *
FROM information_schema.columns
WHERE table_name='editor_tools' and column_name='export_name')
THEN
ALTER TABLE "public"."editor_tools" RENAME COLUMN "exportName" TO "export_name";
END IF;
END IF;
END $$;
7 changes: 3 additions & 4 deletions src/domain/entities/user.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type UserExtensions from '@domain/entities/userExtensions.js';
import type EditorTool from './editorTools';

/**
* User entity
Expand Down Expand Up @@ -30,8 +30,7 @@ export default interface User {
photo?: string;

/**
* Custom plugins from the marketplace that improve
* editor or notes environment
* Custom plugins ids from the marketplace that improve editor or notes environment
*/
extensions?: UserExtensions;
editorTools?: EditorTool['id'][];
}
19 changes: 0 additions & 19 deletions src/domain/entities/userExtensions.ts

This file was deleted.

9 changes: 8 additions & 1 deletion src/domain/service/editorTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,17 @@ export default class EditorToolsService {
*
* @param editorToolIds - tool ids
*/
public async getToolsByIds(editorToolIds: EditorTool['id'][] ): Promise<EditorTool[] | null> {
public async getToolsByIds(editorToolIds: EditorTool['id'][]): Promise<EditorTool[]> {
return await this.repository.getToolsByIds(editorToolIds);
}

/**
* Get all default tools
*/
public async getDefaultEditorTools(): Promise<EditorTool[]> {
return await this.repository.getDefaultEditorTools();
}

/**
* Adding custom editor tool
*
Expand Down
19 changes: 10 additions & 9 deletions src/domain/service/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,18 @@ export default class UserService {
}

/**
* Get user extensions that contains only editoTools for now
* TODO: Simplify extenisons
* Get user editor tools ids
*
* @param userId - user unique identifier
*/
public async getUserExtensions(userId: User['id']): Promise<User['extensions']> {
public async getUserEditorTools(userId: User['id']): Promise<EditorTool['id'][]> {
const user = await this.getUserById(userId);

return user?.extensions ?? {};
if (user === null) {
throw new Error('User not found');
}

return user.editorTools ?? [];
}

/**
Expand All @@ -65,16 +68,14 @@ export default class UserService {
*/
public async addUserEditorTool({
userId,
editorToolId,
toolId,
}: {
userId: User['id'],
editorToolId: EditorTool['id'],
toolId: EditorTool['id'],
}): Promise<void> {
return await this.repository.addUserEditorTool({
userId,
tool: {
id: editorToolId,
},
toolId,
});
}
}
21 changes: 13 additions & 8 deletions src/presentation/http/router/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const UserRouter: FastifyPluginCallback<UserRouterOptions> = (fastify, opts, don
});

/**
* Get user extensions
* Get user editor tools
*/
fastify.get('/editor-tools', {
config: {
Expand Down Expand Up @@ -93,12 +93,17 @@ const UserRouter: FastifyPluginCallback<UserRouterOptions> = (fastify, opts, don
}, async (request, reply) => {
const userId = request.userId as number;

const userExtensions = await userService.getUserExtensions(userId);
const userEditorToolIds = userExtensions?.editorTools?.map(tools => tools.id) ?? [];
const editorTools = await editorToolsService.getToolsByIds(userEditorToolIds) ?? [];
const userEditorToolIds = await userService.getUserEditorTools(userId);
const defaultEditorTools = await editorToolsService.getDefaultEditorTools();
const uniqueDefaultEditorTools = defaultEditorTools.filter(({ id }) => !userEditorToolIds.includes(id));
const userEditorTools = await editorToolsService.getToolsByIds(userEditorToolIds) ?? [];

// Combine user tools and default tools
// TODO: load tools in notes service
const mergedTools = [...userEditorTools, ...uniqueDefaultEditorTools];

return reply.send({
data: editorTools,
data: mergedTools,
});
});

Expand All @@ -124,16 +129,16 @@ const UserRouter: FastifyPluginCallback<UserRouterOptions> = (fastify, opts, don
},
},
}, async (request, reply) => {
const editorToolId = request.body.toolId;
const toolId = request.body.toolId;
const userId = request.userId as number;

await userService.addUserEditorTool({
userId,
editorToolId,
toolId,
});

return reply.send({
data: editorToolId,
data: toolId,
});
});

Expand Down
7 changes: 7 additions & 0 deletions src/presentation/http/schema/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@ export const UserSchema = {
name: { type: 'string' },
photo: { type: 'string' },
},
editorTools: {
type: 'array',
description: 'List of editor tools ids installed by user from Marketplace',
items: {
type: 'string',
},
},
};
7 changes: 7 additions & 0 deletions src/repository/editorTools.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ export default class EditorToolsRepository {
return tools;
}

/**
* Get all default tools
*/
public async getDefaultEditorTools(): Promise<EditorTool[]> {
return await this.storage.getDefaultEditorTools();
}

/**
* Get all editor tools
*/
Expand Down
34 changes: 25 additions & 9 deletions src/repository/storage/postgres/orm/sequelize/editorTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class EditorToolModel extends Model<InferAttributes<EditorToolModel>, Inf
public declare id: EditorTool['id'];

/**
* Custom name that uses in editor initiazliation. e.g. 'code'
* Custom name that uses in editor initialization. e.g. 'code'
*/
public declare name: EditorTool['name'];

Expand All @@ -31,6 +31,11 @@ export class EditorToolModel extends Model<InferAttributes<EditorToolModel>, Inf
* Editor tool sources
*/
public declare source: EditorTool['source'];

/**
* Applies to user editor tools by default
*/
public declare isDefault: EditorTool['isDefault'];
}

/**
Expand Down Expand Up @@ -85,6 +90,10 @@ export default class UserSequelizeStorage {
type: DataTypes.JSON,
allowNull: false,
},
isDefault: {
type: DataTypes.BOOLEAN,
allowNull: true,
},
}, {
tableName: this.tableName,
sequelize: this.database,
Expand All @@ -101,16 +110,16 @@ export default class UserSequelizeStorage {
title,
exportName,
source,
isDefault,
}: EditorTool): Promise<EditorTool> {
const editorTool = await this.model.create({
return await this.model.create({
id,
name,
title,
exportName,
source,
isDefault,
});

return editorTool;
}

/**
Expand All @@ -119,23 +128,30 @@ export default class UserSequelizeStorage {
* @param editorToolIds - tool ids
*/
public async getToolsByIds(editorToolIds: EditorTool['id'][]): Promise<EditorTool[]> {
const editorTools = await this.model.findAll({
return await this.model.findAll({
where: {
id: {
[Op.in]: editorToolIds,
},
},
});
}

return editorTools;
/**
* Get all default tools
*/
public async getDefaultEditorTools(): Promise<EditorTool[]> {
return await this.model.findAll({
where: {
isDefault: true,
},
});
}

/**
* Get all available editor tools
*/
public async getTools(): Promise<EditorTool[]> {
const editorTools = await EditorToolModel.findAll();

return editorTools;
return await EditorToolModel.findAll();
}
}
6 changes: 6 additions & 0 deletions src/repository/storage/postgres/orm/sequelize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ export default class SequelizeOrm {

this.conn = new Sequelize(this.config.dsn, {
logging: databaseLogger.info.bind(databaseLogger),
define: {
/**
* Use snake_case for fields in db, but camelCase in code
*/
underscored: true,
},
});
}

Expand Down
Loading