@dssp/supervision 0.0.2

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.
Files changed (174) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/assets/images/hatiolab-logo.png +0 -0
  3. package/client/actions/main.ts +1 -0
  4. package/client/bootstrap.ts +8 -0
  5. package/client/index.ts +1 -0
  6. package/client/pages/action-plan/action-plan-importer.ts +96 -0
  7. package/client/pages/action-plan/action-plan-list-page.ts +355 -0
  8. package/client/pages/check-item/check-item-importer.ts +96 -0
  9. package/client/pages/check-item/check-item-list-page.ts +355 -0
  10. package/client/pages/issue/issue-importer.ts +96 -0
  11. package/client/pages/issue/issue-list-page.ts +355 -0
  12. package/client/pages/main.ts +25 -0
  13. package/client/pages/project-report/project-report-importer.ts +96 -0
  14. package/client/pages/project-report/project-report-list-page.ts +355 -0
  15. package/client/pages/supervisor/supervisor-importer.ts +96 -0
  16. package/client/pages/supervisor/supervisor-list-page.ts +355 -0
  17. package/client/reducers/main.ts +17 -0
  18. package/client/route.ts +27 -0
  19. package/client/tsconfig.json +11 -0
  20. package/dist-client/actions/main.d.ts +1 -0
  21. package/dist-client/actions/main.js +2 -0
  22. package/dist-client/actions/main.js.map +1 -0
  23. package/dist-client/bootstrap.d.ts +1 -0
  24. package/dist-client/bootstrap.js +8 -0
  25. package/dist-client/bootstrap.js.map +1 -0
  26. package/dist-client/index.d.ts +1 -0
  27. package/dist-client/index.js +2 -0
  28. package/dist-client/index.js.map +1 -0
  29. package/dist-client/pages/action-plan/action-plan-importer.d.ts +9 -0
  30. package/dist-client/pages/action-plan/action-plan-importer.js +100 -0
  31. package/dist-client/pages/action-plan/action-plan-importer.js.map +1 -0
  32. package/dist-client/pages/action-plan/action-plan-list-page.d.ts +62 -0
  33. package/dist-client/pages/action-plan/action-plan-list-page.js +331 -0
  34. package/dist-client/pages/action-plan/action-plan-list-page.js.map +1 -0
  35. package/dist-client/pages/check-item/check-item-importer.d.ts +9 -0
  36. package/dist-client/pages/check-item/check-item-importer.js +100 -0
  37. package/dist-client/pages/check-item/check-item-importer.js.map +1 -0
  38. package/dist-client/pages/check-item/check-item-list-page.d.ts +62 -0
  39. package/dist-client/pages/check-item/check-item-list-page.js +331 -0
  40. package/dist-client/pages/check-item/check-item-list-page.js.map +1 -0
  41. package/dist-client/pages/issue/issue-importer.d.ts +9 -0
  42. package/dist-client/pages/issue/issue-importer.js +100 -0
  43. package/dist-client/pages/issue/issue-importer.js.map +1 -0
  44. package/dist-client/pages/issue/issue-list-page.d.ts +62 -0
  45. package/dist-client/pages/issue/issue-list-page.js +331 -0
  46. package/dist-client/pages/issue/issue-list-page.js.map +1 -0
  47. package/dist-client/pages/main.d.ts +1 -0
  48. package/dist-client/pages/main.js +27 -0
  49. package/dist-client/pages/main.js.map +1 -0
  50. package/dist-client/pages/project-report/project-report-importer.d.ts +9 -0
  51. package/dist-client/pages/project-report/project-report-importer.js +100 -0
  52. package/dist-client/pages/project-report/project-report-importer.js.map +1 -0
  53. package/dist-client/pages/project-report/project-report-list-page.d.ts +62 -0
  54. package/dist-client/pages/project-report/project-report-list-page.js +331 -0
  55. package/dist-client/pages/project-report/project-report-list-page.js.map +1 -0
  56. package/dist-client/pages/supervisor/supervisor-importer.d.ts +9 -0
  57. package/dist-client/pages/supervisor/supervisor-importer.js +100 -0
  58. package/dist-client/pages/supervisor/supervisor-importer.js.map +1 -0
  59. package/dist-client/pages/supervisor/supervisor-list-page.d.ts +62 -0
  60. package/dist-client/pages/supervisor/supervisor-list-page.js +331 -0
  61. package/dist-client/pages/supervisor/supervisor-list-page.js.map +1 -0
  62. package/dist-client/reducers/main.d.ts +6 -0
  63. package/dist-client/reducers/main.js +14 -0
  64. package/dist-client/reducers/main.js.map +1 -0
  65. package/dist-client/route.d.ts +1 -0
  66. package/dist-client/route.js +23 -0
  67. package/dist-client/route.js.map +1 -0
  68. package/dist-client/tsconfig.tsbuildinfo +1 -0
  69. package/dist-server/controllers/index.js +1 -0
  70. package/dist-server/controllers/index.js.map +1 -0
  71. package/dist-server/index.js +7 -0
  72. package/dist-server/index.js.map +1 -0
  73. package/dist-server/middlewares/index.js +8 -0
  74. package/dist-server/middlewares/index.js.map +1 -0
  75. package/dist-server/migrations/index.js +12 -0
  76. package/dist-server/migrations/index.js.map +1 -0
  77. package/dist-server/routes.js +25 -0
  78. package/dist-server/routes.js.map +1 -0
  79. package/dist-server/service/action-plan/action-plan-mutation.js +168 -0
  80. package/dist-server/service/action-plan/action-plan-mutation.js.map +1 -0
  81. package/dist-server/service/action-plan/action-plan-query.js +97 -0
  82. package/dist-server/service/action-plan/action-plan-query.js.map +1 -0
  83. package/dist-server/service/action-plan/action-plan-type.js +86 -0
  84. package/dist-server/service/action-plan/action-plan-type.js.map +1 -0
  85. package/dist-server/service/action-plan/action-plan.js +116 -0
  86. package/dist-server/service/action-plan/action-plan.js.map +1 -0
  87. package/dist-server/service/action-plan/index.js +10 -0
  88. package/dist-server/service/action-plan/index.js.map +1 -0
  89. package/dist-server/service/check-item/check-item-mutation.js +168 -0
  90. package/dist-server/service/check-item/check-item-mutation.js.map +1 -0
  91. package/dist-server/service/check-item/check-item-query.js +97 -0
  92. package/dist-server/service/check-item/check-item-query.js.map +1 -0
  93. package/dist-server/service/check-item/check-item-type.js +86 -0
  94. package/dist-server/service/check-item/check-item-type.js.map +1 -0
  95. package/dist-server/service/check-item/check-item.js +117 -0
  96. package/dist-server/service/check-item/check-item.js.map +1 -0
  97. package/dist-server/service/check-item/index.js +10 -0
  98. package/dist-server/service/check-item/index.js.map +1 -0
  99. package/dist-server/service/index.js +43 -0
  100. package/dist-server/service/index.js.map +1 -0
  101. package/dist-server/service/issue/index.js +10 -0
  102. package/dist-server/service/issue/index.js.map +1 -0
  103. package/dist-server/service/issue/issue-mutation.js +168 -0
  104. package/dist-server/service/issue/issue-mutation.js.map +1 -0
  105. package/dist-server/service/issue/issue-query.js +97 -0
  106. package/dist-server/service/issue/issue-query.js.map +1 -0
  107. package/dist-server/service/issue/issue-type.js +86 -0
  108. package/dist-server/service/issue/issue-type.js.map +1 -0
  109. package/dist-server/service/issue/issue.js +117 -0
  110. package/dist-server/service/issue/issue.js.map +1 -0
  111. package/dist-server/service/project-report/index.js +10 -0
  112. package/dist-server/service/project-report/index.js.map +1 -0
  113. package/dist-server/service/project-report/project-report-mutation.js +168 -0
  114. package/dist-server/service/project-report/project-report-mutation.js.map +1 -0
  115. package/dist-server/service/project-report/project-report-query.js +97 -0
  116. package/dist-server/service/project-report/project-report-query.js.map +1 -0
  117. package/dist-server/service/project-report/project-report-type.js +86 -0
  118. package/dist-server/service/project-report/project-report-type.js.map +1 -0
  119. package/dist-server/service/project-report/project-report.js +128 -0
  120. package/dist-server/service/project-report/project-report.js.map +1 -0
  121. package/dist-server/service/supervisor/index.js +10 -0
  122. package/dist-server/service/supervisor/index.js.map +1 -0
  123. package/dist-server/service/supervisor/supervisor-mutation.js +168 -0
  124. package/dist-server/service/supervisor/supervisor-mutation.js.map +1 -0
  125. package/dist-server/service/supervisor/supervisor-query.js +97 -0
  126. package/dist-server/service/supervisor/supervisor-query.js.map +1 -0
  127. package/dist-server/service/supervisor/supervisor-type.js +86 -0
  128. package/dist-server/service/supervisor/supervisor-type.js.map +1 -0
  129. package/dist-server/service/supervisor/supervisor.js +127 -0
  130. package/dist-server/service/supervisor/supervisor.js.map +1 -0
  131. package/dist-server/tsconfig.tsbuildinfo +1 -0
  132. package/helps/supervision/action-plan.md +160 -0
  133. package/helps/supervision/check-item.md +160 -0
  134. package/helps/supervision/issue.md +160 -0
  135. package/helps/supervision/project-report.md +160 -0
  136. package/helps/supervision/supervisor.md +160 -0
  137. package/package.json +37 -0
  138. package/server/controllers/index.ts +0 -0
  139. package/server/index.ts +4 -0
  140. package/server/middlewares/index.ts +3 -0
  141. package/server/migrations/index.ts +9 -0
  142. package/server/routes.ts +28 -0
  143. package/server/service/action-plan/action-plan-mutation.ts +198 -0
  144. package/server/service/action-plan/action-plan-query.ts +62 -0
  145. package/server/service/action-plan/action-plan-type.ts +61 -0
  146. package/server/service/action-plan/action-plan.ts +103 -0
  147. package/server/service/action-plan/index.ts +7 -0
  148. package/server/service/check-item/check-item-mutation.ts +198 -0
  149. package/server/service/check-item/check-item-query.ts +62 -0
  150. package/server/service/check-item/check-item-type.ts +61 -0
  151. package/server/service/check-item/check-item.ts +111 -0
  152. package/server/service/check-item/index.ts +7 -0
  153. package/server/service/index.ts +42 -0
  154. package/server/service/issue/index.ts +7 -0
  155. package/server/service/issue/issue-mutation.ts +198 -0
  156. package/server/service/issue/issue-query.ts +62 -0
  157. package/server/service/issue/issue-type.ts +61 -0
  158. package/server/service/issue/issue.ts +105 -0
  159. package/server/service/project-report/index.ts +7 -0
  160. package/server/service/project-report/project-report-mutation.ts +198 -0
  161. package/server/service/project-report/project-report-query.ts +62 -0
  162. package/server/service/project-report/project-report-type.ts +61 -0
  163. package/server/service/project-report/project-report.ts +113 -0
  164. package/server/service/supervisor/index.ts +7 -0
  165. package/server/service/supervisor/supervisor-mutation.ts +198 -0
  166. package/server/service/supervisor/supervisor-query.ts +62 -0
  167. package/server/service/supervisor/supervisor-type.ts +61 -0
  168. package/server/service/supervisor/supervisor.ts +113 -0
  169. package/server/tsconfig.json +10 -0
  170. package/things-factory.config.js +15 -0
  171. package/translations/en.json +1 -0
  172. package/translations/ko.json +1 -0
  173. package/translations/ms.json +1 -0
  174. package/translations/zh.json +1 -0
@@ -0,0 +1,198 @@
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 { CheckItem } from './check-item'
7
+ import { NewCheckItem, CheckItemPatch } from './check-item-type'
8
+
9
+ @Resolver(CheckItem)
10
+ export class CheckItemMutation {
11
+ @Directive('@transaction')
12
+ @Mutation(returns => CheckItem, { description: 'To create new CheckItem' })
13
+ async createCheckItem(@Arg('checkItem') checkItem: NewCheckItem, @Ctx() context: ResolverContext): Promise<CheckItem> {
14
+ const { domain, user, tx } = context.state
15
+
16
+ const result = await tx.getRepository(CheckItem).save({
17
+ ...checkItem,
18
+ domain,
19
+ creator: user,
20
+ updater: user
21
+ })
22
+
23
+ if (checkItem.thumbnail) {
24
+ await createAttachment(
25
+ null,
26
+ {
27
+ attachment: {
28
+ file: checkItem.thumbnail,
29
+ refType: CheckItem.name,
30
+ refBy: result.id
31
+ }
32
+ },
33
+ context
34
+ )
35
+ }
36
+
37
+ return result
38
+ }
39
+
40
+ @Directive('@transaction')
41
+ @Mutation(returns => CheckItem, { description: 'To modify CheckItem information' })
42
+ async updateCheckItem(
43
+ @Arg('id') id: string,
44
+ @Arg('patch') patch: CheckItemPatch,
45
+ @Ctx() context: ResolverContext
46
+ ): Promise<CheckItem> {
47
+ const { domain, user, tx } = context.state
48
+
49
+ const repository = tx.getRepository(CheckItem)
50
+ const checkItem = await repository.findOne({
51
+ where: { domain: { id: domain.id }, id }
52
+ })
53
+
54
+ const result = await repository.save({
55
+ ...checkItem,
56
+ ...patch,
57
+ updater: user
58
+ })
59
+
60
+ if (patch.thumbnail) {
61
+ await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)
62
+ await createAttachment(
63
+ null,
64
+ {
65
+ attachment: {
66
+ file: patch.thumbnail,
67
+ refType: CheckItem.name,
68
+ refBy: result.id
69
+ }
70
+ },
71
+ context
72
+ )
73
+ }
74
+
75
+ return result
76
+ }
77
+
78
+ @Directive('@transaction')
79
+ @Mutation(returns => [CheckItem], { description: "To modify multiple CheckItems' information" })
80
+ async updateMultipleCheckItem(
81
+ @Arg('patches', type => [CheckItemPatch]) patches: CheckItemPatch[],
82
+ @Ctx() context: ResolverContext
83
+ ): Promise<CheckItem[]> {
84
+ const { domain, user, tx } = context.state
85
+
86
+ let results = []
87
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
88
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
89
+ const checkItemRepo = tx.getRepository(CheckItem)
90
+
91
+ if (_createRecords.length > 0) {
92
+ for (let i = 0; i < _createRecords.length; i++) {
93
+ const newRecord = _createRecords[i]
94
+
95
+ const result = await checkItemRepo.save({
96
+ ...newRecord,
97
+ domain,
98
+ creator: user,
99
+ updater: user
100
+ })
101
+
102
+ if (newRecord.thumbnail) {
103
+ await createAttachment(
104
+ null,
105
+ {
106
+ attachment: {
107
+ file: newRecord.thumbnail,
108
+ refType: CheckItem.name,
109
+ refBy: result.id
110
+ }
111
+ },
112
+ context
113
+ )
114
+ }
115
+
116
+ results.push({ ...result, cuFlag: '+' })
117
+ }
118
+ }
119
+
120
+ if (_updateRecords.length > 0) {
121
+ for (let i = 0; i < _updateRecords.length; i++) {
122
+ const updateRecord = _updateRecords[i]
123
+ const checkItem = await checkItemRepo.findOneBy({ id: updateRecord.id })
124
+
125
+ const result = await checkItemRepo.save({
126
+ ...checkItem,
127
+ ...updateRecord,
128
+ updater: user
129
+ })
130
+
131
+ if (updateRecord.thumbnail) {
132
+ await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)
133
+ await createAttachment(
134
+ null,
135
+ {
136
+ attachment: {
137
+ file: updateRecord.thumbnail,
138
+ refType: CheckItem.name,
139
+ refBy: result.id
140
+ }
141
+ },
142
+ context
143
+ )
144
+ }
145
+
146
+ results.push({ ...result, cuFlag: 'M' })
147
+ }
148
+ }
149
+
150
+ return results
151
+ }
152
+
153
+ @Directive('@transaction')
154
+ @Mutation(returns => Boolean, { description: 'To delete CheckItem' })
155
+ async deleteCheckItem(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
156
+ const { domain, tx } = context.state
157
+
158
+ await tx.getRepository(CheckItem).delete({ domain: { id: domain.id }, id })
159
+ await deleteAttachmentsByRef(null, { refBys: [id] }, context)
160
+
161
+ return true
162
+ }
163
+
164
+ @Directive('@transaction')
165
+ @Mutation(returns => Boolean, { description: 'To delete multiple CheckItems' })
166
+ async deleteCheckItems(
167
+ @Arg('ids', type => [String]) ids: string[],
168
+ @Ctx() context: ResolverContext
169
+ ): Promise<boolean> {
170
+ const { domain, tx } = context.state
171
+
172
+ await tx.getRepository(CheckItem).delete({
173
+ domain: { id: domain.id },
174
+ id: In(ids)
175
+ })
176
+
177
+ await deleteAttachmentsByRef(null, { refBys: ids }, context)
178
+
179
+ return true
180
+ }
181
+
182
+ @Directive('@transaction')
183
+ @Mutation(returns => Boolean, { description: 'To import multiple CheckItems' })
184
+ async importCheckItems(
185
+ @Arg('checkItems', type => [CheckItemPatch]) checkItems: CheckItemPatch[],
186
+ @Ctx() context: ResolverContext
187
+ ): Promise<boolean> {
188
+ const { domain, tx } = context.state
189
+
190
+ await Promise.all(
191
+ checkItems.map(async (checkItem: CheckItemPatch) => {
192
+ const createdCheckItem: CheckItem = await tx.getRepository(CheckItem).save({ domain, ...checkItem })
193
+ })
194
+ )
195
+
196
+ return true
197
+ }
198
+ }
@@ -0,0 +1,62 @@
1
+ import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
2
+ import { Attachment } from '@things-factory/attachment-base'
3
+ import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
4
+ import { User } from '@things-factory/auth-base'
5
+ import { CheckItem } from './check-item'
6
+ import { CheckItemList } from './check-item-type'
7
+
8
+ @Resolver(CheckItem)
9
+ export class CheckItemQuery {
10
+ @Query(returns => CheckItem!, { nullable: true, description: 'To fetch a CheckItem' })
11
+ async checkItem(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<CheckItem> {
12
+ const { domain } = context.state
13
+
14
+ return await getRepository(CheckItem).findOne({
15
+ where: { domain: { id: domain.id }, id }
16
+ })
17
+ }
18
+
19
+ @Query(returns => CheckItemList, { description: 'To fetch multiple CheckItems' })
20
+ async checkItems(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<CheckItemList> {
21
+ const { domain } = context.state
22
+
23
+ const queryBuilder = getQueryBuilderFromListParams({
24
+ domain,
25
+ params,
26
+ repository: await getRepository(CheckItem),
27
+ searchables: ['name', 'description']
28
+ })
29
+
30
+ const [items, total] = await queryBuilder.getManyAndCount()
31
+
32
+ return { items, total }
33
+ }
34
+
35
+ @FieldResolver(type => String)
36
+ async thumbnail(@Root() checkItem: CheckItem): Promise<string | undefined> {
37
+ const attachment: Attachment = await getRepository(Attachment).findOne({
38
+ where: {
39
+ domain: { id: checkItem.domainId },
40
+ refType: CheckItem.name,
41
+ refBy: checkItem.id
42
+ }
43
+ })
44
+
45
+ return attachment?.fullpath
46
+ }
47
+
48
+ @FieldResolver(type => Domain)
49
+ async domain(@Root() checkItem: CheckItem): Promise<Domain> {
50
+ return await getRepository(Domain).findOneBy({ id: checkItem.domainId })
51
+ }
52
+
53
+ @FieldResolver(type => User)
54
+ async updater(@Root() checkItem: CheckItem): Promise<User> {
55
+ return await getRepository(User).findOneBy({ id: checkItem.updaterId })
56
+ }
57
+
58
+ @FieldResolver(type => User)
59
+ async creator(@Root() checkItem: CheckItem): Promise<User> {
60
+ return await getRepository(User).findOneBy({ id: checkItem.creatorId })
61
+ }
62
+ }
@@ -0,0 +1,61 @@
1
+ import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'
2
+ import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'
3
+ import { ObjectType, Field, InputType, Int, ID, registerEnumType } from 'type-graphql'
4
+
5
+ import { ObjectRef, ScalarObject } from '@things-factory/shell'
6
+
7
+ import { CheckItem, CheckItemStatus } from './check-item'
8
+
9
+ @InputType()
10
+ export class NewCheckItem {
11
+ @Field()
12
+ name: string
13
+
14
+ @Field({ nullable: true })
15
+ description?: string
16
+
17
+ @Field(type => CheckItemStatus, { nullable: true })
18
+ state?: CheckItemStatus
19
+
20
+ @Field({ nullable: true })
21
+ active?: boolean
22
+
23
+ @Field({ nullable: true })
24
+ params?: string
25
+
26
+ @Field(type => GraphQLUpload, { nullable: true })
27
+ thumbnail?: FileUpload
28
+ }
29
+
30
+ @InputType()
31
+ export class CheckItemPatch {
32
+ @Field(type => ID, { nullable: true })
33
+ id?: string
34
+
35
+ @Field({ nullable: true })
36
+ name?: string
37
+
38
+ @Field({ nullable: true })
39
+ description?: string
40
+
41
+ @Field(type => CheckItemStatus, { nullable: true })
42
+ state?: CheckItemStatus
43
+
44
+ @Field({ nullable: true })
45
+ active?: boolean
46
+
47
+ @Field(type => GraphQLUpload, { nullable: true })
48
+ thumbnail?: FileUpload
49
+
50
+ @Field({ nullable: true })
51
+ cuFlag?: string
52
+ }
53
+
54
+ @ObjectType()
55
+ export class CheckItemList {
56
+ @Field(type => [CheckItem])
57
+ items: CheckItem[]
58
+
59
+ @Field(type => Int)
60
+ total: number
61
+ }
@@ -0,0 +1,111 @@
1
+ import {
2
+ CreateDateColumn,
3
+ UpdateDateColumn,
4
+ DeleteDateColumn,
5
+ Entity,
6
+ Index,
7
+ Column,
8
+ RelationId,
9
+ ManyToOne,
10
+ OneToMany,
11
+ PrimaryGeneratedColumn,
12
+ VersionColumn
13
+ } from 'typeorm'
14
+ import { ObjectType, Field, Int, ID, registerEnumType } from 'type-graphql'
15
+
16
+ import { Domain } from '@things-factory/shell'
17
+ import { User } from '@things-factory/auth-base'
18
+ import { Task } from '@dssp/project'
19
+
20
+ import { Issue } from '../issue/issue'
21
+ import { Supervisor } from '../supervisor/supervisor'
22
+
23
+ export enum CheckItemStatus {
24
+ STATUS_A = 'STATUS_A',
25
+ STATUS_B = 'STATUS_B'
26
+ }
27
+
28
+ registerEnumType(CheckItemStatus, {
29
+ name: 'CheckItemStatus',
30
+ description: 'state enumeration of a checkItem'
31
+ })
32
+
33
+ @Entity()
34
+ @Index('ix_check_item_0', (checkItem: CheckItem) => [checkItem.domain, checkItem.name], {
35
+ unique: true,
36
+ where: '"deleted_at" IS NULL'
37
+ })
38
+ @ObjectType({ description: 'Entity for CheckItem' })
39
+ export class CheckItem {
40
+ @PrimaryGeneratedColumn('uuid')
41
+ @Field(type => ID)
42
+ readonly id: string
43
+
44
+ @ManyToOne(type => Domain)
45
+ @Field({ nullable: true })
46
+ domain?: Domain
47
+
48
+ @RelationId((checkItem: CheckItem) => checkItem.domain)
49
+ domainId?: string
50
+
51
+ @Column()
52
+ @Field({ nullable: true })
53
+ name?: string
54
+
55
+ @Column({ nullable: true })
56
+ @Field({ nullable: true })
57
+ description?: string
58
+
59
+ @Column({ nullable: true })
60
+ @Field({ nullable: true })
61
+ active?: boolean
62
+
63
+ @Column({ nullable: true })
64
+ @Field({ nullable: true })
65
+ state?: CheckItemStatus
66
+
67
+ @Column({ nullable: true })
68
+ @Field({ nullable: true })
69
+ params?: string
70
+
71
+ // @Field(() => Task)
72
+ // @ManyToOne(() => Task, task => task.checkItems)
73
+ // task: Task
74
+
75
+ @Field(() => Supervisor)
76
+ @ManyToOne(() => Supervisor, supervisor => supervisor.checkItems)
77
+ supervisor: Supervisor
78
+
79
+ @Field(() => [Issue])
80
+ @OneToMany(() => Issue, issue => issue.checkItem)
81
+ issues: Issue[]
82
+
83
+ @CreateDateColumn()
84
+ @Field({ nullable: true })
85
+ createdAt?: Date
86
+
87
+ @UpdateDateColumn()
88
+ @Field({ nullable: true })
89
+ updatedAt?: Date
90
+
91
+ @DeleteDateColumn()
92
+ @Field({ nullable: true })
93
+ deletedAt?: Date
94
+
95
+ @ManyToOne(type => User, { nullable: true })
96
+ @Field(type => User, { nullable: true })
97
+ creator?: User
98
+
99
+ @RelationId((checkItem: CheckItem) => checkItem.creator)
100
+ creatorId?: string
101
+
102
+ @ManyToOne(type => User, { nullable: true })
103
+ @Field(type => User, { nullable: true })
104
+ updater?: User
105
+
106
+ @RelationId((checkItem: CheckItem) => checkItem.updater)
107
+ updaterId?: string
108
+
109
+ @Field(type => String, { nullable: true })
110
+ thumbnail?: string
111
+ }
@@ -0,0 +1,7 @@
1
+ import { CheckItem } from './check-item'
2
+ import { CheckItemQuery } from './check-item-query'
3
+ import { CheckItemMutation } from './check-item-mutation'
4
+
5
+ export const entities = [CheckItem]
6
+ export const resolvers = [CheckItemQuery, CheckItemMutation]
7
+ export const subscribers = []
@@ -0,0 +1,42 @@
1
+ /* EXPORT ENTITY TYPES */
2
+ export * from './action-plan/action-plan'
3
+ export * from './issue/issue'
4
+ export * from './check-item/check-item'
5
+ export * from './project-report/project-report'
6
+ export * from './supervisor/supervisor'
7
+
8
+ /* IMPORT ENTITIES AND RESOLVERS */
9
+ import { entities as ActionPlanEntities, resolvers as ActionPlanResolvers, subscribers as ActionPlanSubscribers } from './action-plan'
10
+ import { entities as IssueEntities, resolvers as IssueResolvers, subscribers as IssueSubscribers } from './issue'
11
+ import { entities as CheckItemEntities, resolvers as CheckItemResolvers, subscribers as CheckItemSubscribers } from './check-item'
12
+ import { entities as ProjectReportEntities, resolvers as ProjectReportResolvers, subscribers as ProjectReportSubscribers } from './project-report'
13
+ import { entities as SupervisorEntities, resolvers as SupervisorResolvers, subscribers as SupervisorSubscribers } from './supervisor'
14
+
15
+ export const entities = [
16
+ /* ENTITIES */
17
+ ...ActionPlanEntities,
18
+ ...IssueEntities,
19
+ ...CheckItemEntities,
20
+ ...ProjectReportEntities,
21
+ ...SupervisorEntities,
22
+ ]
23
+
24
+ export const subscribers = [
25
+ /* SUBSCRIBERS */
26
+ ...ActionPlanSubscribers,
27
+ ...IssueSubscribers,
28
+ ...CheckItemSubscribers,
29
+ ...ProjectReportSubscribers,
30
+ ...SupervisorSubscribers,
31
+ ]
32
+
33
+ export const schema = {
34
+ resolverClasses: [
35
+ /* RESOLVER CLASSES */
36
+ ...ActionPlanResolvers,
37
+ ...IssueResolvers,
38
+ ...CheckItemResolvers,
39
+ ...ProjectReportResolvers,
40
+ ...SupervisorResolvers,
41
+ ]
42
+ }
@@ -0,0 +1,7 @@
1
+ import { Issue } from './issue'
2
+ import { IssueQuery } from './issue-query'
3
+ import { IssueMutation } from './issue-mutation'
4
+
5
+ export const entities = [Issue]
6
+ export const resolvers = [IssueQuery, IssueMutation]
7
+ export const subscribers = []
@@ -0,0 +1,198 @@
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 { Issue } from './issue'
7
+ import { NewIssue, IssuePatch } from './issue-type'
8
+
9
+ @Resolver(Issue)
10
+ export class IssueMutation {
11
+ @Directive('@transaction')
12
+ @Mutation(returns => Issue, { description: 'To create new Issue' })
13
+ async createIssue(@Arg('issue') issue: NewIssue, @Ctx() context: ResolverContext): Promise<Issue> {
14
+ const { domain, user, tx } = context.state
15
+
16
+ const result = await tx.getRepository(Issue).save({
17
+ ...issue,
18
+ domain,
19
+ creator: user,
20
+ updater: user
21
+ })
22
+
23
+ if (issue.thumbnail) {
24
+ await createAttachment(
25
+ null,
26
+ {
27
+ attachment: {
28
+ file: issue.thumbnail,
29
+ refType: Issue.name,
30
+ refBy: result.id
31
+ }
32
+ },
33
+ context
34
+ )
35
+ }
36
+
37
+ return result
38
+ }
39
+
40
+ @Directive('@transaction')
41
+ @Mutation(returns => Issue, { description: 'To modify Issue information' })
42
+ async updateIssue(
43
+ @Arg('id') id: string,
44
+ @Arg('patch') patch: IssuePatch,
45
+ @Ctx() context: ResolverContext
46
+ ): Promise<Issue> {
47
+ const { domain, user, tx } = context.state
48
+
49
+ const repository = tx.getRepository(Issue)
50
+ const issue = await repository.findOne({
51
+ where: { domain: { id: domain.id }, id }
52
+ })
53
+
54
+ const result = await repository.save({
55
+ ...issue,
56
+ ...patch,
57
+ updater: user
58
+ })
59
+
60
+ if (patch.thumbnail) {
61
+ await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)
62
+ await createAttachment(
63
+ null,
64
+ {
65
+ attachment: {
66
+ file: patch.thumbnail,
67
+ refType: Issue.name,
68
+ refBy: result.id
69
+ }
70
+ },
71
+ context
72
+ )
73
+ }
74
+
75
+ return result
76
+ }
77
+
78
+ @Directive('@transaction')
79
+ @Mutation(returns => [Issue], { description: "To modify multiple Issues' information" })
80
+ async updateMultipleIssue(
81
+ @Arg('patches', type => [IssuePatch]) patches: IssuePatch[],
82
+ @Ctx() context: ResolverContext
83
+ ): Promise<Issue[]> {
84
+ const { domain, user, tx } = context.state
85
+
86
+ let results = []
87
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
88
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
89
+ const issueRepo = tx.getRepository(Issue)
90
+
91
+ if (_createRecords.length > 0) {
92
+ for (let i = 0; i < _createRecords.length; i++) {
93
+ const newRecord = _createRecords[i]
94
+
95
+ const result = await issueRepo.save({
96
+ ...newRecord,
97
+ domain,
98
+ creator: user,
99
+ updater: user
100
+ })
101
+
102
+ if (newRecord.thumbnail) {
103
+ await createAttachment(
104
+ null,
105
+ {
106
+ attachment: {
107
+ file: newRecord.thumbnail,
108
+ refType: Issue.name,
109
+ refBy: result.id
110
+ }
111
+ },
112
+ context
113
+ )
114
+ }
115
+
116
+ results.push({ ...result, cuFlag: '+' })
117
+ }
118
+ }
119
+
120
+ if (_updateRecords.length > 0) {
121
+ for (let i = 0; i < _updateRecords.length; i++) {
122
+ const updateRecord = _updateRecords[i]
123
+ const issue = await issueRepo.findOneBy({ id: updateRecord.id })
124
+
125
+ const result = await issueRepo.save({
126
+ ...issue,
127
+ ...updateRecord,
128
+ updater: user
129
+ })
130
+
131
+ if (updateRecord.thumbnail) {
132
+ await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)
133
+ await createAttachment(
134
+ null,
135
+ {
136
+ attachment: {
137
+ file: updateRecord.thumbnail,
138
+ refType: Issue.name,
139
+ refBy: result.id
140
+ }
141
+ },
142
+ context
143
+ )
144
+ }
145
+
146
+ results.push({ ...result, cuFlag: 'M' })
147
+ }
148
+ }
149
+
150
+ return results
151
+ }
152
+
153
+ @Directive('@transaction')
154
+ @Mutation(returns => Boolean, { description: 'To delete Issue' })
155
+ async deleteIssue(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
156
+ const { domain, tx } = context.state
157
+
158
+ await tx.getRepository(Issue).delete({ domain: { id: domain.id }, id })
159
+ await deleteAttachmentsByRef(null, { refBys: [id] }, context)
160
+
161
+ return true
162
+ }
163
+
164
+ @Directive('@transaction')
165
+ @Mutation(returns => Boolean, { description: 'To delete multiple Issues' })
166
+ async deleteIssues(
167
+ @Arg('ids', type => [String]) ids: string[],
168
+ @Ctx() context: ResolverContext
169
+ ): Promise<boolean> {
170
+ const { domain, tx } = context.state
171
+
172
+ await tx.getRepository(Issue).delete({
173
+ domain: { id: domain.id },
174
+ id: In(ids)
175
+ })
176
+
177
+ await deleteAttachmentsByRef(null, { refBys: ids }, context)
178
+
179
+ return true
180
+ }
181
+
182
+ @Directive('@transaction')
183
+ @Mutation(returns => Boolean, { description: 'To import multiple Issues' })
184
+ async importIssues(
185
+ @Arg('issues', type => [IssuePatch]) issues: IssuePatch[],
186
+ @Ctx() context: ResolverContext
187
+ ): Promise<boolean> {
188
+ const { domain, tx } = context.state
189
+
190
+ await Promise.all(
191
+ issues.map(async (issue: IssuePatch) => {
192
+ const createdIssue: Issue = await tx.getRepository(Issue).save({ domain, ...issue })
193
+ })
194
+ )
195
+
196
+ return true
197
+ }
198
+ }