mirror of
https://github.com/colanode/colanode.git
synced 2025-12-28 16:06:37 +01:00
Collaborator improvements for nodes
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes, ViewNodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes, ViewNodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { compareString } from '@/lib/utils';
|
||||
@@ -52,6 +52,10 @@ export class BoardViewCreateMutationHandler
|
||||
attributesMap.set('index', generateNodeIndex(maxIndex, null));
|
||||
attributesMap.set('name', input.name);
|
||||
attributesMap.set('groupBy', input.groupBy);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes, ViewNodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes, ViewNodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { compareString } from '@/lib/utils';
|
||||
@@ -52,6 +52,10 @@ export class CalendarViewCreateMutationHandler
|
||||
attributesMap.set('index', generateNodeIndex(maxIndex, null));
|
||||
attributesMap.set('name', input.name);
|
||||
attributesMap.set('groupBy', input.groupBy);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { compareString } from '@/lib/utils';
|
||||
@@ -46,6 +46,10 @@ export class ChannelCreateMutationHandler
|
||||
attributesMap.set('parentId', input.spaceId);
|
||||
attributesMap.set('index', generateNodeIndex(maxIndex, null));
|
||||
attributesMap.set('name', input.name);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { MutationHandler, MutationResult } from '@/operations/mutations';
|
||||
import { ChatCreateMutationInput } from '@/operations/mutations/chat-create';
|
||||
@@ -55,8 +55,8 @@ export class ChatCreateMutationHandler
|
||||
attributesMap.set('collaborators', new Y.Map());
|
||||
|
||||
const collaboratorsMap = attributesMap.get('collaborators') as Y.Map<any>;
|
||||
collaboratorsMap.set(input.userId, 'owner');
|
||||
collaboratorsMap.set(input.otherUserId, 'owner');
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
collaboratorsMap.set(input.otherUserId, NodeRole.Owner);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { compareString } from '@/lib/utils';
|
||||
@@ -47,6 +47,10 @@ export class DatabaseCreateMutationHandler
|
||||
attributesMap.set('parentId', input.spaceId);
|
||||
attributesMap.set('index', generateNodeIndex(maxIndex, null));
|
||||
attributesMap.set('name', input.name);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const databaseAttributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -3,7 +3,7 @@ import { databaseManager } from '@/main/data/database-manager';
|
||||
import { MutationHandler, MutationResult } from '@/operations/mutations';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { FileCreateMutationInput } from '@/operations/mutations/file-create';
|
||||
import { NodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { fileManager } from '@/main/file-manager';
|
||||
import { LocalCreateNodeChangeData } from '@/types/sync';
|
||||
import { fromUint8Array } from 'js-base64';
|
||||
@@ -46,6 +46,10 @@ export class FileCreateMutationHandler
|
||||
attributesMap.set('extension', metadata.extension);
|
||||
attributesMap.set('size', metadata.size);
|
||||
attributesMap.set('mimeType', metadata.mimeType);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { compareString } from '@/lib/utils';
|
||||
@@ -51,6 +51,10 @@ export class FolderCreateMutationHandler
|
||||
attributesMap.set('parentId', input.parentId);
|
||||
attributesMap.set('index', index);
|
||||
attributesMap.set('name', input.name);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { EditorNodeTypes, NodeTypes } from '@/lib/constants';
|
||||
import { EditorNodeTypes, NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import {
|
||||
MutationChange,
|
||||
@@ -79,6 +79,10 @@ export class MessageCreateMutationHandler
|
||||
fileAttributesMap.set('extension', metadata.extension);
|
||||
fileAttributesMap.set('size', metadata.size);
|
||||
fileAttributesMap.set('mimeType', metadata.mimeType);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
fileAttributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const fileAttributes = JSON.stringify(fileAttributesMap.toJSON());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { compareString } from '@/lib/utils';
|
||||
@@ -51,6 +51,10 @@ export class PageCreateMutationHandler
|
||||
attributesMap.set('parentId', input.parentId);
|
||||
attributesMap.set('index', index);
|
||||
attributesMap.set('name', input.name);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { MutationHandler, MutationResult } from '@/operations/mutations';
|
||||
@@ -46,6 +46,10 @@ export class RecordCreateMutationHandler
|
||||
attributesMap.set('type', NodeTypes.Record);
|
||||
attributesMap.set('parentId', input.databaseId);
|
||||
attributesMap.set('index', generateNodeIndex(maxIndex, null));
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -4,7 +4,7 @@ import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { MutationHandler, MutationResult } from '@/operations/mutations';
|
||||
import { SpaceCreateMutationInput } from '@/operations/mutations/space-create';
|
||||
import * as Y from 'yjs';
|
||||
import { NodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes } from '@/lib/constants';
|
||||
import { fromUint8Array } from 'js-base64';
|
||||
import { LocalCreateNodeChangeData } from '@/types/sync';
|
||||
|
||||
@@ -35,15 +35,10 @@ export class SpaceCreateMutationHandler
|
||||
spaceAttributesMap.set('description', input.description);
|
||||
}
|
||||
|
||||
if (!spaceAttributesMap.has('collaborators')) {
|
||||
spaceAttributesMap.set('collaborators', new Y.Map<string>());
|
||||
}
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
spaceAttributesMap.set('collaborators', collaboratorsMap);
|
||||
|
||||
const collaboratorsMap = spaceAttributesMap.get(
|
||||
'collaborators',
|
||||
) as Y.Map<string>;
|
||||
|
||||
collaboratorsMap.set(input.userId, 'owner');
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
});
|
||||
|
||||
const spaceAttributes = JSON.stringify(spaceAttributesMap.toJSON());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Y from 'yjs';
|
||||
import { databaseManager } from '@/main/data/database-manager';
|
||||
import { NodeTypes, ViewNodeTypes } from '@/lib/constants';
|
||||
import { NodeRole, NodeTypes, ViewNodeTypes } from '@/lib/constants';
|
||||
import { generateId, IdType } from '@/lib/id';
|
||||
import { generateNodeIndex } from '@/lib/nodes';
|
||||
import { compareString } from '@/lib/utils';
|
||||
@@ -51,6 +51,10 @@ export class TableViewCreateMutationHandler
|
||||
attributesMap.set('parentId', input.databaseId);
|
||||
attributesMap.set('index', generateNodeIndex(maxIndex, null));
|
||||
attributesMap.set('name', input.name);
|
||||
|
||||
const collaboratorsMap = new Y.Map<string>();
|
||||
collaboratorsMap.set(input.userId, NodeRole.Owner);
|
||||
attributesMap.set('collaborators', collaboratorsMap);
|
||||
});
|
||||
|
||||
const attributes = JSON.stringify(attributesMap.toJSON());
|
||||
|
||||
@@ -5,30 +5,22 @@ import {
|
||||
QueryHandler,
|
||||
QueryResult,
|
||||
} from '@/operations/queries';
|
||||
import { sql } from 'kysely';
|
||||
import {
|
||||
InheritNodeCollaboratorsGroup,
|
||||
LocalNodeAttributes,
|
||||
NodeCollaboratorNode,
|
||||
NodeCollaboratorsWrapper,
|
||||
NodeCollaborator,
|
||||
} from '@/types/nodes';
|
||||
import { MutationChange } from '@/operations/mutations';
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
type NodeRow = {
|
||||
id: string;
|
||||
attributes: string;
|
||||
parent_id: string | null;
|
||||
level: number;
|
||||
};
|
||||
|
||||
type NodeCollaboratorWithRole = {
|
||||
type ExtractedNodeCollaborator = {
|
||||
nodeId: string;
|
||||
collaboratorId: string;
|
||||
role: string;
|
||||
};
|
||||
|
||||
type CollaboratorNodeRow = {
|
||||
type NodeWithAttributesRow = {
|
||||
id: string;
|
||||
attributes: string;
|
||||
};
|
||||
@@ -39,11 +31,12 @@ export class NodeCollaboratorListQueryHandler
|
||||
public async handleQuery(
|
||||
input: NodeCollaboratorListQueryInput,
|
||||
): Promise<QueryResult<NodeCollaboratorListQueryInput>> {
|
||||
const nodes = await this.fetchAncestors(input);
|
||||
const collaboratorsWithRoles = this.extractCollaborators(nodes);
|
||||
const collaboratorIds = collaboratorsWithRoles.map(
|
||||
const ancestors = await this.fetchAncestors(input);
|
||||
const extractedCollaborators = this.extractCollaborators(ancestors);
|
||||
const collaboratorIds = extractedCollaborators.map(
|
||||
(collaborator) => collaborator.collaboratorId,
|
||||
);
|
||||
|
||||
const collaboratorNodes = await this.fetchCollaborators(
|
||||
input,
|
||||
collaboratorIds,
|
||||
@@ -52,13 +45,13 @@ export class NodeCollaboratorListQueryHandler
|
||||
return {
|
||||
output: this.buildNodeCollaborators(
|
||||
input.nodeId,
|
||||
nodes,
|
||||
ancestors,
|
||||
collaboratorNodes,
|
||||
collaboratorsWithRoles,
|
||||
extractedCollaborators,
|
||||
),
|
||||
state: {
|
||||
nodes,
|
||||
collaboratorsWithRoles,
|
||||
ancestors,
|
||||
extractedCollaborators,
|
||||
collaboratorNodes,
|
||||
},
|
||||
};
|
||||
@@ -82,19 +75,20 @@ export class NodeCollaboratorListQueryHandler
|
||||
};
|
||||
}
|
||||
|
||||
const nodes = await this.fetchAncestors(input);
|
||||
const collaboratorsWithRoles = this.extractCollaborators(nodes);
|
||||
const collaboratorIds = collaboratorsWithRoles.map(
|
||||
const ancestors = await this.fetchAncestors(input);
|
||||
const extractedCollaborators = this.extractCollaborators(ancestors);
|
||||
const collaboratorIds = extractedCollaborators.map(
|
||||
(collaborator) => collaborator.collaboratorId,
|
||||
);
|
||||
|
||||
const collaboratorNodes = await this.fetchCollaborators(
|
||||
input,
|
||||
collaboratorIds,
|
||||
);
|
||||
|
||||
if (
|
||||
isEqual(nodes, state.nodes) &&
|
||||
isEqual(collaboratorsWithRoles, state.collaboratorsWithRoles) &&
|
||||
isEqual(ancestors, state.ancestors) &&
|
||||
isEqual(extractedCollaborators, state.extractedCollaborators) &&
|
||||
isEqual(collaboratorNodes, state.collaboratorNodes)
|
||||
) {
|
||||
return {
|
||||
@@ -107,13 +101,13 @@ export class NodeCollaboratorListQueryHandler
|
||||
result: {
|
||||
output: this.buildNodeCollaborators(
|
||||
input.nodeId,
|
||||
nodes,
|
||||
ancestors,
|
||||
collaboratorNodes,
|
||||
collaboratorsWithRoles,
|
||||
extractedCollaborators,
|
||||
),
|
||||
state: {
|
||||
nodes,
|
||||
collaboratorsWithRoles,
|
||||
ancestors,
|
||||
extractedCollaborators,
|
||||
collaboratorNodes,
|
||||
},
|
||||
},
|
||||
@@ -122,32 +116,26 @@ export class NodeCollaboratorListQueryHandler
|
||||
|
||||
private async fetchAncestors(
|
||||
input: NodeCollaboratorListQueryInput,
|
||||
): Promise<NodeRow[]> {
|
||||
): Promise<NodeWithAttributesRow[]> {
|
||||
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
|
||||
input.userId,
|
||||
);
|
||||
|
||||
const query = sql<NodeRow>`
|
||||
WITH RECURSIVE ancestors(id, attributes, parent_id, level) AS (
|
||||
SELECT id, attributes, parent_id, 0 AS level
|
||||
FROM nodes
|
||||
WHERE id = ${input.nodeId}
|
||||
UNION ALL
|
||||
SELECT n.id, n.attributes, n.parent_id, a.level + 1
|
||||
FROM nodes n
|
||||
INNER JOIN ancestors a ON n.id = a.parent_id
|
||||
)
|
||||
SELECT id, attributes, parent_id, level
|
||||
FROM ancestors
|
||||
ORDER BY level DESC;
|
||||
`.compile(workspaceDatabase);
|
||||
const result = await workspaceDatabase
|
||||
.selectFrom('nodes')
|
||||
.select(['nodes.id', 'nodes.attributes'])
|
||||
.innerJoin('node_paths', 'nodes.id', 'node_paths.ancestor_id')
|
||||
.where('node_paths.descendant_id', '=', input.nodeId)
|
||||
.orderBy('node_paths.level', 'desc')
|
||||
.execute();
|
||||
|
||||
const result = await workspaceDatabase.executeQuery(query);
|
||||
return result.rows;
|
||||
return result;
|
||||
}
|
||||
|
||||
private extractCollaborators(nodes: NodeRow[]): NodeCollaboratorWithRole[] {
|
||||
const extractedCollaborators: NodeCollaboratorWithRole[] = [];
|
||||
private extractCollaborators(
|
||||
nodes: NodeWithAttributesRow[],
|
||||
): ExtractedNodeCollaborator[] {
|
||||
const map: Map<string, ExtractedNodeCollaborator> = new Map();
|
||||
|
||||
for (const node of nodes) {
|
||||
const attributes = JSON.parse(node.attributes) as LocalNodeAttributes;
|
||||
@@ -158,7 +146,7 @@ export class NodeCollaboratorListQueryHandler
|
||||
|
||||
const collaboratorIds = Object.keys(collaborators);
|
||||
for (const collaboratorId of collaboratorIds) {
|
||||
extractedCollaborators.push({
|
||||
map.set(collaboratorId, {
|
||||
nodeId: node.id,
|
||||
collaboratorId,
|
||||
role: collaborators[collaboratorId],
|
||||
@@ -166,13 +154,13 @@ export class NodeCollaboratorListQueryHandler
|
||||
}
|
||||
}
|
||||
|
||||
return extractedCollaborators;
|
||||
return Array.from(map.values());
|
||||
}
|
||||
|
||||
private async fetchCollaborators(
|
||||
input: NodeCollaboratorListQueryInput,
|
||||
collaboratorIds: string[],
|
||||
): Promise<CollaboratorNodeRow[]> {
|
||||
): Promise<NodeWithAttributesRow[]> {
|
||||
if (collaboratorIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -192,107 +180,65 @@ export class NodeCollaboratorListQueryHandler
|
||||
|
||||
private buildNodeCollaborators = (
|
||||
nodeId: string,
|
||||
nodes: NodeRow[],
|
||||
collaboratorNodes: CollaboratorNodeRow[],
|
||||
collaboratorsWithRoles: NodeCollaboratorWithRole[],
|
||||
ancestors: NodeWithAttributesRow[],
|
||||
collaboratorNodes: NodeWithAttributesRow[],
|
||||
extractedCollaborators: ExtractedNodeCollaborator[],
|
||||
): NodeCollaboratorsWrapper => {
|
||||
const direct: NodeCollaboratorNode[] = [];
|
||||
const inheritCollaboratorMap: Map<string, NodeCollaboratorWithRole> =
|
||||
new Map();
|
||||
const direct: NodeCollaborator[] = [];
|
||||
const inherit: InheritNodeCollaboratorsGroup[] = [];
|
||||
|
||||
for (const collaboratorWithRole of collaboratorsWithRoles) {
|
||||
if (collaboratorWithRole.nodeId === nodeId) {
|
||||
const collaboratorAttributes = JSON.parse(
|
||||
collaboratorNodes.find(
|
||||
(row) => row.id === collaboratorWithRole.collaboratorId,
|
||||
)?.attributes,
|
||||
);
|
||||
const inheritCollaboratorMap: Map<string, NodeCollaborator[]> = new Map();
|
||||
|
||||
const collaborator: NodeCollaboratorNode = {
|
||||
id: collaboratorWithRole.collaboratorId,
|
||||
name: collaboratorAttributes.name,
|
||||
email: collaboratorAttributes.email,
|
||||
avatar: collaboratorAttributes.avatar || null,
|
||||
role: collaboratorWithRole.role,
|
||||
};
|
||||
for (const extractedCollaborator of extractedCollaborators) {
|
||||
const collaboratorNode = collaboratorNodes.find(
|
||||
(row) => row.id === extractedCollaborator.collaboratorId,
|
||||
);
|
||||
|
||||
if (!collaboratorNode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const collaboratorAttributes = JSON.parse(collaboratorNode?.attributes);
|
||||
|
||||
const collaborator: NodeCollaborator = {
|
||||
id: extractedCollaborator.collaboratorId,
|
||||
name: collaboratorAttributes.name,
|
||||
email: collaboratorAttributes.email,
|
||||
avatar: collaboratorAttributes.avatar || null,
|
||||
role: extractedCollaborator.role,
|
||||
};
|
||||
if (extractedCollaborator.nodeId === nodeId) {
|
||||
direct.push(collaborator);
|
||||
} else {
|
||||
if (!inheritCollaboratorMap.has(collaboratorWithRole.collaboratorId)) {
|
||||
inheritCollaboratorMap.set(collaboratorWithRole.collaboratorId, {
|
||||
nodeId: collaboratorWithRole.nodeId,
|
||||
collaboratorId: collaboratorWithRole.collaboratorId,
|
||||
role: collaboratorWithRole.role,
|
||||
});
|
||||
} else {
|
||||
const existingRow = inheritCollaboratorMap.get(
|
||||
collaboratorWithRole.collaboratorId,
|
||||
);
|
||||
if (
|
||||
!existingRow ||
|
||||
existingRow.nodeId !== collaboratorWithRole.nodeId
|
||||
) {
|
||||
inheritCollaboratorMap.set(
|
||||
collaboratorWithRole.collaboratorId,
|
||||
collaboratorWithRole,
|
||||
);
|
||||
}
|
||||
if (!inheritCollaboratorMap.has(extractedCollaborator.nodeId)) {
|
||||
inheritCollaboratorMap.set(extractedCollaborator.nodeId, []);
|
||||
}
|
||||
|
||||
inheritCollaboratorMap
|
||||
.get(extractedCollaborator.nodeId)
|
||||
.push(collaborator);
|
||||
}
|
||||
}
|
||||
|
||||
const inheritLeveledMap: Map<number, InheritNodeCollaboratorsGroup> =
|
||||
new Map();
|
||||
|
||||
for (const collaboratorWithRole of inheritCollaboratorMap.values()) {
|
||||
if (
|
||||
direct.some(
|
||||
(collaborator) =>
|
||||
collaborator.id === collaboratorWithRole.collaboratorId,
|
||||
)
|
||||
) {
|
||||
for (const ancestor of ancestors.reverse()) {
|
||||
if (!inheritCollaboratorMap.has(ancestor.id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const nodeLevel = nodes.find(
|
||||
(node) => node.id === collaboratorWithRole.nodeId,
|
||||
)?.level;
|
||||
const ancestorAttributes = JSON.parse(ancestor.attributes);
|
||||
const group: InheritNodeCollaboratorsGroup = {
|
||||
id: ancestor.id,
|
||||
name: ancestorAttributes.name,
|
||||
avatar: ancestorAttributes.avatar || null,
|
||||
collaborators: inheritCollaboratorMap.get(ancestor.id),
|
||||
};
|
||||
|
||||
if (nodeLevel === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!inheritLeveledMap.has(nodeLevel)) {
|
||||
const nodeAttributes = JSON.parse(
|
||||
nodes.find((node) => node.id === collaboratorWithRole.nodeId)
|
||||
?.attributes,
|
||||
);
|
||||
inheritLeveledMap.set(nodeLevel, {
|
||||
id: collaboratorWithRole.nodeId,
|
||||
name: nodeAttributes.name,
|
||||
avatar: nodeAttributes.avatar,
|
||||
collaborators: [],
|
||||
});
|
||||
}
|
||||
|
||||
const group = inheritLeveledMap.get(nodeLevel);
|
||||
const collaboratorAttributes = JSON.parse(
|
||||
collaboratorNodes.find(
|
||||
(row) => row.id === collaboratorWithRole.collaboratorId,
|
||||
)?.attributes,
|
||||
);
|
||||
group.collaborators.push({
|
||||
id: collaboratorWithRole.collaboratorId,
|
||||
name: collaboratorAttributes.name,
|
||||
avatar: collaboratorAttributes.avatar,
|
||||
email: collaboratorAttributes.email,
|
||||
role: collaboratorWithRole.role,
|
||||
});
|
||||
inherit.push(group);
|
||||
}
|
||||
|
||||
return {
|
||||
direct,
|
||||
inherit: Array.from(inheritLeveledMap.values()),
|
||||
inherit,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ export type NodeInsertInput = {
|
||||
};
|
||||
|
||||
export type NodeCollaboratorsWrapper = {
|
||||
direct: NodeCollaboratorNode[];
|
||||
direct: NodeCollaborator[];
|
||||
inherit: InheritNodeCollaboratorsGroup[];
|
||||
};
|
||||
|
||||
@@ -85,10 +85,10 @@ export type InheritNodeCollaboratorsGroup = {
|
||||
id: string;
|
||||
name: string;
|
||||
avatar: string | null;
|
||||
collaborators: NodeCollaboratorNode[];
|
||||
collaborators: NodeCollaborator[];
|
||||
};
|
||||
|
||||
export type NodeCollaboratorNode = {
|
||||
export type NodeCollaborator = {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
|
||||
Reference in New Issue
Block a user