Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement dashboard endpoints #65

Merged
merged 1 commit into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
563 changes: 355 additions & 208 deletions package-lock.json

Large diffs are not rendered by default.

File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions packages/content-platform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Curator Content Platform

Plugin for turning Strapi into a full-featured content platform.

## Features

- Audit logs
- Dashboard (recently edited, user's drafts, etc.)
- Versioning
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@curatorjs/strapi",
"name": "@curatorjs/content-platform",
"version": "0.1.0",
"description": "Curator plugin for Strapi.",
"main": "strapi-server.js",
Expand All @@ -13,13 +13,13 @@
"ramda": "^0.29.0"
},
"devDependencies": {
"@strapi/typescript-utils": "4.13.1",
"@strapi/strapi": "^4.13.1",
"@strapi/typescript-utils": "4.13.3",
"@strapi/strapi": "^4.13.3",
"@types/ramda": "0.29.3",
"typescript": "5.2.2"
},
"peerDependencies": {
"@strapi/strapi": "^4.13.0"
"@strapi/strapi": "^4.13.3"
},
"author": "Devtastic <hi@devtastic.build>",
"maintainers": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ export default async function ({ strapi }: { strapi: Strapi }) {
*/
strapi.db.lifecycles.subscribe(async (event) => {
const config = strapi.plugin("curator").config("audit");
const included: string[] = Array.isArray(config?.included)
? config.included
const include: string[] = Array.isArray(config?.include)
? config.include
: [];
const excluded: string[] = Array.isArray(config?.excluded)
? config.excluded
const exclude: string[] = Array.isArray(config?.exclude)
? config.exclude
: [];
const uidMatch =
R.anyPass([
R.startsWith("api::"),
R.includes(R.__, included),
R.includes(R.__, include),
R.equals("plugin::curator.curator-secret"),
])(event.model?.uid ?? "") && !excluded.includes(event.model?.uid);
])(event.model?.uid ?? "") && !exclude.includes(event.model?.uid);

if (
config &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
export default {
default: {
/*
* Eiter a boolean to enable/disable or a configuration object:
* {
* include: ['plugin::my-plugin.my-content-type'],
* exclude: ['api::page.page']
* }
*/
audit: true,
},
validator(config: Record<string, any>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default {
description: "A log of an action of a user.",
},
options: {
draftAndPublished: false,
draftAndPublish: false,
},
pluginOptions: {
"content-type-builder": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default {
description: "A key-value with role-based access scope.",
},
options: {
draftAndPublished: false,
draftAndPublish: false,
},
pluginOptions: {
"content-type-builder": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Strapi } from "@strapi/strapi";

export default ({ strapi }: { strapi: Strapi }) => ({
index() {
return strapi.plugin("curator").service("dashboardService").getData();
},
});
7 changes: 7 additions & 0 deletions packages/content-platform/server/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import dashboardController from "./dashboard.controller";
import secretsController from "./secrets.controller";

export default {
secretsController,
dashboardController,
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Strapi } from "@strapi/strapi";

export default ({ strapi }: { strapi: Strapi }) => ({
find() {
index() {
return strapi.plugin("curator").service("secretsService").getSecrets();
},
});
1 change: 1 addition & 0 deletions packages/content-platform/server/policies/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default {};
14 changes: 14 additions & 0 deletions packages/content-platform/server/routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default [
{
method: "GET",
path: "/secrets",
handler: "secretsController.index",
config: {},
},
{
method: "GET",
path: "/dashboard",
handler: "dashboardController.index",
config: {},
},
];
93 changes: 93 additions & 0 deletions packages/content-platform/server/services/dashboard.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { Strapi } from "@strapi/strapi";
import * as R from "ramda";

export default ({ strapi }: { strapi: Strapi }) => ({
async getData() {
const ctx = strapi.requestContext.get();

const recent = await this.getRecent(ctx);
const drafts = await this.getDrafts(ctx);

return { recent, drafts };
},
/**
* Get recently created or updated items.
*/
async getRecent(ctx: any) {
const user = ctx.state.user;
const query = await strapi.entityService.findMany(
"plugin::curator.curator-audit-log",
{
sort: "updatedAt:DESC",
filters: {
subjectId: user.id,
objectUid: {
$startsWith: "api::",
},
action: ["update", "create"],
},
}
);

const distinct: Record<string, any>[] = R.uniqBy(
R.props(["objectId", "objectUid"]),
query as any[]
).slice(0, 5);

let results: any[] = [];

for await (const item of distinct) {
try {
const data = await strapi.entityService.findOne(
item.objectUid,
item.objectId
);

results = [
...results,
{ uid: item.objectUid, id: item.objectId, attributes: data ?? {} },
];
} catch (e) {
console.warn(e);
}
}

return results;
},

/**
* Get draft content created by the current user.
*/
async getDrafts(ctx: any) {
const user = ctx.state.user;

const modelsWithDraftState = Object.values(strapi.contentTypes)
.filter(R.path(["options", "draftAndPublish"]))
.map<string>(R.prop<string>("uid"));

let results: any[] = [];

for await (const uid of modelsWithDraftState) {
try {
const data = (await strapi.entityService.findMany(uid as any, {
sort: "updatedAt:DESC",
filters: {
createdBy: user.id,
publishedAt: {
$null: true,
},
},
})) as any[];

results = [
...results,
...data.map(({ id, ...attributes }) => ({ id, uid, attributes })),
];
} catch (e) {
console.warn(e);
}
}

return results.slice(0, 10);
},
});
7 changes: 7 additions & 0 deletions packages/content-platform/server/services/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import secretsService from "./secrets.service";
import dashboardService from "./dashboard.service";

export default {
secretsService,
dashboardService,
};
File renamed without changes.
3 changes: 0 additions & 3 deletions packages/strapi/README.md

This file was deleted.

Loading