@dssp/project 1.0.0-alpha.0 → 1.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/client/bootstrap.ts +0 -0
- package/client/index.ts +0 -0
- package/client/pages/lib/select2-component.ts +0 -175
- package/client/pages/lib/waether.ts +0 -159
- package/client/pages/project/component/project-update-header.ts +0 -88
- package/client/pages/project/popup/popup-plan-upload.ts +0 -138
- package/client/pages/project/popup/popup-project-create.ts +0 -147
- package/client/pages/project/popup/popup-schedule-upload.ts +0 -102
- package/client/pages/project/project-completed-list.ts +0 -281
- package/client/pages/project/project-detail.ts +0 -738
- package/client/pages/project/project-list.ts +0 -418
- package/client/pages/project/project-plan-management.ts +0 -476
- package/client/pages/project/project-schedule-list.ts +0 -294
- package/client/pages/project/project-schedule.ts +0 -393
- package/client/pages/project/project-setting-list.ts +0 -393
- package/client/pages/project/project-update.ts +0 -876
- package/client/pages/resource/construction-detail-type-popup.ts +0 -201
- package/client/pages/resource/construction-type-management.ts +0 -212
- package/client/pages/resource/inspection-drawing-type-management.ts +0 -245
- package/client/pages/resource/inspection-part-popup.ts +0 -201
- package/client/pages/resource/resource-importer.ts +0 -97
- package/client/pages/resource/resource-list-page.ts +0 -356
- package/client/pages/resource/worker-type-management.ts +0 -192
- package/client/pages/task/task-importer.ts +0 -94
- package/client/pages/task/task-list-page.ts +0 -340
- package/client/pages/task-resource/task-resource-importer.ts +0 -97
- package/client/pages/task-resource/task-resource-list-page.ts +0 -356
- package/client/route.ts +0 -55
- package/client/tsconfig.json +0 -11
- package/server/controllers/export-tasks.ts +0 -40
- package/server/controllers/import-task.ts +0 -134
- package/server/controllers/index.ts +0 -0
- package/server/controllers/parse-excel.ts +0 -86
- package/server/controllers/types.ts +0 -20
- package/server/index.ts +0 -4
- package/server/middlewares/index.ts +0 -3
- package/server/migrations/1723861466413-seed-roles.ts +0 -128
- package/server/migrations/1723861466414-seed-codes.ts +0 -157
- package/server/migrations/1723861476419-seed-resources.ts +0 -62
- package/server/migrations/1723861478420-seed-/bsample-project.ts +0 -87
- package/server/migrations/1723861478421-seed-/bsample-tasks.ts +0 -194
- package/server/migrations/index.ts +0 -9
- package/server/routes.ts +0 -108
- package/server/service/construction-detail-type/construction-detail-type-mutation.ts +0 -57
- package/server/service/construction-detail-type/construction-detail-type-query.ts +0 -31
- package/server/service/construction-detail-type/construction-detail-type-type.ts +0 -26
- package/server/service/construction-detail-type/construction-detail-type.ts +0 -52
- package/server/service/construction-detail-type/index.ts +0 -6
- package/server/service/construction-type/construction-type-mutation.ts +0 -66
- package/server/service/construction-type/construction-type-query.ts +0 -56
- package/server/service/construction-type/construction-type-type.ts +0 -26
- package/server/service/construction-type/construction-type.ts +0 -74
- package/server/service/construction-type/index.ts +0 -6
- package/server/service/index.ts +0 -56
- package/server/service/inspection-drawing-type/index.ts +0 -6
- package/server/service/inspection-drawing-type/inspection-drawing-type-mutation.ts +0 -69
- package/server/service/inspection-drawing-type/inspection-drawing-type-query.ts +0 -55
- package/server/service/inspection-drawing-type/inspection-drawing-type-type.ts +0 -23
- package/server/service/inspection-drawing-type/inspection-drawing-type.ts +0 -68
- package/server/service/inspection-part/index.ts +0 -6
- package/server/service/inspection-part/inspection-part-mutation.ts +0 -52
- package/server/service/inspection-part/inspection-part-query.ts +0 -41
- package/server/service/inspection-part/inspection-part-type.ts +0 -26
- package/server/service/inspection-part/inspection-part.ts +0 -51
- package/server/service/manager/index.ts +0 -6
- package/server/service/manager/manager-mutation.ts +0 -42
- package/server/service/manager/manager-query.ts +0 -28
- package/server/service/manager/manager-type.ts +0 -40
- package/server/service/manager/manager.ts +0 -29
- package/server/service/project/index.ts +0 -6
- package/server/service/project/project-mutation.ts +0 -255
- package/server/service/project/project-query.ts +0 -105
- package/server/service/project/project-type.ts +0 -72
- package/server/service/project/project.ts +0 -134
- package/server/service/resource/index.ts +0 -7
- package/server/service/resource/resource-mutation.ts +0 -137
- package/server/service/resource/resource-query.ts +0 -50
- package/server/service/resource/resource-type.ts +0 -41
- package/server/service/resource/resource.ts +0 -82
- package/server/service/task/index.ts +0 -6
- package/server/service/task/task-mutation.ts +0 -135
- package/server/service/task/task-query.ts +0 -169
- package/server/service/task/task-type.ts +0 -75
- package/server/service/task/task.ts +0 -130
- package/server/service/task-resource/index.ts +0 -7
- package/server/service/task-resource/task-resource-mutation.ts +0 -140
- package/server/service/task-resource/task-resource-query.ts +0 -36
- package/server/service/task-resource/task-resource-type.ts +0 -41
- package/server/service/task-resource/task-resource.ts +0 -51
- package/server/service/worker-type/index.ts +0 -6
- package/server/service/worker-type/worker-type-mutation.ts +0 -66
- package/server/service/worker-type/worker-type-query.ts +0 -47
- package/server/service/worker-type/worker-type-type.ts +0 -26
- package/server/service/worker-type/worker-type.ts +0 -68
- package/server/tsconfig.json +0 -10
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
-
import { In } from 'typeorm'
|
|
3
|
-
|
|
4
|
-
import { Resource } from './resource'
|
|
5
|
-
import { NewResource, ResourcePatch } from './resource-type'
|
|
6
|
-
|
|
7
|
-
@Resolver(Resource)
|
|
8
|
-
export class ResourceMutation {
|
|
9
|
-
@Directive('@transaction')
|
|
10
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
11
|
-
@Mutation(returns => Resource, { description: 'To create new Resource' })
|
|
12
|
-
async createResource(@Arg('resource') resource: NewResource, @Ctx() context: ResolverContext): Promise<Resource> {
|
|
13
|
-
const { domain, user, tx } = context.state
|
|
14
|
-
|
|
15
|
-
const result = await tx.getRepository(Resource).save({
|
|
16
|
-
...resource,
|
|
17
|
-
domain,
|
|
18
|
-
creator: user,
|
|
19
|
-
updater: user
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
return result
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@Directive('@transaction')
|
|
26
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
27
|
-
@Mutation(returns => Resource, { description: 'To modify Resource information' })
|
|
28
|
-
async updateResource(
|
|
29
|
-
@Arg('id') id: string,
|
|
30
|
-
@Arg('patch') patch: ResourcePatch,
|
|
31
|
-
@Ctx() context: ResolverContext
|
|
32
|
-
): Promise<Resource> {
|
|
33
|
-
const { domain, user, tx } = context.state
|
|
34
|
-
|
|
35
|
-
const repository = tx.getRepository(Resource)
|
|
36
|
-
const resource = await repository.findOne({
|
|
37
|
-
where: { domain: { id: domain.id }, id }
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const result = await repository.save({
|
|
41
|
-
...resource,
|
|
42
|
-
...patch,
|
|
43
|
-
updater: user
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
return result
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@Directive('@transaction')
|
|
50
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
51
|
-
@Mutation(returns => [Resource], { description: "To modify multiple Resources' information" })
|
|
52
|
-
async updateMultipleResource(
|
|
53
|
-
@Arg('patches', type => [ResourcePatch]) patches: ResourcePatch[],
|
|
54
|
-
@Ctx() context: ResolverContext
|
|
55
|
-
): Promise<Resource[]> {
|
|
56
|
-
const { domain, user, tx } = context.state
|
|
57
|
-
|
|
58
|
-
let results = []
|
|
59
|
-
const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
|
|
60
|
-
const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
|
|
61
|
-
const resourceRepo = tx.getRepository(Resource)
|
|
62
|
-
|
|
63
|
-
if (_createRecords.length > 0) {
|
|
64
|
-
for (let i = 0; i < _createRecords.length; i++) {
|
|
65
|
-
const newRecord = _createRecords[i]
|
|
66
|
-
|
|
67
|
-
const result = await resourceRepo.save({
|
|
68
|
-
...newRecord,
|
|
69
|
-
domain,
|
|
70
|
-
creator: user,
|
|
71
|
-
updater: user
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
results.push({ ...result, cuFlag: '+' })
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (_updateRecords.length > 0) {
|
|
79
|
-
for (let i = 0; i < _updateRecords.length; i++) {
|
|
80
|
-
const updateRecord = _updateRecords[i]
|
|
81
|
-
const resource = await resourceRepo.findOneBy({ id: updateRecord.id })
|
|
82
|
-
|
|
83
|
-
const result = await resourceRepo.save({
|
|
84
|
-
...resource,
|
|
85
|
-
...updateRecord,
|
|
86
|
-
updater: user
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
results.push({ ...result, cuFlag: 'M' })
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return results
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
@Directive('@transaction')
|
|
97
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
98
|
-
@Mutation(returns => Boolean, { description: 'To delete Resource' })
|
|
99
|
-
async deleteResource(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
|
100
|
-
const { domain, tx } = context.state
|
|
101
|
-
|
|
102
|
-
await tx.getRepository(Resource).delete({ domain: { id: domain.id }, id })
|
|
103
|
-
|
|
104
|
-
return true
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
@Directive('@transaction')
|
|
108
|
-
@Mutation(returns => Boolean, { description: 'To delete multiple Resources' })
|
|
109
|
-
async deleteResources(@Arg('ids', type => [String]) ids: string[], @Ctx() context: ResolverContext): Promise<boolean> {
|
|
110
|
-
const { domain, tx } = context.state
|
|
111
|
-
|
|
112
|
-
await tx.getRepository(Resource).delete({
|
|
113
|
-
domain: { id: domain.id },
|
|
114
|
-
id: In(ids)
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
return true
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
@Directive('@transaction')
|
|
121
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
122
|
-
@Mutation(returns => Boolean, { description: 'To import multiple Resources' })
|
|
123
|
-
async importResources(
|
|
124
|
-
@Arg('resources', type => [ResourcePatch]) resources: ResourcePatch[],
|
|
125
|
-
@Ctx() context: ResolverContext
|
|
126
|
-
): Promise<boolean> {
|
|
127
|
-
const { domain, tx } = context.state
|
|
128
|
-
|
|
129
|
-
await Promise.all(
|
|
130
|
-
resources.map(async (resource: ResourcePatch) => {
|
|
131
|
-
const createdResource: Resource = await tx.getRepository(Resource).save({ domain, ...resource })
|
|
132
|
-
})
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
return true
|
|
136
|
-
}
|
|
137
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
-
import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
|
|
3
|
-
import { User } from '@things-factory/auth-base'
|
|
4
|
-
import { Resource } from './resource'
|
|
5
|
-
import { ResourceList } from './resource-type'
|
|
6
|
-
|
|
7
|
-
@Resolver(Resource)
|
|
8
|
-
export class ResourceQuery {
|
|
9
|
-
@Directive('@privilege(category: "project", privilege: "query", domainOwnerGranted: true)')
|
|
10
|
-
@Query(returns => Resource!, { nullable: true, description: 'To fetch a Resource' })
|
|
11
|
-
async resource(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Resource> {
|
|
12
|
-
const { domain } = context.state
|
|
13
|
-
|
|
14
|
-
return await getRepository(Resource).findOne({
|
|
15
|
-
where: { domain: { id: domain.id }, id }
|
|
16
|
-
})
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@Directive('@privilege(category: "project", privilege: "query", domainOwnerGranted: true)')
|
|
20
|
-
@Query(returns => ResourceList, { description: 'To fetch multiple Resources' })
|
|
21
|
-
async resources(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<ResourceList> {
|
|
22
|
-
const { domain } = context.state
|
|
23
|
-
|
|
24
|
-
const queryBuilder = getQueryBuilderFromListParams({
|
|
25
|
-
domain,
|
|
26
|
-
params,
|
|
27
|
-
repository: await getRepository(Resource),
|
|
28
|
-
searchables: ['name', 'description']
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const [items, total] = await queryBuilder.getManyAndCount()
|
|
32
|
-
|
|
33
|
-
return { items, total }
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@FieldResolver(type => Domain)
|
|
37
|
-
async domain(@Root() resource: Resource): Promise<Domain> {
|
|
38
|
-
return await getRepository(Domain).findOneBy({ id: resource.domainId })
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@FieldResolver(type => User)
|
|
42
|
-
async updater(@Root() resource: Resource): Promise<User> {
|
|
43
|
-
return await getRepository(User).findOneBy({ id: resource.updaterId })
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@FieldResolver(type => User)
|
|
47
|
-
async creator(@Root() resource: Resource): Promise<User> {
|
|
48
|
-
return await getRepository(User).findOneBy({ id: resource.creatorId })
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { InputType, Field, ID, ObjectType, Int } from 'type-graphql'
|
|
2
|
-
import { Resource, ResourceType } from './resource'
|
|
3
|
-
|
|
4
|
-
@InputType()
|
|
5
|
-
export class NewResource {
|
|
6
|
-
@Field()
|
|
7
|
-
name: string
|
|
8
|
-
|
|
9
|
-
@Field(type => ResourceType)
|
|
10
|
-
type: ResourceType
|
|
11
|
-
|
|
12
|
-
@Field()
|
|
13
|
-
unit: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
@InputType()
|
|
17
|
-
export class ResourcePatch {
|
|
18
|
-
@Field(type => ID, { nullable: true })
|
|
19
|
-
id?: string
|
|
20
|
-
|
|
21
|
-
@Field({ nullable: true })
|
|
22
|
-
name?: string
|
|
23
|
-
|
|
24
|
-
@Field(type => ResourceType, { nullable: true })
|
|
25
|
-
type?: ResourceType
|
|
26
|
-
|
|
27
|
-
@Field({ nullable: true })
|
|
28
|
-
unit?: string
|
|
29
|
-
|
|
30
|
-
@Field({ nullable: true })
|
|
31
|
-
cuFlag?: string
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@ObjectType()
|
|
35
|
-
export class ResourceList {
|
|
36
|
-
@Field(type => [Resource])
|
|
37
|
-
items: Resource[]
|
|
38
|
-
|
|
39
|
-
@Field(type => Int)
|
|
40
|
-
total: number
|
|
41
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CreateDateColumn,
|
|
3
|
-
UpdateDateColumn,
|
|
4
|
-
DeleteDateColumn,
|
|
5
|
-
Entity,
|
|
6
|
-
Column,
|
|
7
|
-
PrimaryGeneratedColumn,
|
|
8
|
-
ManyToOne,
|
|
9
|
-
RelationId,
|
|
10
|
-
OneToMany
|
|
11
|
-
} from 'typeorm'
|
|
12
|
-
import { ObjectType, Field, ID, registerEnumType } from 'type-graphql'
|
|
13
|
-
import { Domain } from '@things-factory/shell'
|
|
14
|
-
import { User } from '@things-factory/auth-base'
|
|
15
|
-
import { TaskResource } from '../task-resource/task-resource'
|
|
16
|
-
|
|
17
|
-
export enum ResourceType {
|
|
18
|
-
HUMAN = 'HUMAN',
|
|
19
|
-
MATERIAL = 'MATERIAL',
|
|
20
|
-
EQUIPMENT = 'EQUIPMENT'
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
registerEnumType(ResourceType, {
|
|
24
|
-
name: 'ResourceType',
|
|
25
|
-
description: '자원 유형'
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
@Entity()
|
|
29
|
-
@ObjectType({ description: '자원' })
|
|
30
|
-
export class Resource {
|
|
31
|
-
@PrimaryGeneratedColumn('uuid')
|
|
32
|
-
@Field(type => ID)
|
|
33
|
-
readonly id: string
|
|
34
|
-
|
|
35
|
-
@ManyToOne(type => Domain)
|
|
36
|
-
@Field({ nullable: true })
|
|
37
|
-
domain?: Domain
|
|
38
|
-
|
|
39
|
-
@RelationId((resource: Resource) => resource.domain)
|
|
40
|
-
domainId?: string
|
|
41
|
-
|
|
42
|
-
@Column({ nullable: false, comment: '자원 이름' })
|
|
43
|
-
@Field({ nullable: false })
|
|
44
|
-
name?: string
|
|
45
|
-
|
|
46
|
-
@Column({ nullable: false, default: ResourceType.HUMAN, comment: '자원 유형' })
|
|
47
|
-
@Field({ nullable: false })
|
|
48
|
-
type: ResourceType
|
|
49
|
-
|
|
50
|
-
@Column({ nullable: false, comment: '단위 (예: man/day, kg, hour 등)' })
|
|
51
|
-
@Field({ nullable: false })
|
|
52
|
-
unit: string
|
|
53
|
-
|
|
54
|
-
@CreateDateColumn()
|
|
55
|
-
@Field({ nullable: true })
|
|
56
|
-
createdAt?: Date
|
|
57
|
-
|
|
58
|
-
@UpdateDateColumn()
|
|
59
|
-
@Field({ nullable: true })
|
|
60
|
-
updatedAt?: Date
|
|
61
|
-
|
|
62
|
-
@DeleteDateColumn()
|
|
63
|
-
@Field({ nullable: true })
|
|
64
|
-
deletedAt?: Date
|
|
65
|
-
|
|
66
|
-
@ManyToOne(type => User, { nullable: true })
|
|
67
|
-
@Field(type => User, { nullable: true })
|
|
68
|
-
creator?: User
|
|
69
|
-
|
|
70
|
-
@RelationId((resource: Resource) => resource.creator)
|
|
71
|
-
creatorId?: string
|
|
72
|
-
|
|
73
|
-
@ManyToOne(type => User, { nullable: true })
|
|
74
|
-
@Field(type => User, { nullable: true })
|
|
75
|
-
updater?: User
|
|
76
|
-
|
|
77
|
-
@RelationId((resource: Resource) => resource.updater)
|
|
78
|
-
updaterId?: string
|
|
79
|
-
|
|
80
|
-
@OneToMany(() => TaskResource, taskResource => taskResource.resource)
|
|
81
|
-
taskResources?: TaskResource[]
|
|
82
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
-
import { In } from 'typeorm'
|
|
3
|
-
|
|
4
|
-
import { createAttachment, deleteAttachmentsByRef } from '@things-factory/attachment-base'
|
|
5
|
-
|
|
6
|
-
import { Task } from './task'
|
|
7
|
-
import { NewTask, TaskPatch } from './task-type'
|
|
8
|
-
|
|
9
|
-
@Resolver(Task)
|
|
10
|
-
export class TaskMutation {
|
|
11
|
-
@Directive('@transaction')
|
|
12
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
13
|
-
@Mutation(returns => Task, { description: 'To create new Task' })
|
|
14
|
-
async createTask(@Arg('task') task: NewTask, @Ctx() context: ResolverContext): Promise<Task> {
|
|
15
|
-
const { domain, user, tx } = context.state
|
|
16
|
-
|
|
17
|
-
const result = await tx.getRepository(Task).save({
|
|
18
|
-
...task,
|
|
19
|
-
domain,
|
|
20
|
-
creator: user,
|
|
21
|
-
updater: user
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
return result
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@Directive('@transaction')
|
|
28
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
29
|
-
@Mutation(returns => Task, { description: 'To modify Task information' })
|
|
30
|
-
async updateTask(@Arg('id') id: string, @Arg('patch') patch: TaskPatch, @Ctx() context: ResolverContext): Promise<Task> {
|
|
31
|
-
const { domain, user, tx } = context.state
|
|
32
|
-
|
|
33
|
-
const repository = tx.getRepository(Task)
|
|
34
|
-
const task = await repository.findOne({
|
|
35
|
-
where: { id }
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
const result = await repository.save({
|
|
39
|
-
...task,
|
|
40
|
-
...patch,
|
|
41
|
-
updater: user
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
return result
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
@Directive('@transaction')
|
|
48
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
49
|
-
@Mutation(returns => [Task], { description: "To modify multiple Tasks' information" })
|
|
50
|
-
async updateMultipleTask(
|
|
51
|
-
@Arg('patches', type => [TaskPatch]) patches: TaskPatch[],
|
|
52
|
-
@Ctx() context: ResolverContext
|
|
53
|
-
): Promise<Task[]> {
|
|
54
|
-
const { domain, user, tx } = context.state
|
|
55
|
-
|
|
56
|
-
let results = []
|
|
57
|
-
const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
|
|
58
|
-
const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
|
|
59
|
-
const taskRepo = tx.getRepository(Task)
|
|
60
|
-
|
|
61
|
-
if (_createRecords.length > 0) {
|
|
62
|
-
for (let i = 0; i < _createRecords.length; i++) {
|
|
63
|
-
const newRecord = _createRecords[i]
|
|
64
|
-
|
|
65
|
-
const result = await taskRepo.save({
|
|
66
|
-
...newRecord,
|
|
67
|
-
domain,
|
|
68
|
-
creator: user,
|
|
69
|
-
updater: user
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
results.push({ ...result, cuFlag: '+' })
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (_updateRecords.length > 0) {
|
|
77
|
-
for (let i = 0; i < _updateRecords.length; i++) {
|
|
78
|
-
const updateRecord = _updateRecords[i]
|
|
79
|
-
const task = await taskRepo.findOneBy({ id: updateRecord.id })
|
|
80
|
-
|
|
81
|
-
const result = await taskRepo.save({
|
|
82
|
-
...task,
|
|
83
|
-
...updateRecord,
|
|
84
|
-
updater: user
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
results.push({ ...result, cuFlag: 'M' })
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return results
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
@Directive('@transaction')
|
|
95
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
96
|
-
@Mutation(returns => Boolean, { description: 'To delete Task' })
|
|
97
|
-
async deleteTask(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
|
98
|
-
const { domain, tx } = context.state
|
|
99
|
-
|
|
100
|
-
await tx.getRepository(Task).delete({ id })
|
|
101
|
-
await deleteAttachmentsByRef(null, { refBys: [id] }, context)
|
|
102
|
-
|
|
103
|
-
return true
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
@Directive('@transaction')
|
|
107
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
108
|
-
@Mutation(returns => Boolean, { description: 'To delete multiple Tasks' })
|
|
109
|
-
async deleteTasks(@Arg('ids', type => [String]) ids: string[], @Ctx() context: ResolverContext): Promise<boolean> {
|
|
110
|
-
const { domain, tx } = context.state
|
|
111
|
-
|
|
112
|
-
await tx.getRepository(Task).delete({
|
|
113
|
-
id: In(ids)
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
await deleteAttachmentsByRef(null, { refBys: ids }, context)
|
|
117
|
-
|
|
118
|
-
return true
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
@Directive('@transaction')
|
|
122
|
-
@Directive('@privilege(category: "project", privilege: "mutation", domainOwnerGranted: true)')
|
|
123
|
-
@Mutation(returns => Boolean, { description: 'To import multiple Tasks' })
|
|
124
|
-
async importTasks(@Arg('tasks', type => [TaskPatch]) tasks: TaskPatch[], @Ctx() context: ResolverContext): Promise<boolean> {
|
|
125
|
-
const { domain, tx } = context.state
|
|
126
|
-
|
|
127
|
-
await Promise.all(
|
|
128
|
-
tasks.map(async (task: TaskPatch) => {
|
|
129
|
-
const createdTask: Task = await tx.getRepository(Task).save({ domain, ...task })
|
|
130
|
-
})
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
return true
|
|
134
|
-
}
|
|
135
|
-
}
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { Resolver, Query, Field, FieldResolver, ObjectType, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
-
import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
|
|
3
|
-
import { User } from '@things-factory/auth-base'
|
|
4
|
-
import { Task, TaskType } from './task'
|
|
5
|
-
import { TaskList } from './task-type'
|
|
6
|
-
import { TaskResource } from '../task-resource/task-resource'
|
|
7
|
-
import { ResourceType } from 'service/resource/resource'
|
|
8
|
-
|
|
9
|
-
@ObjectType()
|
|
10
|
-
export class DigestedResource {
|
|
11
|
-
@Field({ nullable: true, description: '자원 유형' })
|
|
12
|
-
type?: string
|
|
13
|
-
|
|
14
|
-
@Field({ nullable: true, description: '할당량' })
|
|
15
|
-
allocated?: number
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@Resolver(Task)
|
|
19
|
-
export class TaskQuery {
|
|
20
|
-
@Directive('@privilege(category: "project", privilege: "query", domainOwnerGranted: true)')
|
|
21
|
-
@Query(returns => Task!, { nullable: true, description: 'Fetch a single Task by its ID' })
|
|
22
|
-
async task(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Task> {
|
|
23
|
-
return await getRepository(Task).findOne({
|
|
24
|
-
where: { id },
|
|
25
|
-
relations: ['parent', 'taskResources']
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Directive('@privilege(category: "project", privilege: "query", domainOwnerGranted: true)')
|
|
30
|
-
@Query(returns => TaskList, { description: 'Fetch multiple Tasks based on list parameters' })
|
|
31
|
-
async tasks(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<TaskList> {
|
|
32
|
-
const queryBuilder = getQueryBuilderFromListParams({
|
|
33
|
-
params,
|
|
34
|
-
repository: await getRepository(Task),
|
|
35
|
-
alias: 'tasks',
|
|
36
|
-
searchables: ['name', 'code']
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const [items, total] = await queryBuilder.getManyAndCount()
|
|
40
|
-
|
|
41
|
-
return { items, total }
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// @FieldResolver(type => Date, { nullable: true, description: 'Calculate or return the start date of the task' })
|
|
45
|
-
// async startDate(@Root() task: Task): Promise<Date | undefined> {
|
|
46
|
-
// if (task.type === TaskType.TASK) {
|
|
47
|
-
// return task.startDate
|
|
48
|
-
// } else {
|
|
49
|
-
// const children = await getRepository(Task).find({ where: { parent: { id: task.id } } })
|
|
50
|
-
// return children.reduce(
|
|
51
|
-
// (earliest, child) => {
|
|
52
|
-
// if (!earliest || (child.startDate && child.startDate < earliest)) {
|
|
53
|
-
// return child.startDate
|
|
54
|
-
// }
|
|
55
|
-
// return earliest
|
|
56
|
-
// },
|
|
57
|
-
// undefined as Date | undefined
|
|
58
|
-
// )
|
|
59
|
-
// }
|
|
60
|
-
// }
|
|
61
|
-
|
|
62
|
-
// @FieldResolver(type => Date, { nullable: true, description: 'Calculate or return the end date of the task' })
|
|
63
|
-
// async endDate(@Root() task: Task): Promise<Date | undefined> {
|
|
64
|
-
// if (task.type === TaskType.TASK) {
|
|
65
|
-
// return task.endDate
|
|
66
|
-
// } else {
|
|
67
|
-
// const children = await getRepository(Task).find({ where: { parent: { id: task.id } } })
|
|
68
|
-
// return children.reduce(
|
|
69
|
-
// (latest, child) => {
|
|
70
|
-
// if (!latest || (child.endDate && child.endDate > latest)) {
|
|
71
|
-
// return child.endDate
|
|
72
|
-
// }
|
|
73
|
-
// return latest
|
|
74
|
-
// },
|
|
75
|
-
// undefined as Date | undefined
|
|
76
|
-
// )
|
|
77
|
-
// }
|
|
78
|
-
// }
|
|
79
|
-
|
|
80
|
-
// @FieldResolver(type => Number, { nullable: true, description: 'Calculate the duration of the task in days' })
|
|
81
|
-
// async duration(@Root() task: Task): Promise<number | undefined> {
|
|
82
|
-
// if (task.type === TaskType.TASK) {
|
|
83
|
-
// return task.duration
|
|
84
|
-
// } else {
|
|
85
|
-
// const startDate = await this.startDate(task)
|
|
86
|
-
// const endDate = await this.endDate(task)
|
|
87
|
-
|
|
88
|
-
// if (startDate && endDate) {
|
|
89
|
-
// const durationInMs = endDate.getTime() - startDate.getTime()
|
|
90
|
-
// const durationInDays = Math.ceil(durationInMs / (1000 * 60 * 60 * 24))
|
|
91
|
-
// return durationInDays
|
|
92
|
-
// }
|
|
93
|
-
|
|
94
|
-
// return
|
|
95
|
-
// }
|
|
96
|
-
// }
|
|
97
|
-
|
|
98
|
-
@FieldResolver(type => String, { nullable: true, description: 'Calculate the duration of the task in days' })
|
|
99
|
-
async length(@Root() task: Task): Promise<string | undefined> {
|
|
100
|
-
// if (task.type === TaskType.TASK) {
|
|
101
|
-
return `${task.duration || 1}d`
|
|
102
|
-
// } else {
|
|
103
|
-
// const startDate = await this.startDate(task)
|
|
104
|
-
// const endDate = await this.endDate(task)
|
|
105
|
-
|
|
106
|
-
// if (startDate && endDate) {
|
|
107
|
-
// const durationInMs = endDate.getTime() - startDate.getTime()
|
|
108
|
-
// const durationInDays = Math.ceil(durationInMs / (1000 * 60 * 60 * 24))
|
|
109
|
-
// return `${durationInDays || 1}d`
|
|
110
|
-
// }
|
|
111
|
-
|
|
112
|
-
// return
|
|
113
|
-
// }
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@FieldResolver(type => [Task])
|
|
117
|
-
async children(
|
|
118
|
-
@Root() task: Task,
|
|
119
|
-
@Args(type => ListParam) params: ListParam,
|
|
120
|
-
@Ctx() context: ResolverContext
|
|
121
|
-
): Promise<Task[]> {
|
|
122
|
-
const { domain } = context.state
|
|
123
|
-
|
|
124
|
-
const queryBuilder = getQueryBuilderFromListParams({
|
|
125
|
-
params,
|
|
126
|
-
alias: 'tasks',
|
|
127
|
-
repository: await getRepository(Task),
|
|
128
|
-
searchables: ['name', 'code']
|
|
129
|
-
}).andWhere({ parent: { id: task.id } })
|
|
130
|
-
|
|
131
|
-
const [items, total] = await queryBuilder.getManyAndCount()
|
|
132
|
-
|
|
133
|
-
return items
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
@FieldResolver(type => [TaskResource], { description: 'Return the list of resources allocated to the task' })
|
|
137
|
-
async taskResources(@Root() task: Task): Promise<TaskResource[]> {
|
|
138
|
-
return task?.id && (await getRepository(TaskResource).find({ where: { task: { id: task.id } } }))
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
@FieldResolver(type => [DigestedResource], { description: 'Return the simple list of resources allocated to the task' })
|
|
142
|
-
async resources(@Root() task: Task): Promise<DigestedResource[]> {
|
|
143
|
-
const taskResources =
|
|
144
|
-
task?.id &&
|
|
145
|
-
(await getRepository(TaskResource).find({
|
|
146
|
-
where: {
|
|
147
|
-
task: { id: task.id }
|
|
148
|
-
},
|
|
149
|
-
relations: ['resource']
|
|
150
|
-
}))
|
|
151
|
-
|
|
152
|
-
return (taskResources || []).map(taskResource => {
|
|
153
|
-
return {
|
|
154
|
-
type: taskResource.resource.name,
|
|
155
|
-
allocated: taskResource.quantity
|
|
156
|
-
}
|
|
157
|
-
})
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
@FieldResolver(type => User, { description: 'Fetch the user who last updated the task' })
|
|
161
|
-
async updater(@Root() task: Task): Promise<User> {
|
|
162
|
-
return await getRepository(User).findOneBy({ id: task.updaterId })
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
@FieldResolver(type => User, { description: 'Fetch the user who created the task' })
|
|
166
|
-
async creator(@Root() task: Task): Promise<User> {
|
|
167
|
-
return await getRepository(User).findOneBy({ id: task.creatorId })
|
|
168
|
-
}
|
|
169
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { ObjectType, Field, InputType, Int, ID, registerEnumType } from 'type-graphql'
|
|
2
|
-
import { ObjectRef, ScalarObject } from '@things-factory/shell'
|
|
3
|
-
import { Task } from './task'
|
|
4
|
-
|
|
5
|
-
@InputType()
|
|
6
|
-
export class ObjectRefForProject extends ObjectRef {
|
|
7
|
-
@Field({ nullable: true, description: '프로젝트 이름 (선택 사항)' })
|
|
8
|
-
name?: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
@InputType()
|
|
12
|
-
export class ObjectRefForTask extends ObjectRef {
|
|
13
|
-
@Field({ nullable: true, description: '작업 코드 (선택 사항)' })
|
|
14
|
-
code?: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@InputType()
|
|
18
|
-
export class NewTask {
|
|
19
|
-
@Field({ description: '프로젝트 내에서 유니크한 작업 코드' })
|
|
20
|
-
code: string
|
|
21
|
-
|
|
22
|
-
@Field({ description: '작업의 이름' })
|
|
23
|
-
name: string
|
|
24
|
-
|
|
25
|
-
@Field(type => ObjectRefForProject, { nullable: true, description: '작업이 속한 프로젝트 (선택 사항)' })
|
|
26
|
-
project?: ObjectRefForProject
|
|
27
|
-
|
|
28
|
-
@Field(type => ObjectRefForTask, { nullable: true, description: '부모 작업, 해당 작업이 하위 작업인 경우 (선택 사항)' })
|
|
29
|
-
parent?: ObjectRefForTask
|
|
30
|
-
|
|
31
|
-
@Field({ nullable: true, description: '작업에 대한 설명 (선택 사항)' })
|
|
32
|
-
description?: string
|
|
33
|
-
|
|
34
|
-
@Field({ nullable: true, description: '작업이 활성 상태인지 여부 (선택 사항)' })
|
|
35
|
-
active?: boolean
|
|
36
|
-
|
|
37
|
-
@Field({ nullable: true, description: '작업에 대한 추가 파라미터, JSON 형식으로 저장 (선택 사항)' })
|
|
38
|
-
params?: string
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@InputType()
|
|
42
|
-
export class TaskPatch {
|
|
43
|
-
@Field(type => ID, { nullable: true, description: '수정할 작업의 ID (선택 사항)' })
|
|
44
|
-
id?: string
|
|
45
|
-
|
|
46
|
-
@Field({ nullable: true, description: '프로젝트 내에서 유니크한 작업 코드 (선택 사항)' })
|
|
47
|
-
code?: string
|
|
48
|
-
|
|
49
|
-
@Field({ nullable: true, description: '작업의 이름 (선택 사항)' })
|
|
50
|
-
name?: string
|
|
51
|
-
|
|
52
|
-
@Field(type => ObjectRefForProject, { nullable: true, description: '작업이 속한 프로젝트 (선택 사항)' })
|
|
53
|
-
project?: ObjectRefForProject
|
|
54
|
-
|
|
55
|
-
@Field(type => ObjectRefForTask, { nullable: true, description: '부모 작업, 해당 작업이 하위 작업인 경우 (선택 사항)' })
|
|
56
|
-
parent?: ObjectRefForTask
|
|
57
|
-
|
|
58
|
-
@Field({ nullable: true, description: '작업에 대한 설명 (선택 사항)' })
|
|
59
|
-
description?: string
|
|
60
|
-
|
|
61
|
-
@Field({ nullable: true, description: '작업이 활성 상태인지 여부 (선택 사항)' })
|
|
62
|
-
active?: boolean
|
|
63
|
-
|
|
64
|
-
@Field({ nullable: true, description: "생성('+') 또는 수정('M') 플래그 (선택 사항)" })
|
|
65
|
-
cuFlag?: string
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
@ObjectType()
|
|
69
|
-
export class TaskList {
|
|
70
|
-
@Field(type => [Task], { description: '작업 리스트 항목들' })
|
|
71
|
-
items: Task[]
|
|
72
|
-
|
|
73
|
-
@Field(type => Int, { description: '전체 작업 수' })
|
|
74
|
-
total: number
|
|
75
|
-
}
|