Skip to content

Commit

Permalink
task: improving support for single types while trying to replicate #17 (
Browse files Browse the repository at this point in the history
#19)

* task: improving support for single types while trying to replicate #17

* chore: updating package-lock
  • Loading branch information
PenguinOfWar committed Feb 15, 2024
1 parent 4e9403f commit 59b3f9b
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 17 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Accountability and content versioning for strapi v4+.
## Features

- Automatic revision history and auditing with support for all major strapi content types including relations, media, components, and dynamic zones via the admin panel.
- Support for collection and single content types.
- Roll-back capabilities with the option to select specific fields to restore via the admin panel.
- Tracks revision history by both admins and users.
- Internationalization (i18n) plugin support.
Expand Down
49 changes: 42 additions & 7 deletions admin/src/components/PaperTrail/PaperTrail.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ function PaperTrail() {
const { uid, pluginOptions = {} } = layout;

const { formatMessage } = useIntl();
const { id } = useParams();
// params works for collection types but not single types
const { id, collectionType } = useParams();

const [recordId, setRecordId] = useState(id);

const paperTrailEnabled = pluginOptions?.paperTrail?.enabled;

Expand All @@ -47,14 +50,42 @@ function PaperTrail() {
const [total, setTotal] = useState(0);
const [pageCount, setPageCount] = useState(1);

// if collectionType is single then fetch the ID (if exists) from the server and set `1` if nothing.

const getSingleTypeId = useCallback(async () => {
const requestUri = `/content-manager/single-types/${uid}/`;

try {
const result = await request.get(requestUri);

const { data = {} } = result;

const { id } = data;

setRecordId(id);

return id;
} catch (err) {
console.warn('paper-trail:', 'No existing single type for this UID', err);
}

return null;
}, [uid, request]);

useEffect(() => {
if (collectionType === 'single-types') {
getSingleTypeId();
}
}, [collectionType, getSingleTypeId]);

useEffect(() => {
async function getTrails(page, pageSize) {
const params = new URLSearchParams({
page,
pageSize,
sort: 'version:DESC',
'filters[$and][0][contentType][$eq]': uid,
'filters[$and][1][recordId][$eq]': id
'filters[$and][1][recordId][$eq]': recordId
}).toString();

const requestUri = `/content-manager/collection-types/plugin::paper-trail.trail?${params}`;
Expand Down Expand Up @@ -84,24 +115,27 @@ function PaperTrail() {
}
}

if (!loaded && paperTrailEnabled && id) {
if (!loaded && paperTrailEnabled && recordId) {
getTrails(page, pageSize);
} else {
setInitialLoad(true);
}
}, [loaded, uid, id, page, paperTrailEnabled, request]);
}, [loaded, uid, recordId, page, paperTrailEnabled, request]);

/**
* event listener for submit button
*/

const handler = useCallback(() => {
setTimeout(() => {
const handler = useCallback(async () => {
setTimeout(async () => {
if (collectionType === 'single-types') {
await getSingleTypeId();
}
setPage(1);
setLoaded(false);
setInitialLoad(false);
}, 1000);
}, []);
}, [getSingleTypeId, collectionType]);

const handleSetPage = useCallback(newPage => {
setPage(newPage);
Expand Down Expand Up @@ -228,6 +262,7 @@ function PaperTrail() {
pageCount={pageCount}
total={total}
setPage={handleSetPage}
collectionType={collectionType}
/>
</Fragment>
);
Expand Down
11 changes: 8 additions & 3 deletions admin/src/components/PaperTrailViewer/PaperTrailViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ function PaperTrailViewer(props) {
pageSize,
total,
pageCount,
setPage
setPage,
collectionType
} = props;
const [viewRevision, setViewRevision] = useState(null);
const [revisedFields, setRevisedFields] = useState([]);
Expand Down Expand Up @@ -107,15 +108,19 @@ function PaperTrailViewer(props) {
const payload = buildPayload(trimmedContent, revisedFields);

try {
const requestUri = `/content-manager/collection-types/${contentType}/${recordId}`;
const requestUri =
collectionType === 'single-types'
? `/content-manager/${collectionType}/${contentType}`
: `/content-manager/${collectionType}/${contentType}/${recordId}`;

await request.put(requestUri, payload);

window.location.reload();
} catch (Err) {
setError(Err);
console.warn('paper-trail:', Err);
}
}, [layout, viewRevision, revisedFields, request, setError]);
}, [layout, viewRevision, revisedFields, request, setError, collectionType]);

return (
<Fragment>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "strapi-plugin-paper-trail",
"version": "0.5.0",
"version": "0.6.0",
"description": "Accountability and content versioning for strapi v4+",
"homepage": "https://github.com/PenguinOfWar/strapi-plugin-paper-trail#readme",
"bugs": {
Expand Down
8 changes: 5 additions & 3 deletions server/utils/getPathParams.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
const { match } = require('path-to-regexp');

module.exports = (path, isAdmin) => {
// take the path without the query string

path = path.split('?')[0];

const matchFn = isAdmin
? match(
'/content-manager/collection-types/:contentTypeName/:contentTypeId?'
)
? match('/content-manager/:collectionType/:contentTypeName/:contentTypeId?')
: match('/api/:contentTypeName/:contentTypeId?');

const matches = matchFn(path);
Expand Down
2 changes: 1 addition & 1 deletion server/utils/matchAdminPath.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = string => {
const regex =
/\/content-manager\/collection-types\/([a-zA-Z0-9-]+::[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+)(?:\/\d*)?/;
/\/content-manager\/(collection-types|single-types)\/([a-zA-Z0-9-]+::[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+)(?:\/\d*)?/;
return string.match(regex);
};
6 changes: 6 additions & 0 deletions tests/getPathParms.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ describe('utils: getPathParams', () => {
'/content-manager/collection-types/foo-type/42',
1
);
const result4 = getPathParams(
'/content-manager/collection-types/api::another-type.another-type/4?locale=en',
1
);

expect(result1.contentTypeName).toBe('foo-type');
expect(result2.contentTypeName).toBe('foo-type');
expect(result3.contentTypeName).toBe('foo-type');
expect(result3.contentTypeId).toBe('42');
expect(result4.contentTypeName).toBe('api::another-type.another-type');
expect(result4.contentTypeId).toBe('4');
});

it('should return params from valid api paths', async function () {
Expand Down
10 changes: 10 additions & 0 deletions tests/matchAdminPath.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,20 @@ describe('utils: matchAdminPath', () => {
)
);

const result5 = Boolean(
matchAdminPath('/content-manager/single-types/api::foo-type.bar-type/')
);

const result6 = Boolean(
matchAdminPath('/content-manager/single-types/api::foo-type.bar-type/4')
);

expect(result1).toBe(true);
expect(result2).toBe(true);
expect(result3).toBe(true);
expect(result4).toBe(true);
expect(result5).toBe(true);
expect(result6).toBe(true);
});

it('should reject invalid paths', async function () {
Expand Down

0 comments on commit 59b3f9b

Please sign in to comment.