@things-factory/dataset 8.0.0-beta.9 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. package/client/activities/activity-data-collect-edit.ts +105 -0
  2. package/client/activities/activity-data-collect-view.ts +91 -0
  3. package/client/activities/activity-data-review-edit.ts +133 -0
  4. package/client/activities/activity-data-review-view.ts +145 -0
  5. package/client/activities/activity-ooc-resolve-edit.ts +195 -0
  6. package/client/activities/activity-ooc-resolve-view.ts +143 -0
  7. package/client/activities/activity-ooc-review-edit.ts +173 -0
  8. package/client/activities/activity-ooc-review-view.ts +129 -0
  9. package/client/bootstrap.ts +35 -0
  10. package/client/components/data-entry-form.ts +109 -0
  11. package/client/index.ts +1 -0
  12. package/client/pages/data-archive/data-archive-list-page.ts +277 -0
  13. package/client/pages/data-archive/data-archive-request-popup.ts +177 -0
  14. package/client/pages/data-entry/data-entry-list-page.ts +464 -0
  15. package/client/pages/data-key-set/data-key-item-list.ts +183 -0
  16. package/client/pages/data-key-set/data-key-set-importer.ts +89 -0
  17. package/client/pages/data-key-set/data-key-set-list-page.ts +413 -0
  18. package/client/pages/data-ooc/data-ooc-list-page.ts +549 -0
  19. package/client/pages/data-ooc/data-ooc-page.ts +164 -0
  20. package/client/pages/data-ooc/data-ooc-view.ts +236 -0
  21. package/client/pages/data-ooc/data-oocs-page.ts +200 -0
  22. package/client/pages/data-report/data-report-embed-page.ts +108 -0
  23. package/client/pages/data-report/data-report-list-page.ts +454 -0
  24. package/client/pages/data-report/data-report-samples-page.ts +174 -0
  25. package/client/pages/data-report/jasper-report-oocs-page.ts +110 -0
  26. package/client/pages/data-report/jasper-report-samples-crosstab-page.ts +110 -0
  27. package/client/pages/data-report/jasper-report-samples-page.ts +110 -0
  28. package/client/pages/data-sample/data-sample-list-page.ts +442 -0
  29. package/client/pages/data-sample/data-sample-page.ts +55 -0
  30. package/client/pages/data-sample/data-sample-search-page.ts +424 -0
  31. package/client/pages/data-sample/data-sample-view.ts +292 -0
  32. package/client/pages/data-sample/data-samples-page.ts +249 -0
  33. package/client/pages/data-sensor/data-sensor-list-page.ts +456 -0
  34. package/client/pages/data-set/data-item-list.ts +304 -0
  35. package/client/pages/data-set/data-set-importer.ts +89 -0
  36. package/client/pages/data-set/data-set-list-page.ts +1078 -0
  37. package/client/pages/data-summary/data-summary-list-page.ts +363 -0
  38. package/client/pages/data-summary/data-summary-period-page.ts +439 -0
  39. package/client/pages/data-summary/data-summary-search-page.ts +426 -0
  40. package/client/pages/data-summary/data-summary-view.ts +133 -0
  41. package/client/route.ts +91 -0
  42. package/client/tsconfig.json +13 -0
  43. package/dist-client/activities/activity-data-review-edit.d.ts +1 -5
  44. package/dist-client/activities/activity-data-review-edit.js +5 -143
  45. package/dist-client/activities/activity-data-review-edit.js.map +1 -1
  46. package/dist-client/pages/data-entry/data-entry-list-page.js +2 -2
  47. package/dist-client/pages/data-entry/data-entry-list-page.js.map +1 -1
  48. package/dist-client/tsconfig.tsbuildinfo +1 -1
  49. package/dist-server/activities/activity-data-review.js +5 -18
  50. package/dist-server/activities/activity-data-review.js.map +1 -1
  51. package/dist-server/activities/activity-ooc-review.js +52 -13
  52. package/dist-server/activities/activity-ooc-review.js.map +1 -1
  53. package/dist-server/controllers/create-data-sample.js +94 -4
  54. package/dist-server/controllers/create-data-sample.js.map +1 -1
  55. package/dist-server/controllers/index.d.ts +0 -3
  56. package/dist-server/controllers/index.js +0 -3
  57. package/dist-server/controllers/index.js.map +1 -1
  58. package/dist-server/service/data-sample/data-sample-query.d.ts +1 -1
  59. package/dist-server/service/data-sample/data-sample-query.js +3 -3
  60. package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
  61. package/dist-server/service/index.d.ts +1 -1
  62. package/dist-server/tsconfig.tsbuildinfo +1 -1
  63. package/package.json +26 -26
  64. package/server/activities/activity-data-collect.ts +100 -0
  65. package/server/activities/activity-data-review.ts +82 -0
  66. package/server/activities/activity-ooc-resolve.ts +123 -0
  67. package/server/activities/activity-ooc-review.ts +144 -0
  68. package/server/activities/index.ts +11 -0
  69. package/server/controllers/create-data-sample.ts +426 -0
  70. package/server/controllers/data-use-case.ts +98 -0
  71. package/server/controllers/finalize-data-collection.ts +388 -0
  72. package/server/controllers/index.ts +3 -0
  73. package/server/controllers/issue-data-collection-task.ts +70 -0
  74. package/server/controllers/jasper-report.ts +186 -0
  75. package/server/controllers/query-data-summary-by-period.ts +178 -0
  76. package/server/controllers/shiny-report.ts +54 -0
  77. package/server/engine/index.ts +1 -0
  78. package/server/engine/task/create-data-sample.ts +100 -0
  79. package/server/engine/task/index.ts +2 -0
  80. package/server/engine/task/issue-collect-data.ts +45 -0
  81. package/server/index.ts +8 -0
  82. package/server/routes.ts +188 -0
  83. package/server/service/data-archive/data-archive-mutation.ts +273 -0
  84. package/server/service/data-archive/data-archive-query.ts +58 -0
  85. package/server/service/data-archive/data-archive-type.ts +48 -0
  86. package/server/service/data-archive/data-archive.ts +69 -0
  87. package/server/service/data-archive/index.ts +6 -0
  88. package/server/service/data-key-set/data-key-item-type.ts +31 -0
  89. package/server/service/data-key-set/data-key-set-mutation.ts +201 -0
  90. package/server/service/data-key-set/data-key-set-query.ts +68 -0
  91. package/server/service/data-key-set/data-key-set-type.ts +70 -0
  92. package/server/service/data-key-set/data-key-set.ts +86 -0
  93. package/server/service/data-key-set/index.ts +6 -0
  94. package/server/service/data-ooc/data-ooc-mutation.ts +154 -0
  95. package/server/service/data-ooc/data-ooc-query.ts +106 -0
  96. package/server/service/data-ooc/data-ooc-subscription.ts +48 -0
  97. package/server/service/data-ooc/data-ooc-type.ts +71 -0
  98. package/server/service/data-ooc/data-ooc.ts +259 -0
  99. package/server/service/data-ooc/index.ts +7 -0
  100. package/server/service/data-sample/data-sample-mutation.ts +18 -0
  101. package/server/service/data-sample/data-sample-query.ts +215 -0
  102. package/server/service/data-sample/data-sample-type.ts +47 -0
  103. package/server/service/data-sample/data-sample.ts +193 -0
  104. package/server/service/data-sample/index.ts +6 -0
  105. package/server/service/data-sensor/data-sensor-mutation.ts +116 -0
  106. package/server/service/data-sensor/data-sensor-query.ts +76 -0
  107. package/server/service/data-sensor/data-sensor-type.ts +104 -0
  108. package/server/service/data-sensor/data-sensor.ts +126 -0
  109. package/server/service/data-sensor/index.ts +6 -0
  110. package/server/service/data-set/data-item-type.ts +155 -0
  111. package/server/service/data-set/data-set-mutation.ts +552 -0
  112. package/server/service/data-set/data-set-query.ts +461 -0
  113. package/server/service/data-set/data-set-type.ts +204 -0
  114. package/server/service/data-set/data-set.ts +326 -0
  115. package/server/service/data-set/index.ts +6 -0
  116. package/server/service/data-set-history/data-set-history-query.ts +126 -0
  117. package/server/service/data-set-history/data-set-history-type.ts +12 -0
  118. package/server/service/data-set-history/data-set-history.ts +217 -0
  119. package/server/service/data-set-history/event-subscriber.ts +17 -0
  120. package/server/service/data-set-history/index.ts +7 -0
  121. package/server/service/data-spec/data-spec-manager.ts +21 -0
  122. package/server/service/data-spec/data-spec-query.ts +21 -0
  123. package/server/service/data-spec/data-spec.ts +45 -0
  124. package/server/service/data-spec/index.ts +5 -0
  125. package/server/service/data-summary/data-summary-mutation.ts +45 -0
  126. package/server/service/data-summary/data-summary-query.ts +179 -0
  127. package/server/service/data-summary/data-summary-type.ts +86 -0
  128. package/server/service/data-summary/data-summary.ts +170 -0
  129. package/server/service/data-summary/index.ts +7 -0
  130. package/server/service/index.ts +57 -0
  131. package/server/tsconfig.json +10 -0
  132. package/server/utils/config-resolver.ts +29 -0
  133. package/server/utils/index.ts +1 -0
  134. package/translations/en.json +0 -3
  135. package/translations/ja.json +0 -3
  136. package/translations/ko.json +0 -3
  137. package/translations/ms.json +0 -3
  138. package/translations/zh.json +0 -3
  139. package/dist-server/controllers/create-data-ooc.d.ts +0 -4
  140. package/dist-server/controllers/create-data-ooc.js +0 -65
  141. package/dist-server/controllers/create-data-ooc.js.map +0 -1
  142. package/dist-server/controllers/issue-ooc-resolve.d.ts +0 -3
  143. package/dist-server/controllers/issue-ooc-resolve.js +0 -49
  144. package/dist-server/controllers/issue-ooc-resolve.js.map +0 -1
  145. package/dist-server/controllers/issue-ooc-review.d.ts +0 -3
  146. package/dist-server/controllers/issue-ooc-review.js +0 -47
  147. package/dist-server/controllers/issue-ooc-review.js.map +0 -1
@@ -0,0 +1,68 @@
1
+ import { In } from 'typeorm'
2
+ import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
3
+
4
+ import { Attachment } from '@things-factory/attachment-base'
5
+ import { User } from '@things-factory/auth-base'
6
+ import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
7
+
8
+ import { DataKeySet } from './data-key-set'
9
+ import { DataKeySetList } from './data-key-set-type'
10
+
11
+ @Resolver(DataKeySet)
12
+ export class DataKeySetQuery {
13
+ @Query(returns => DataKeySet!, { nullable: true, description: 'To fetch a DataKeySet' })
14
+ async dataKeySet(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<DataKeySet> {
15
+ const { domain } = context.state
16
+
17
+ return await getRepository(DataKeySet).findOne({
18
+ where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id }
19
+ })
20
+ }
21
+
22
+ @Query(returns => DataKeySetList, { description: 'To fetch multiple DataKeySets' })
23
+ async dataKeySets(
24
+ @Args(type => ListParam) params: ListParam,
25
+ @Ctx() context: ResolverContext
26
+ ): Promise<DataKeySetList> {
27
+ const { domain } = context.state
28
+
29
+ const queryBuilder = getQueryBuilderFromListParams({
30
+ domain,
31
+ params,
32
+ repository: await getRepository(DataKeySet),
33
+ searchables: ['name', 'description']
34
+ })
35
+
36
+ const [items, total] = await queryBuilder.getManyAndCount()
37
+
38
+ return { items, total }
39
+ }
40
+
41
+ @FieldResolver(type => String)
42
+ async thumbnail(@Root() dataKeySet: DataKeySet): Promise<string | undefined> {
43
+ const attachment: Attachment = await getRepository(Attachment).findOne({
44
+ where: {
45
+ domain: { id: dataKeySet.domainId },
46
+ refType: DataKeySet.name,
47
+ refBy: dataKeySet.id
48
+ }
49
+ })
50
+
51
+ return attachment?.fullpath
52
+ }
53
+
54
+ @FieldResolver(type => Domain)
55
+ async domain(@Root() dataKeySet: DataKeySet): Promise<Domain> {
56
+ return dataKeySet.domainId && (await getRepository(Domain).findOneBy({ id: dataKeySet.domainId }))
57
+ }
58
+
59
+ @FieldResolver(type => User)
60
+ async updater(@Root() dataKeySet: DataKeySet): Promise<User> {
61
+ return dataKeySet.updaterId && (await getRepository(User).findOneBy({ id: dataKeySet.updaterId }))
62
+ }
63
+
64
+ @FieldResolver(type => User)
65
+ async creator(@Root() dataKeySet: DataKeySet): Promise<User> {
66
+ return dataKeySet.creatorId && (await getRepository(User).findOneBy({ id: dataKeySet.creatorId }))
67
+ }
68
+ }
@@ -0,0 +1,70 @@
1
+ import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'
2
+ import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'
3
+ import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
4
+
5
+ import { DataKeyItemPatch } from './data-key-item-type'
6
+ import { DataKeySet } from './data-key-set'
7
+ import { DataSetReportType } from '../data-set/data-set'
8
+
9
+ @InputType()
10
+ export class NewDataKeySet {
11
+ @Field()
12
+ name: string
13
+
14
+ @Field({ nullable: true })
15
+ description?: string
16
+
17
+ @Field({ nullable: true })
18
+ active?: boolean
19
+
20
+ @Field({ nullable: true })
21
+ reportType?: DataSetReportType
22
+
23
+ @Field({ nullable: true })
24
+ reportView?: string
25
+
26
+ @Field(type => [DataKeyItemPatch], { nullable: true })
27
+ dataKeyItems?: DataKeyItemPatch[]
28
+
29
+ @Field(type => GraphQLUpload, { nullable: true })
30
+ thumbnail?: FileUpload
31
+ }
32
+
33
+ @InputType()
34
+ export class DataKeySetPatch {
35
+ @Field(type => ID, { nullable: true })
36
+ id?: string
37
+
38
+ @Field({ nullable: true })
39
+ name?: string
40
+
41
+ @Field({ nullable: true })
42
+ description?: string
43
+
44
+ @Field({ nullable: true })
45
+ active?: boolean
46
+
47
+ @Field({ nullable: true })
48
+ reportType?: DataSetReportType
49
+
50
+ @Field({ nullable: true })
51
+ reportView?: string
52
+
53
+ @Field(type => [DataKeyItemPatch], { nullable: true })
54
+ dataKeyItems?: DataKeyItemPatch[]
55
+
56
+ @Field(type => GraphQLUpload, { nullable: true })
57
+ thumbnail?: FileUpload
58
+
59
+ @Field({ nullable: true })
60
+ cuFlag?: string
61
+ }
62
+
63
+ @ObjectType()
64
+ export class DataKeySetList {
65
+ @Field(type => [DataKeySet])
66
+ items: DataKeySet[]
67
+
68
+ @Field(type => Int)
69
+ total: number
70
+ }
@@ -0,0 +1,86 @@
1
+ import { Field, ID, ObjectType } from 'type-graphql'
2
+ import {
3
+ Column,
4
+ CreateDateColumn,
5
+ Entity,
6
+ Index,
7
+ ManyToOne,
8
+ PrimaryGeneratedColumn,
9
+ RelationId,
10
+ UpdateDateColumn
11
+ } from 'typeorm'
12
+
13
+ import { User } from '@things-factory/auth-base'
14
+ import { Domain } from '@things-factory/shell'
15
+
16
+ import { DataKeyItem } from './data-key-item-type'
17
+ import { DataSetReportType } from '../data-set/data-set'
18
+
19
+ @Entity()
20
+ @Index('ix_data_key_set_0', (dataKeySet: DataKeySet) => [dataKeySet.domain, dataKeySet.name], { unique: true })
21
+ @ObjectType({ description: 'Entity for DataKeySet' })
22
+ export class DataKeySet {
23
+ @PrimaryGeneratedColumn('uuid')
24
+ @Field(type => ID)
25
+ readonly id: string
26
+
27
+ @ManyToOne(type => Domain)
28
+ @Field(type => Domain)
29
+ domain?: Domain
30
+
31
+ @RelationId((dataKeySet: DataKeySet) => dataKeySet.domain)
32
+ domainId?: string
33
+
34
+ @Column()
35
+ @Field()
36
+ name: string
37
+
38
+ @Column({
39
+ nullable: true
40
+ })
41
+ @Field({ nullable: true })
42
+ description?: string
43
+
44
+ @Column({
45
+ nullable: true
46
+ })
47
+ @Field({ nullable: true })
48
+ active?: boolean
49
+
50
+ @Column({ nullable: true })
51
+ @Field({ nullable: true })
52
+ reportType?: DataSetReportType
53
+
54
+ @Column({ nullable: true })
55
+ @Field({ nullable: true })
56
+ reportView?: string
57
+
58
+ @Column('simple-json', { nullable: true })
59
+ @Field(type => [DataKeyItem], { nullable: true })
60
+ dataKeyItems: DataKeyItem[]
61
+
62
+ @CreateDateColumn()
63
+ @Field({ nullable: true })
64
+ createdAt?: Date
65
+
66
+ @UpdateDateColumn()
67
+ @Field({ nullable: true })
68
+ updatedAt?: Date
69
+
70
+ @ManyToOne(type => User, { nullable: true })
71
+ @Field(type => User, { nullable: true })
72
+ creator?: User
73
+
74
+ @RelationId((dataKeySet: DataKeySet) => dataKeySet.creator)
75
+ creatorId?: string
76
+
77
+ @ManyToOne(type => User, { nullable: true })
78
+ @Field(type => User, { nullable: true })
79
+ updater?: User
80
+
81
+ @RelationId((dataKeySet: DataKeySet) => dataKeySet.updater)
82
+ updaterId?: string
83
+
84
+ @Field(type => String, { nullable: true })
85
+ thumbnail?: string
86
+ }
@@ -0,0 +1,6 @@
1
+ import { DataKeySet } from './data-key-set'
2
+ import { DataKeySetQuery } from './data-key-set-query'
3
+ import { DataKeySetMutation } from './data-key-set-mutation'
4
+
5
+ export const entities = [DataKeySet]
6
+ export const resolvers = [DataKeySetQuery, DataKeySetMutation]
@@ -0,0 +1,154 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+
3
+ import { DataOoc, DataOocStatus } from './data-ooc'
4
+ import { DataOocPatch, NewDataOoc } from './data-ooc-type'
5
+
6
+ @Resolver(DataOoc)
7
+ export class DataOocMutation {
8
+ @Directive('@privilege(category: "data-ooc", privilege: "mutation", domainOwnerGranted: true)')
9
+ @Directive('@transaction')
10
+ @Mutation(returns => DataOoc, { description: 'To create new DataOoc' })
11
+ async createDataOoc(@Arg('dataOoc') dataOoc: NewDataOoc, @Ctx() context: ResolverContext): Promise<DataOoc> {
12
+ const { domain, user, tx } = context.state
13
+
14
+ const state = dataOoc.state || DataOocStatus.ISSUED
15
+ const history = [
16
+ {
17
+ user: {
18
+ id: user.id,
19
+ name: user.name
20
+ },
21
+ state,
22
+ timestamp: Date.now()
23
+ }
24
+ ]
25
+
26
+ return await tx.getRepository(DataOoc).save({
27
+ ...dataOoc,
28
+ state,
29
+ domain,
30
+ history,
31
+ creator: user,
32
+ updater: user
33
+ })
34
+ }
35
+
36
+ @Directive('@privilege(category: "data-ooc", privilege: "mutation", domainOwnerGranted: true)')
37
+ @Directive('@transaction')
38
+ @Mutation(returns => DataOoc, { description: 'To modify DataOoc information' })
39
+ async updateDataOoc(
40
+ @Arg('id') id: string,
41
+ @Arg('patch') patch: DataOocPatch,
42
+ @Ctx() context: ResolverContext
43
+ ): Promise<DataOoc> {
44
+ const { domain, user, tx } = context.state
45
+
46
+ const repository = tx.getRepository(DataOoc)
47
+ const dataOoc = await repository.findOne({
48
+ where: { domain: { id: domain.id }, id }
49
+ })
50
+
51
+ const state = patch.state || dataOoc.state
52
+
53
+ const history = dataOoc.history || []
54
+ history.push({
55
+ user: {
56
+ id: user.id,
57
+ name: user.name
58
+ },
59
+ state,
60
+ comment: patch.correctiveAction || '',
61
+ timestamp: Date.now()
62
+ })
63
+
64
+ const more = {} as any
65
+
66
+ if (dataOoc.state !== patch.state) {
67
+ if (patch.state === DataOocStatus.CORRECTED) {
68
+ more.corrector = user
69
+ } else {
70
+ more.corrector = null
71
+ }
72
+ }
73
+
74
+ return await repository.save({
75
+ ...dataOoc,
76
+ ...patch,
77
+ ...more,
78
+ state,
79
+ history,
80
+ updater: user
81
+ })
82
+ }
83
+
84
+ // @Directive('@privilege(category: "data-ooc", privilege: "mutation", domainOwnerGranted: true)')
85
+ // @Directive('@transaction')
86
+ // @Mutation(returns => [DataOoc], { description: "To modify multiple DataOoc' information" })
87
+ // async updateMultipleDataOoc(
88
+ // @Arg('patches', type => [DataOocPatch]) patches: DataOocPatch[],
89
+ // @Ctx() context: ResolverContext
90
+ // ): Promise<DataOoc[]> {
91
+ // const { domain, user, tx } = context.state
92
+
93
+ // let results = []
94
+ // const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
95
+ // const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
96
+ // const dataOocRepo = tx.getRepository(DataOoc)
97
+
98
+ // if (_createRecords.length > 0) {
99
+ // for (let i = 0; i < _createRecords.length; i++) {
100
+ // const newRecord = _createRecords[i]
101
+
102
+ // const result = await dataOocRepo.save({
103
+ // ...newRecord,
104
+ // domain,
105
+ // creator: user,
106
+ // updater: user
107
+ // })
108
+
109
+ // results.push({ ...result, cuFlag: '+' })
110
+ // }
111
+ // }
112
+
113
+ // if (_updateRecords.length > 0) {
114
+ // for (let i = 0; i < _updateRecords.length; i++) {
115
+ // const newRecord = _updateRecords[i]
116
+ // const dataOoc = await dataOocRepo.findOneBy({id: newRecord.id})
117
+
118
+ // const result = await dataOocRepo.save({
119
+ // ...dataOoc,
120
+ // ...newRecord,
121
+ // updater: user
122
+ // })
123
+
124
+ // results.push({ ...result, cuFlag: 'M' })
125
+ // }
126
+ // }
127
+
128
+ // return results
129
+ // }
130
+
131
+ // @Directive('@privilege(category: "data-ooc", privilege: "mutation", domainOwnerGranted: true)')
132
+ // @Directive('@transaction')
133
+ // @Mutation(returns => Boolean, { description: 'To delete DataOoc' })
134
+ // async deleteDataOoc(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
135
+ // const { domain, tx } = context.state
136
+
137
+ // await tx.getRepository(DataOoc).delete({ domain: { id: domain.id }, id })
138
+ // return true
139
+ // }
140
+
141
+ // @Directive('@privilege(category: "data-ooc", privilege: "mutation", domainOwnerGranted: true)')
142
+ // @Directive('@transaction')
143
+ // @Mutation(returns => Boolean, { description: 'To delete multiple dataOocs' })
144
+ // async deleteDataOocs(@Arg('ids', type => [String]) ids: string[], @Ctx() context: ResolverContext): Promise<boolean> {
145
+ // const { domain, tx } = context.state
146
+
147
+ // await tx.getRepository(DataOoc).delete({
148
+ // domain,
149
+ // id: In(ids)
150
+ // })
151
+
152
+ // return true
153
+ // }
154
+ }
@@ -0,0 +1,106 @@
1
+ import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+
3
+ import { User } from '@things-factory/auth-base'
4
+ import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
5
+ import { ActivityInstance } from '@things-factory/worklist'
6
+
7
+ import { DataSetHistory } from '../data-set-history/data-set-history'
8
+ import { DataItem } from '../data-set/data-item-type'
9
+ import { DataSet } from '../data-set/data-set'
10
+ import { DataSample } from '../data-sample/data-sample'
11
+ import { DataOoc } from './data-ooc'
12
+ import { DataOocList } from './data-ooc-type'
13
+
14
+ @Resolver(DataOoc)
15
+ export class DataOocQuery {
16
+ @Directive('@privilege(category: "data-ooc", privilege: "query", domainOwnerGranted: true)')
17
+ @Query(returns => DataOoc, { description: 'To fetch a DataOoc' })
18
+ async dataOoc(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<DataOoc> {
19
+ const { domain } = context.state
20
+
21
+ return await getRepository(DataOoc).findOne({
22
+ where: { domain: { id: domain.id }, id }
23
+ })
24
+ }
25
+
26
+ @Directive('@privilege(category: "data-ooc", privilege: "query", domainOwnerGranted: true)')
27
+ @Query(returns => DataOocList, { description: 'To fetch multiple DataOoc' })
28
+ async dataOocs(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<DataOocList> {
29
+ const { domain } = context.state
30
+
31
+ const queryBuilder = getQueryBuilderFromListParams({
32
+ repository: getRepository(DataOoc),
33
+ params,
34
+ domain,
35
+ searchables: ['name', 'description']
36
+ })
37
+
38
+ const [items, total] = await queryBuilder.getManyAndCount()
39
+
40
+ return { items, total }
41
+ }
42
+
43
+ @FieldResolver(type => [DataItem])
44
+ async dataItems(@Root() dataOoc: DataOoc): Promise<DataItem[]> {
45
+ const dataSetHistory: DataSetHistory =
46
+ dataOoc.dataSetId &&
47
+ (await getRepository(DataSetHistory).findOne({
48
+ where: {
49
+ originalId: dataOoc.dataSetId,
50
+ version: dataOoc.dataSetVersion
51
+ }
52
+ }))
53
+ return dataSetHistory?.dataItems.filter(item => item.active) || []
54
+ }
55
+
56
+ @FieldResolver(type => DataSample)
57
+ async dataSample(@Root() dataOoc: DataOoc): Promise<DataSample> {
58
+ return dataOoc.dataSampleId && (await getRepository(DataSample).findOneBy({ id: dataOoc.dataSampleId }))
59
+ }
60
+
61
+ @FieldResolver(type => DataSet)
62
+ async dataSet(@Root() dataOoc: DataOoc): Promise<DataSet> {
63
+ return dataOoc.dataSetId && (await getRepository(DataSet).findOneBy({ id: dataOoc.dataSetId }))
64
+ }
65
+
66
+ @FieldResolver(type => ActivityInstance)
67
+ async reviewActivityInstance(@Root() dataOoc: DataOoc): Promise<ActivityInstance> {
68
+ return (
69
+ dataOoc.reviewActivityInstanceId &&
70
+ (await getRepository(ActivityInstance).findOneBy({ id: dataOoc.reviewActivityInstanceId }))
71
+ )
72
+ }
73
+
74
+ @FieldResolver(type => ActivityInstance)
75
+ async resolveActivityInstance(@Root() dataOoc: DataOoc): Promise<ActivityInstance> {
76
+ return (
77
+ dataOoc.resolveActivityInstanceId &&
78
+ (await getRepository(ActivityInstance).findOneBy({ id: dataOoc.resolveActivityInstanceId }))
79
+ )
80
+ }
81
+
82
+ @FieldResolver(type => User)
83
+ async corrector(@Root() dataOoc: DataOoc): Promise<User> {
84
+ return dataOoc.correctorId && (await getRepository(User).findOneBy({ id: dataOoc.correctorId }))
85
+ }
86
+
87
+ @FieldResolver(type => User)
88
+ async reviewer(@Root() dataOoc: DataOoc): Promise<User> {
89
+ return dataOoc.reviewerId && (await getRepository(User).findOneBy({ id: dataOoc.reviewerId }))
90
+ }
91
+
92
+ @FieldResolver(type => Domain)
93
+ async domain(@Root() dataOoc: DataOoc): Promise<Domain> {
94
+ return await getRepository(Domain).findOneBy({ id: dataOoc.domainId })
95
+ }
96
+
97
+ @FieldResolver(type => User)
98
+ async updater(@Root() dataOoc: DataOoc): Promise<User> {
99
+ return dataOoc.updaterId && (await getRepository(User).findOneBy({ id: dataOoc.updaterId }))
100
+ }
101
+
102
+ @FieldResolver(type => User)
103
+ async creator(@Root() dataOoc: DataOoc): Promise<User> {
104
+ return dataOoc.creatorId && (await getRepository(User).findOneBy({ id: dataOoc.creatorId }))
105
+ }
106
+ }
@@ -0,0 +1,48 @@
1
+ import { filter, pipe } from 'graphql-yoga'
2
+ import { Resolver, Root, Subscription } from 'type-graphql'
3
+
4
+ import { User } from '@things-factory/auth-base'
5
+ import { getRepository, pubsub } from '@things-factory/shell'
6
+
7
+ import { DataOoc } from './data-ooc'
8
+
9
+ @Resolver(DataOoc)
10
+ export class DataOocSubscription {
11
+ @Subscription({
12
+ subscribe: ({ args, context, info }) => {
13
+ const { domain, user } = context.state
14
+ const subdomain = domain?.subdomain
15
+
16
+ if (!domain) {
17
+ throw new Error('domain required')
18
+ }
19
+
20
+ if (!user.domains?.find(d => d.subdomain === subdomain) && !process.superUserGranted(domain, user)) {
21
+ throw new Error(`domain(${subdomain}) is not working for user(${user.email}).`)
22
+ }
23
+
24
+ return pipe(
25
+ pubsub.subscribe('data-ooc'),
26
+ filter(async (payload: { dataOoc: DataOoc; supervisoryRoleId: string }) => {
27
+ const { dataOoc, supervisoryRoleId } = payload
28
+ const { domain } = dataOoc
29
+
30
+ if (subdomain !== domain?.subdomain) {
31
+ return false
32
+ }
33
+
34
+ // check if the user has that role
35
+ const userWithRoles: User = await getRepository(User).findOne({
36
+ where: { id: user.id },
37
+ relations: ['roles']
38
+ })
39
+
40
+ return !!userWithRoles.roles.find(role => role.id === supervisoryRoleId)
41
+ })
42
+ )
43
+ }
44
+ })
45
+ dataOoc(@Root() payload: { dataOoc: DataOoc; supervisoryRoleId: string }): DataOoc {
46
+ return payload.dataOoc
47
+ }
48
+ }
@@ -0,0 +1,71 @@
1
+ import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
2
+
3
+ import { ObjectRef, ScalarObject } from '@things-factory/shell'
4
+
5
+ import { DataOoc, DataOocStatus } from './data-ooc'
6
+
7
+ @InputType()
8
+ export class NewDataOoc {
9
+ @Field()
10
+ name: string
11
+
12
+ @Field({ nullable: true })
13
+ description?: string
14
+
15
+ @Field(type => ObjectRef, { nullable: true })
16
+ dataSet?: ObjectRef
17
+
18
+ @Field({ nullable: true })
19
+ dataSetVersion?: number
20
+
21
+ @Field(type => ObjectRef, { nullable: true })
22
+ dataSample?: ObjectRef
23
+
24
+ @Field(type => DataOocStatus, { nullable: true })
25
+ state?: DataOocStatus
26
+
27
+ @Field(type => ScalarObject, { nullable: true })
28
+ data?: any
29
+
30
+ @Field({ nullable: true })
31
+ rawData?: string
32
+
33
+ @Field({ nullable: true })
34
+ source?: string
35
+
36
+ @Field({ nullable: true })
37
+ ooc?: boolean
38
+
39
+ @Field({ nullable: true })
40
+ oos?: boolean
41
+
42
+ @Field({ nullable: true })
43
+ workDate?: string
44
+
45
+ @Field({ nullable: true })
46
+ workShift?: string
47
+
48
+ @Field({ nullable: true })
49
+ collectedAt?: Date
50
+ }
51
+
52
+ @InputType()
53
+ export class DataOocPatch {
54
+ @Field(type => ID, { nullable: true })
55
+ id?: string
56
+
57
+ @Field(type => DataOocStatus, { nullable: true })
58
+ state?: DataOocStatus
59
+
60
+ @Field({ nullable: true })
61
+ correctiveAction?: string
62
+ }
63
+
64
+ @ObjectType()
65
+ export class DataOocList {
66
+ @Field(type => [DataOoc])
67
+ items: DataOoc[]
68
+
69
+ @Field(type => Int)
70
+ total: number
71
+ }