Skip to content

Commit 9d2e2a3

Browse files
committed
fix(editor): added option for consuming application to add samples in their code base, Readme pending
1 parent e9b2cce commit 9d2e2a3

File tree

5 files changed

+79
-34
lines changed

5 files changed

+79
-34
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<workspaceFilter version="1.0">
33
<filter root="/apps/cq/core/content/nav/tools/jcr-hopper" />
4-
<filter root="/apps/jcr-hopper" />
4+
<filter root="/apps/jcr-hopper">
5+
<exclude pattern="/apps/jcr-hopper/script-builder/samples(/.*)?" />
6+
</filter>
57
<filter root="/etc/jcr-hopper" />
68
</workspaceFilter>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<jcr:root
3+
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
4+
xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
5+
xmlns:cq="http://www.day.com/jcr/cq/1.0"
6+
xmlns:jcr="http://www.jcp.org/jcr/1.0"
7+
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
8+
jcr:mixinTypes="granite:PublicArea"
9+
jcr:primaryType="nt:folder"
10+
/>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Sample, SAMPLES } from '../model/samples';
2+
import { useEffect, useState } from 'react';
3+
import { Script } from '../model/Script';
4+
5+
export const useSamples = (): [Sample[], boolean] => {
6+
const [samples, setSamples] = useState<Sample[]>([]);
7+
const [loading, setLoading] = useState(false);
8+
9+
useEffect(() => {
10+
const loadSamples = async () => {
11+
setLoading(true);
12+
try {
13+
const response = await fetch('/apps/jcr-hopper/script-builder/samples/additional-samples.json');
14+
if (!response.ok) throw new Error(`Failed to fetch samples: ${response.statusText}`);
15+
16+
const fetchedData = await response.json();
17+
if (Array.isArray(fetchedData)) {
18+
const additionalSamples = fetchedData.map(item => ({
19+
label: item.label,
20+
config: item.config as Script,
21+
}));
22+
setSamples([...SAMPLES, ...additionalSamples]);
23+
} else {
24+
console.error('Fetched data is not an array:', fetchedData);
25+
}
26+
} catch (error) {
27+
console.error('Error fetching additional samples:', error);
28+
} finally {
29+
setLoading(false);
30+
}
31+
};
32+
loadSamples();
33+
}, []);
34+
35+
return [samples, loading];
36+
};

src/main/frontend/model/samples/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import renameNode from './rename-node.json';
1818
import { Hop, HOP_DEFINITIONS } from '../hops';
1919
import { Script } from '../Script';
2020

21-
type Sample = { label: string; config: Script };
21+
export type Sample = { label: string; config: Script };
2222

2323
function suggestionFromDefinition(key: keyof typeof HOP_DEFINITIONS): Sample {
2424
return {

src/main/frontend/sections/Toolbar.tsx

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useCopyToClipboard } from '@uidotdev/usehooks';
66
import { ScriptContext } from '../App';
77
import { INITIAL_SCRIPT } from '../model/Script';
88
import { Picker } from '../widgets/Picker';
9-
import { SAMPLES } from '../model/samples';
9+
import { useSamples } from '../hooks/useSamples';
1010

1111
const Elm = styled('div')`
1212
display: flex;
@@ -17,6 +17,31 @@ export const Toolbar: FC = () => {
1717
const script = scriptContext.draft;
1818

1919
const [, copy] = useCopyToClipboard();
20+
const [samples] = useSamples();
21+
22+
const handlePaste = async () => {
23+
try {
24+
const json = await navigator.clipboard.readText();
25+
const state = JSON.parse(json);
26+
if (typeof state !== 'object') throw new Error(`Pasted JSON is not an object: ${json}`);
27+
28+
if (Array.isArray(state)) {
29+
script.hops.push(...state);
30+
scriptContext.commit();
31+
} else {
32+
scriptContext.replace({ ...INITIAL_SCRIPT, ...state });
33+
}
34+
} catch (e) {
35+
console.error('Could not paste script', e);
36+
}
37+
};
38+
39+
const handleAddHop = (value: string) => {
40+
const sampleScript = samples[Number(value)]!.config;
41+
script.hops.push(...sampleScript.hops);
42+
script.parameters.push(...sampleScript.parameters);
43+
scriptContext.commit();
44+
};
2045

2146
return (
2247
<Elm className="toolbar">
@@ -29,43 +54,15 @@ export const Toolbar: FC = () => {
2954
>
3055
Copy
3156
</button>
32-
<button
33-
is="coral-button"
34-
icon="paste"
35-
onClick={async () => {
36-
try {
37-
const json = await navigator.clipboard.readText();
38-
const state = JSON.parse(json);
39-
// Sanity check
40-
if (typeof state !== 'object') {
41-
throw new Error(`Pasted JSON is not an object: ${json}`);
42-
}
43-
if (Array.isArray(state)) {
44-
// Assume steps were pasted in
45-
script.hops.push(...state);
46-
scriptContext.commit();
47-
} else {
48-
// Otherwise, it’s likely a complete script
49-
scriptContext.replace({ ...INITIAL_SCRIPT, ...state });
50-
}
51-
} catch (e) {
52-
console.error('Could not paste script', e);
53-
}
54-
}}
55-
>
57+
<button is="coral-button" icon="paste" onClick={handlePaste}>
5658
Paste
5759
</button>
5860
<Picker
5961
buttonLabel="Add"
6062
title="Add Hop to Script"
6163
buttonAttributes={{ icon: 'addChildPanel', is: 'coral-button' }}
62-
picked={value => {
63-
const sampleScript = SAMPLES[Number(value)]!.config;
64-
script.hops.push(...sampleScript.hops);
65-
script.parameters.push(...sampleScript.parameters);
66-
scriptContext.commit();
67-
}}
68-
items={SAMPLES.map(({ label }, i) => [String(i), label])}
64+
picked={handleAddHop}
65+
items={samples.map(({ label }, i) => [String(i), label])}
6966
/>
7067
<span className="flex-spacer"></span>
7168
<button is="coral-button" icon="undo" disabled={scriptContext.canUndo ? undefined : true} onClick={scriptContext.undo}>

0 commit comments

Comments
 (0)