@oneuptime/common 7.0.3196 → 7.0.3200
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/Models/DatabaseModels/CallLog.ts +0 -1
- package/Models/DatabaseModels/CopilotAction.ts +0 -1
- package/Models/DatabaseModels/CopilotActionTypePriority.ts +0 -1
- package/Models/DatabaseModels/CopilotPullRequest.ts +0 -1
- package/Models/DatabaseModels/Dashboard.ts +426 -0
- package/Models/DatabaseModels/EmailLog.ts +0 -1
- package/Models/DatabaseModels/Index.ts +4 -0
- package/Models/DatabaseModels/SmsLog.ts +0 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1729682875503-MigrationName.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Services/DashboardService.ts +50 -0
- package/Server/Types/Markdown.ts +4 -0
- package/Tests/Types/Billing/SubscriptionPlan.test.ts +12 -8
- package/Types/Dashboard/Chart/ChartType.ts +5 -2
- package/Types/Dashboard/DashboardComponentType.ts +7 -0
- package/Types/Dashboard/DashboardComponents/DashboardBaseComponent.ts +11 -0
- package/Types/Dashboard/DashboardComponents/DashboardChartComponent.ts +10 -0
- package/Types/Dashboard/DashboardComponents/DashboardTextComponent.ts +9 -0
- package/Types/Dashboard/DashboardComponents/DashboardValueComponent.ts +8 -0
- package/Types/Dashboard/DashboardMode.ts +6 -0
- package/Types/Dashboard/DashboardSize.ts +8 -2
- package/Types/Dashboard/DashboardViewConfig.ts +8 -0
- package/Types/JSON.ts +7 -0
- package/Types/Permission.ts +38 -0
- package/UI/Components/Button/Button.tsx +21 -1
- package/UI/Components/CategoryCheckbox/Index.tsx +6 -6
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +2 -2
- package/UI/Components/MoreMenu/MoreMenu.tsx +11 -10
- package/Utils/Dashboard/Components/DashboardBaseComponent.ts +8 -0
- package/Utils/Dashboard/Components/DashboardChartComponent.ts +19 -0
- package/Utils/Dashboard/Components/DashboardTextComponent.ts +18 -0
- package/Utils/Dashboard/Components/DashboardValueComponent.ts +17 -0
- package/Utils/Dashboard/DashboardViewConfig.ts +68 -0
- package/build/dist/Models/DatabaseModels/CallLog.js +0 -1
- package/build/dist/Models/DatabaseModels/CallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CopilotAction.js +0 -1
- package/build/dist/Models/DatabaseModels/CopilotAction.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CopilotActionTypePriority.js +0 -1
- package/build/dist/Models/DatabaseModels/CopilotActionTypePriority.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CopilotPullRequest.js +0 -1
- package/build/dist/Models/DatabaseModels/CopilotPullRequest.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Dashboard.js +437 -0
- package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +1 -2
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EmailLog.js +0 -1
- package/build/dist/Models/DatabaseModels/EmailLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +3 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/SmsLog.js +0 -1
- package/build/dist/Models/DatabaseModels/SmsLog.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1729682875503-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1729682875503-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/DashboardService.js +36 -0
- package/build/dist/Server/Services/DashboardService.js.map +1 -0
- package/build/dist/Server/Types/Markdown.js +3 -0
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Tests/Types/Billing/SubscriptionPlan.test.js +11 -7
- package/build/dist/Tests/Types/Billing/SubscriptionPlan.test.js.map +1 -1
- package/build/dist/Types/Dashboard/Chart/ChartType.js +6 -1
- package/build/dist/Types/Dashboard/Chart/ChartType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +8 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardBaseComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardBaseComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardChartComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardChartComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardTextComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardTextComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardValueComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardValueComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardMode.js +7 -0
- package/build/dist/Types/Dashboard/DashboardMode.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardSize.js +4 -1
- package/build/dist/Types/Dashboard/DashboardSize.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardViewConfig.js +2 -0
- package/build/dist/Types/Dashboard/DashboardViewConfig.js.map +1 -0
- package/build/dist/Types/JSON.js +5 -0
- package/build/dist/Types/JSON.js.map +1 -1
- package/build/dist/Types/Permission.js +34 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +16 -1
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CategoryCheckbox/Index.js +6 -2
- package/build/dist/UI/Components/CategoryCheckbox/Index.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +4 -2
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +4 -5
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardBaseComponent.js +7 -0
- package/build/dist/Utils/Dashboard/Components/DashboardBaseComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardChartComponent.js +18 -0
- package/build/dist/Utils/Dashboard/Components/DashboardChartComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardTextComponent.js +17 -0
- package/build/dist/Utils/Dashboard/Components/DashboardTextComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardValueComponent.js +16 -0
- package/build/dist/Utils/Dashboard/Components/DashboardValueComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/DashboardViewConfig.js +41 -0
- package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -0
- package/package.json +2 -2
- package/Types/Dashboard/DashboardComponents/BaseComponent.ts +0 -6
- package/Types/Dashboard/DashboardComponents/ChartDashboardComponent.ts +0 -9
- package/Types/Dashboard/DashboardComponents/ValueDashboardComponent.ts +0 -3
- package/build/dist/Types/Dashboard/DashboardComponents/BaseComponent.js +0 -2
- package/build/dist/Types/Dashboard/DashboardComponents/BaseComponent.js.map +0 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ChartDashboardComponent.js +0 -2
- package/build/dist/Types/Dashboard/DashboardComponents/ChartDashboardComponent.js.map +0 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ValueDashboardComponent.js +0 -2
- package/build/dist/Types/Dashboard/DashboardComponents/ValueDashboardComponent.js.map +0 -1
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import Project from "./Project";
|
|
2
|
+
import User from "./User";
|
|
3
|
+
import Route from "../../Types/API/Route";
|
|
4
|
+
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
|
5
|
+
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
|
6
|
+
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
7
|
+
import ColumnType from "../../Types/Database/ColumnType";
|
|
8
|
+
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
|
9
|
+
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
|
10
|
+
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
|
11
|
+
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
|
12
|
+
import TableColumn from "../../Types/Database/TableColumn";
|
|
13
|
+
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
14
|
+
import TableMetadata from "../../Types/Database/TableMetadata";
|
|
15
|
+
import TenantColumn from "../../Types/Database/TenantColumn";
|
|
16
|
+
import UniqueColumnBy from "../../Types/Database/UniqueColumnBy";
|
|
17
|
+
import IconProp from "../../Types/Icon/IconProp";
|
|
18
|
+
import ObjectID from "../../Types/ObjectID";
|
|
19
|
+
import Permission from "../../Types/Permission";
|
|
20
|
+
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
|
21
|
+
import {
|
|
22
|
+
Column,
|
|
23
|
+
Entity,
|
|
24
|
+
Index,
|
|
25
|
+
JoinColumn,
|
|
26
|
+
JoinTable,
|
|
27
|
+
ManyToMany,
|
|
28
|
+
ManyToOne,
|
|
29
|
+
} from "typeorm";
|
|
30
|
+
import AccessControlColumn from "../../Types/Database/AccessControlColumn";
|
|
31
|
+
import Label from "./Label";
|
|
32
|
+
import DashboardViewConfig from "../../Types/Dashboard/DashboardViewConfig";
|
|
33
|
+
|
|
34
|
+
@AccessControlColumn("labels")
|
|
35
|
+
@EnableDocumentation()
|
|
36
|
+
@TenantColumn("projectId")
|
|
37
|
+
@TableAccessControl({
|
|
38
|
+
create: [
|
|
39
|
+
Permission.ProjectOwner,
|
|
40
|
+
Permission.ProjectAdmin,
|
|
41
|
+
Permission.CreateDashboard,
|
|
42
|
+
],
|
|
43
|
+
read: [
|
|
44
|
+
Permission.ProjectOwner,
|
|
45
|
+
Permission.ProjectAdmin,
|
|
46
|
+
Permission.ProjectMember,
|
|
47
|
+
Permission.ReadDashboard,
|
|
48
|
+
],
|
|
49
|
+
delete: [
|
|
50
|
+
Permission.ProjectOwner,
|
|
51
|
+
Permission.ProjectAdmin,
|
|
52
|
+
Permission.DeleteDashboard,
|
|
53
|
+
],
|
|
54
|
+
update: [
|
|
55
|
+
Permission.ProjectOwner,
|
|
56
|
+
Permission.ProjectAdmin,
|
|
57
|
+
Permission.EditDashboard,
|
|
58
|
+
],
|
|
59
|
+
})
|
|
60
|
+
@EnableWorkflow({
|
|
61
|
+
create: true,
|
|
62
|
+
delete: true,
|
|
63
|
+
update: true,
|
|
64
|
+
read: true,
|
|
65
|
+
})
|
|
66
|
+
@CrudApiEndpoint(new Route("/dashboard"))
|
|
67
|
+
@SlugifyColumn("name", "slug")
|
|
68
|
+
@TableMetadata({
|
|
69
|
+
tableName: "Dashboard",
|
|
70
|
+
singularName: "Dashboard",
|
|
71
|
+
pluralName: "Dashboards",
|
|
72
|
+
icon: IconProp.Window,
|
|
73
|
+
tableDescription:
|
|
74
|
+
"Create and manage Dashboards to visualize your data in a single place",
|
|
75
|
+
})
|
|
76
|
+
@Entity({
|
|
77
|
+
name: "Dashboard",
|
|
78
|
+
})
|
|
79
|
+
export default class Dashboard extends BaseModel {
|
|
80
|
+
@ColumnAccessControl({
|
|
81
|
+
create: [
|
|
82
|
+
Permission.ProjectOwner,
|
|
83
|
+
Permission.ProjectAdmin,
|
|
84
|
+
Permission.CreateDashboard,
|
|
85
|
+
],
|
|
86
|
+
read: [
|
|
87
|
+
Permission.ProjectOwner,
|
|
88
|
+
Permission.ProjectAdmin,
|
|
89
|
+
Permission.ProjectMember,
|
|
90
|
+
Permission.ReadDashboard,
|
|
91
|
+
],
|
|
92
|
+
update: [],
|
|
93
|
+
})
|
|
94
|
+
@TableColumn({
|
|
95
|
+
manyToOneRelationColumn: "projectId",
|
|
96
|
+
type: TableColumnType.Entity,
|
|
97
|
+
modelType: Project,
|
|
98
|
+
title: "Project",
|
|
99
|
+
description: "Relation to Project Resource in which this object belongs",
|
|
100
|
+
})
|
|
101
|
+
@ManyToOne(
|
|
102
|
+
() => {
|
|
103
|
+
return Project;
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
eager: false,
|
|
107
|
+
nullable: true,
|
|
108
|
+
onDelete: "CASCADE",
|
|
109
|
+
orphanedRowAction: "nullify",
|
|
110
|
+
},
|
|
111
|
+
)
|
|
112
|
+
@JoinColumn({ name: "projectId" })
|
|
113
|
+
public project?: Project = undefined;
|
|
114
|
+
|
|
115
|
+
@ColumnAccessControl({
|
|
116
|
+
create: [
|
|
117
|
+
Permission.ProjectOwner,
|
|
118
|
+
Permission.ProjectAdmin,
|
|
119
|
+
Permission.CreateDashboard,
|
|
120
|
+
],
|
|
121
|
+
read: [
|
|
122
|
+
Permission.ProjectOwner,
|
|
123
|
+
Permission.ProjectAdmin,
|
|
124
|
+
Permission.ProjectMember,
|
|
125
|
+
Permission.ReadDashboard,
|
|
126
|
+
],
|
|
127
|
+
update: [],
|
|
128
|
+
})
|
|
129
|
+
@Index()
|
|
130
|
+
@TableColumn({
|
|
131
|
+
type: TableColumnType.ObjectID,
|
|
132
|
+
required: true,
|
|
133
|
+
canReadOnRelationQuery: true,
|
|
134
|
+
title: "Project ID",
|
|
135
|
+
description: "ID of your OneUptime Project in which this object belongs",
|
|
136
|
+
})
|
|
137
|
+
@Column({
|
|
138
|
+
type: ColumnType.ObjectID,
|
|
139
|
+
nullable: false,
|
|
140
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
141
|
+
})
|
|
142
|
+
public projectId?: ObjectID = undefined;
|
|
143
|
+
|
|
144
|
+
@ColumnAccessControl({
|
|
145
|
+
create: [
|
|
146
|
+
Permission.ProjectOwner,
|
|
147
|
+
Permission.ProjectAdmin,
|
|
148
|
+
Permission.CreateDashboard,
|
|
149
|
+
],
|
|
150
|
+
read: [
|
|
151
|
+
Permission.ProjectOwner,
|
|
152
|
+
Permission.ProjectAdmin,
|
|
153
|
+
Permission.ProjectMember,
|
|
154
|
+
Permission.ReadDashboard,
|
|
155
|
+
],
|
|
156
|
+
update: [
|
|
157
|
+
Permission.ProjectOwner,
|
|
158
|
+
Permission.ProjectAdmin,
|
|
159
|
+
Permission.EditDashboard,
|
|
160
|
+
],
|
|
161
|
+
})
|
|
162
|
+
@TableColumn({
|
|
163
|
+
required: true,
|
|
164
|
+
type: TableColumnType.ShortText,
|
|
165
|
+
canReadOnRelationQuery: true,
|
|
166
|
+
title: "Name",
|
|
167
|
+
description: "Any friendly name of this object",
|
|
168
|
+
})
|
|
169
|
+
@Column({
|
|
170
|
+
nullable: false,
|
|
171
|
+
type: ColumnType.ShortText,
|
|
172
|
+
length: ColumnLength.ShortText,
|
|
173
|
+
})
|
|
174
|
+
@UniqueColumnBy("projectId")
|
|
175
|
+
public name?: string = undefined;
|
|
176
|
+
|
|
177
|
+
@ColumnAccessControl({
|
|
178
|
+
create: [],
|
|
179
|
+
read: [
|
|
180
|
+
Permission.ProjectOwner,
|
|
181
|
+
Permission.ProjectAdmin,
|
|
182
|
+
Permission.ProjectMember,
|
|
183
|
+
Permission.ReadDashboard,
|
|
184
|
+
],
|
|
185
|
+
update: [],
|
|
186
|
+
})
|
|
187
|
+
@TableColumn({
|
|
188
|
+
required: true,
|
|
189
|
+
unique: true,
|
|
190
|
+
type: TableColumnType.Slug,
|
|
191
|
+
title: "Slug",
|
|
192
|
+
description: "Friendly globally unique name for your object",
|
|
193
|
+
})
|
|
194
|
+
@Column({
|
|
195
|
+
nullable: false,
|
|
196
|
+
type: ColumnType.Slug,
|
|
197
|
+
length: ColumnLength.Slug,
|
|
198
|
+
})
|
|
199
|
+
public slug?: string = undefined;
|
|
200
|
+
|
|
201
|
+
@ColumnAccessControl({
|
|
202
|
+
create: [
|
|
203
|
+
Permission.ProjectOwner,
|
|
204
|
+
Permission.ProjectAdmin,
|
|
205
|
+
Permission.CreateDashboard,
|
|
206
|
+
],
|
|
207
|
+
read: [
|
|
208
|
+
Permission.ProjectOwner,
|
|
209
|
+
Permission.ProjectAdmin,
|
|
210
|
+
Permission.ProjectMember,
|
|
211
|
+
Permission.ReadDashboard,
|
|
212
|
+
],
|
|
213
|
+
update: [
|
|
214
|
+
Permission.ProjectOwner,
|
|
215
|
+
Permission.ProjectAdmin,
|
|
216
|
+
Permission.EditDashboard,
|
|
217
|
+
],
|
|
218
|
+
})
|
|
219
|
+
@TableColumn({
|
|
220
|
+
required: false,
|
|
221
|
+
type: TableColumnType.LongText,
|
|
222
|
+
title: "Description",
|
|
223
|
+
description: "Friendly description that will help you remember",
|
|
224
|
+
})
|
|
225
|
+
@Column({
|
|
226
|
+
nullable: true,
|
|
227
|
+
type: ColumnType.LongText,
|
|
228
|
+
length: ColumnLength.LongText,
|
|
229
|
+
})
|
|
230
|
+
public description?: string = undefined;
|
|
231
|
+
|
|
232
|
+
@ColumnAccessControl({
|
|
233
|
+
create: [
|
|
234
|
+
Permission.ProjectOwner,
|
|
235
|
+
Permission.ProjectAdmin,
|
|
236
|
+
Permission.CreateDashboard,
|
|
237
|
+
],
|
|
238
|
+
read: [
|
|
239
|
+
Permission.ProjectOwner,
|
|
240
|
+
Permission.ProjectAdmin,
|
|
241
|
+
Permission.ProjectMember,
|
|
242
|
+
Permission.ReadDashboard,
|
|
243
|
+
],
|
|
244
|
+
update: [],
|
|
245
|
+
})
|
|
246
|
+
@TableColumn({
|
|
247
|
+
manyToOneRelationColumn: "createdByUserId",
|
|
248
|
+
type: TableColumnType.Entity,
|
|
249
|
+
modelType: User,
|
|
250
|
+
title: "Created by User",
|
|
251
|
+
description:
|
|
252
|
+
"Relation to User who created this object (if this object was created by a User)",
|
|
253
|
+
})
|
|
254
|
+
@ManyToOne(
|
|
255
|
+
() => {
|
|
256
|
+
return User;
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
eager: false,
|
|
260
|
+
nullable: true,
|
|
261
|
+
onDelete: "SET NULL",
|
|
262
|
+
orphanedRowAction: "nullify",
|
|
263
|
+
},
|
|
264
|
+
)
|
|
265
|
+
@JoinColumn({ name: "createdByUserId" })
|
|
266
|
+
public createdByUser?: User = undefined;
|
|
267
|
+
|
|
268
|
+
@ColumnAccessControl({
|
|
269
|
+
create: [
|
|
270
|
+
Permission.ProjectOwner,
|
|
271
|
+
Permission.ProjectAdmin,
|
|
272
|
+
Permission.CreateDashboard,
|
|
273
|
+
],
|
|
274
|
+
read: [
|
|
275
|
+
Permission.ProjectOwner,
|
|
276
|
+
Permission.ProjectAdmin,
|
|
277
|
+
Permission.ProjectMember,
|
|
278
|
+
Permission.ReadDashboard,
|
|
279
|
+
],
|
|
280
|
+
update: [],
|
|
281
|
+
})
|
|
282
|
+
@TableColumn({
|
|
283
|
+
type: TableColumnType.ObjectID,
|
|
284
|
+
title: "Created by User ID",
|
|
285
|
+
description:
|
|
286
|
+
"User ID who created this object (if this object was created by a User)",
|
|
287
|
+
})
|
|
288
|
+
@Column({
|
|
289
|
+
type: ColumnType.ObjectID,
|
|
290
|
+
nullable: true,
|
|
291
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
292
|
+
})
|
|
293
|
+
public createdByUserId?: ObjectID = undefined;
|
|
294
|
+
|
|
295
|
+
@ColumnAccessControl({
|
|
296
|
+
create: [],
|
|
297
|
+
read: [
|
|
298
|
+
Permission.ProjectOwner,
|
|
299
|
+
Permission.ProjectAdmin,
|
|
300
|
+
Permission.ProjectMember,
|
|
301
|
+
Permission.ReadDashboard,
|
|
302
|
+
],
|
|
303
|
+
update: [],
|
|
304
|
+
})
|
|
305
|
+
@TableColumn({
|
|
306
|
+
manyToOneRelationColumn: "deletedByUserId",
|
|
307
|
+
type: TableColumnType.Entity,
|
|
308
|
+
title: "Deleted by User",
|
|
309
|
+
description:
|
|
310
|
+
"Relation to User who deleted this object (if this object was deleted by a User)",
|
|
311
|
+
})
|
|
312
|
+
@ManyToOne(
|
|
313
|
+
() => {
|
|
314
|
+
return User;
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
cascade: false,
|
|
318
|
+
eager: false,
|
|
319
|
+
nullable: true,
|
|
320
|
+
onDelete: "SET NULL",
|
|
321
|
+
orphanedRowAction: "nullify",
|
|
322
|
+
},
|
|
323
|
+
)
|
|
324
|
+
@JoinColumn({ name: "deletedByUserId" })
|
|
325
|
+
public deletedByUser?: User = undefined;
|
|
326
|
+
|
|
327
|
+
@ColumnAccessControl({
|
|
328
|
+
create: [],
|
|
329
|
+
read: [
|
|
330
|
+
Permission.ProjectOwner,
|
|
331
|
+
Permission.ProjectAdmin,
|
|
332
|
+
Permission.ProjectMember,
|
|
333
|
+
Permission.ReadDashboard,
|
|
334
|
+
],
|
|
335
|
+
update: [],
|
|
336
|
+
})
|
|
337
|
+
@TableColumn({
|
|
338
|
+
type: TableColumnType.ObjectID,
|
|
339
|
+
title: "Deleted by User ID",
|
|
340
|
+
description:
|
|
341
|
+
"User ID who deleted this object (if this object was deleted by a User)",
|
|
342
|
+
})
|
|
343
|
+
@Column({
|
|
344
|
+
type: ColumnType.ObjectID,
|
|
345
|
+
nullable: true,
|
|
346
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
347
|
+
})
|
|
348
|
+
public deletedByUserId?: ObjectID = undefined;
|
|
349
|
+
|
|
350
|
+
@ColumnAccessControl({
|
|
351
|
+
create: [
|
|
352
|
+
Permission.ProjectOwner,
|
|
353
|
+
Permission.ProjectAdmin,
|
|
354
|
+
Permission.ProjectMember,
|
|
355
|
+
Permission.CreateDashboard,
|
|
356
|
+
],
|
|
357
|
+
read: [
|
|
358
|
+
Permission.ProjectOwner,
|
|
359
|
+
Permission.ProjectAdmin,
|
|
360
|
+
Permission.ProjectMember,
|
|
361
|
+
Permission.ReadDashboard,
|
|
362
|
+
],
|
|
363
|
+
update: [
|
|
364
|
+
Permission.ProjectOwner,
|
|
365
|
+
Permission.ProjectAdmin,
|
|
366
|
+
Permission.ProjectMember,
|
|
367
|
+
Permission.EditDashboard,
|
|
368
|
+
],
|
|
369
|
+
})
|
|
370
|
+
@TableColumn({
|
|
371
|
+
required: false,
|
|
372
|
+
type: TableColumnType.EntityArray,
|
|
373
|
+
modelType: Label,
|
|
374
|
+
title: "Labels",
|
|
375
|
+
description:
|
|
376
|
+
"Relation to Labels Array where this object is categorized in.",
|
|
377
|
+
})
|
|
378
|
+
@ManyToMany(
|
|
379
|
+
() => {
|
|
380
|
+
return Label;
|
|
381
|
+
},
|
|
382
|
+
{ eager: false },
|
|
383
|
+
)
|
|
384
|
+
@JoinTable({
|
|
385
|
+
name: "DashboardLabel",
|
|
386
|
+
inverseJoinColumn: {
|
|
387
|
+
name: "labelId",
|
|
388
|
+
referencedColumnName: "_id",
|
|
389
|
+
},
|
|
390
|
+
joinColumn: {
|
|
391
|
+
name: "dashboardId",
|
|
392
|
+
referencedColumnName: "_id",
|
|
393
|
+
},
|
|
394
|
+
})
|
|
395
|
+
public labels?: Array<Label> = undefined;
|
|
396
|
+
|
|
397
|
+
@ColumnAccessControl({
|
|
398
|
+
create: [
|
|
399
|
+
Permission.ProjectOwner,
|
|
400
|
+
Permission.ProjectAdmin,
|
|
401
|
+
Permission.CreateDashboard,
|
|
402
|
+
],
|
|
403
|
+
read: [
|
|
404
|
+
Permission.ProjectOwner,
|
|
405
|
+
Permission.ProjectAdmin,
|
|
406
|
+
Permission.ProjectMember,
|
|
407
|
+
Permission.ReadDashboard,
|
|
408
|
+
],
|
|
409
|
+
update: [
|
|
410
|
+
Permission.ProjectOwner,
|
|
411
|
+
Permission.ProjectAdmin,
|
|
412
|
+
Permission.EditDashboard,
|
|
413
|
+
],
|
|
414
|
+
})
|
|
415
|
+
@TableColumn({
|
|
416
|
+
required: true,
|
|
417
|
+
type: TableColumnType.JSON,
|
|
418
|
+
title: "Dashboard View Config",
|
|
419
|
+
description: "Configuration of Dashboard View",
|
|
420
|
+
})
|
|
421
|
+
@Column({
|
|
422
|
+
nullable: false,
|
|
423
|
+
type: ColumnType.JSON,
|
|
424
|
+
})
|
|
425
|
+
public dashboardViewConfig?: DashboardViewConfig = undefined;
|
|
426
|
+
}
|
|
@@ -152,6 +152,7 @@ import AlertOwnerUser from "./AlertOwnerUser";
|
|
|
152
152
|
import AlertSeverity from "./AlertSeverity";
|
|
153
153
|
import AlertNoteTemplate from "./AlertNoteTemplate";
|
|
154
154
|
import TableView from "./TableView";
|
|
155
|
+
import Dashboard from "./Dashboard";
|
|
155
156
|
|
|
156
157
|
const AllModelTypes: Array<{
|
|
157
158
|
new (): BaseModel;
|
|
@@ -327,6 +328,9 @@ const AllModelTypes: Array<{
|
|
|
327
328
|
TelemetryException,
|
|
328
329
|
|
|
329
330
|
TableView,
|
|
331
|
+
|
|
332
|
+
// Dashboards
|
|
333
|
+
Dashboard,
|
|
330
334
|
];
|
|
331
335
|
|
|
332
336
|
const modelTypeMap: { [key: string]: { new (): BaseModel } } = {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1729682875503 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1729682875503";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`CREATE TABLE "Dashboard" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "name" character varying(100) NOT NULL, "slug" character varying(100) NOT NULL, "description" character varying(500), "createdByUserId" uuid, "deletedByUserId" uuid, "dashboardViewConfig" jsonb NOT NULL, CONSTRAINT "PK_98ee748c8a7a18d6f9ca995eaf4" PRIMARY KEY ("_id"))`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`CREATE INDEX "IDX_7f0fc9402b8d4151c46e3015a3" ON "Dashboard" ("projectId") `,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`CREATE TABLE "DashboardLabel" ("dashboardId" uuid NOT NULL, "labelId" uuid NOT NULL, CONSTRAINT "PK_bf2648028a4eab3f57aad76dab6" PRIMARY KEY ("dashboardId", "labelId"))`,
|
|
15
|
+
);
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`CREATE INDEX "IDX_ce2113f43c6d88a632318414d0" ON "DashboardLabel" ("dashboardId") `,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`CREATE INDEX "IDX_31a32c8d6d1d1cb734c7711050" ON "DashboardLabel" ("labelId") `,
|
|
21
|
+
);
|
|
22
|
+
await queryRunner.query(
|
|
23
|
+
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
|
|
24
|
+
);
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "Dashboard" ADD CONSTRAINT "FK_7f0fc9402b8d4151c46e3015a30" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "Dashboard" ADD CONSTRAINT "FK_501b2bb8e0cb03f309211cbfa5f" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
33
|
+
);
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`ALTER TABLE "Dashboard" ADD CONSTRAINT "FK_0debc7bed011eac37da40e875cb" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
36
|
+
);
|
|
37
|
+
await queryRunner.query(
|
|
38
|
+
`ALTER TABLE "DashboardLabel" ADD CONSTRAINT "FK_ce2113f43c6d88a632318414d0d" FOREIGN KEY ("dashboardId") REFERENCES "Dashboard"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
|
39
|
+
);
|
|
40
|
+
await queryRunner.query(
|
|
41
|
+
`ALTER TABLE "DashboardLabel" ADD CONSTRAINT "FK_31a32c8d6d1d1cb734c77110509" FOREIGN KEY ("labelId") REFERENCES "Label"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
46
|
+
await queryRunner.query(
|
|
47
|
+
`ALTER TABLE "DashboardLabel" DROP CONSTRAINT "FK_31a32c8d6d1d1cb734c77110509"`,
|
|
48
|
+
);
|
|
49
|
+
await queryRunner.query(
|
|
50
|
+
`ALTER TABLE "DashboardLabel" DROP CONSTRAINT "FK_ce2113f43c6d88a632318414d0d"`,
|
|
51
|
+
);
|
|
52
|
+
await queryRunner.query(
|
|
53
|
+
`ALTER TABLE "Dashboard" DROP CONSTRAINT "FK_0debc7bed011eac37da40e875cb"`,
|
|
54
|
+
);
|
|
55
|
+
await queryRunner.query(
|
|
56
|
+
`ALTER TABLE "Dashboard" DROP CONSTRAINT "FK_501b2bb8e0cb03f309211cbfa5f"`,
|
|
57
|
+
);
|
|
58
|
+
await queryRunner.query(
|
|
59
|
+
`ALTER TABLE "Dashboard" DROP CONSTRAINT "FK_7f0fc9402b8d4151c46e3015a30"`,
|
|
60
|
+
);
|
|
61
|
+
await queryRunner.query(
|
|
62
|
+
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
|
|
63
|
+
);
|
|
64
|
+
await queryRunner.query(
|
|
65
|
+
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
|
|
66
|
+
);
|
|
67
|
+
await queryRunner.query(
|
|
68
|
+
`DROP INDEX "public"."IDX_31a32c8d6d1d1cb734c7711050"`,
|
|
69
|
+
);
|
|
70
|
+
await queryRunner.query(
|
|
71
|
+
`DROP INDEX "public"."IDX_ce2113f43c6d88a632318414d0"`,
|
|
72
|
+
);
|
|
73
|
+
await queryRunner.query(`DROP TABLE "DashboardLabel"`);
|
|
74
|
+
await queryRunner.query(
|
|
75
|
+
`DROP INDEX "public"."IDX_7f0fc9402b8d4151c46e3015a3"`,
|
|
76
|
+
);
|
|
77
|
+
await queryRunner.query(`DROP TABLE "Dashboard"`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -74,6 +74,7 @@ import { MigrationName1727194579925 } from "./1727194579925-MigrationName";
|
|
|
74
74
|
import { MigrationName1727894983857 } from "./1727894983857-MigrationName";
|
|
75
75
|
import { MigrationName1727906598804 } from "./1727906598804-MigrationName";
|
|
76
76
|
import { MigrationName1728472625805 } from "./1728472625805-MigrationName";
|
|
77
|
+
import { MigrationName1729682875503 } from "./1729682875503-MigrationName";
|
|
77
78
|
|
|
78
79
|
export default [
|
|
79
80
|
InitialMigration,
|
|
@@ -152,4 +153,5 @@ export default [
|
|
|
152
153
|
MigrationName1727894983857,
|
|
153
154
|
MigrationName1727906598804,
|
|
154
155
|
MigrationName1728472625805,
|
|
156
|
+
MigrationName1729682875503,
|
|
155
157
|
];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import CreateBy from "../Types/Database/CreateBy";
|
|
2
|
+
import { OnCreate } from "../Types/Database/Hooks";
|
|
3
|
+
import DatabaseService from "./DatabaseService";
|
|
4
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
5
|
+
import Model from "Common/Models/DatabaseModels/Dashboard";
|
|
6
|
+
import { IsBillingEnabled } from "../EnvironmentConfig";
|
|
7
|
+
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
|
|
8
|
+
import DashboardViewConfigUtil from "../../Utils/Dashboard/DashboardViewConfig";
|
|
9
|
+
|
|
10
|
+
export class Service extends DatabaseService<Model> {
|
|
11
|
+
public constructor() {
|
|
12
|
+
super(Model);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
protected override async onBeforeCreate(
|
|
16
|
+
createBy: CreateBy<Model>,
|
|
17
|
+
): Promise<OnCreate<Model>> {
|
|
18
|
+
if (IsBillingEnabled) {
|
|
19
|
+
// then if free plan, make sure it can only have 1 dashboard.
|
|
20
|
+
|
|
21
|
+
if (createBy.props.currentPlan === PlanType.Free) {
|
|
22
|
+
// get count by project id.
|
|
23
|
+
const count: number = (
|
|
24
|
+
await this.countBy({
|
|
25
|
+
query: {
|
|
26
|
+
projectId: createBy.data.projectId,
|
|
27
|
+
},
|
|
28
|
+
props: {
|
|
29
|
+
isRoot: true,
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
).toNumber();
|
|
33
|
+
|
|
34
|
+
if (count > 0) {
|
|
35
|
+
throw new BadDataException(
|
|
36
|
+
"Free plan can only have 1 dashboard. Please upgrade your plan.",
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// make sure dashboard config is empty.
|
|
43
|
+
createBy.data.dashboardViewConfig =
|
|
44
|
+
DashboardViewConfigUtil.createDefaultDashboardViewConfig();
|
|
45
|
+
|
|
46
|
+
return Promise.resolve({ createBy, carryForward: null });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default new Service();
|
package/Server/Types/Markdown.ts
CHANGED
|
@@ -17,6 +17,10 @@ export default class Markdown {
|
|
|
17
17
|
markdown: string,
|
|
18
18
|
contentType: MarkdownContentType,
|
|
19
19
|
): Promise<string> {
|
|
20
|
+
// convert tags > and < to > and <
|
|
21
|
+
markdown = markdown.replace(/</g, "<");
|
|
22
|
+
markdown = markdown.replace(/>/g, ">");
|
|
23
|
+
|
|
20
24
|
let renderer: Renderer | null = null;
|
|
21
25
|
|
|
22
26
|
if (contentType === MarkdownContentType.Blog) {
|
|
@@ -263,14 +263,18 @@ describe("SubscriptionPlan", () => {
|
|
|
263
263
|
});
|
|
264
264
|
describe("isUnpaid", () => {
|
|
265
265
|
it("should return true if the subscription status is unpaid", () => {
|
|
266
|
-
const
|
|
267
|
-
"incomplete"
|
|
268
|
-
"incomplete_expired"
|
|
269
|
-
"past_due"
|
|
270
|
-
"canceled"
|
|
271
|
-
"unpaid"
|
|
272
|
-
|
|
273
|
-
|
|
266
|
+
const subscriptionStatuses: Array<string> = [
|
|
267
|
+
"incomplete",
|
|
268
|
+
"incomplete_expired",
|
|
269
|
+
"past_due",
|
|
270
|
+
"canceled",
|
|
271
|
+
"unpaid",
|
|
272
|
+
];
|
|
273
|
+
|
|
274
|
+
for (const subscriptionStatus of subscriptionStatuses) {
|
|
275
|
+
const result: boolean = SubscriptionPlan.isUnpaid(subscriptionStatus);
|
|
276
|
+
expect(result).toBe(true);
|
|
277
|
+
}
|
|
274
278
|
});
|
|
275
279
|
it("should return false if the subscription status is active", () => {
|
|
276
280
|
const subscriptionStatus: string = "active";
|