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

THR-18: dev feature h5p editor #3277

Merged
merged 24 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d7a2d2f
Thr 20 create UI elements (#3211)
marode-cap Jul 31, 2023
9679d76
Merge remote-tracking branch 'origin/main' into THR-18-dev-feature-h5…
marode-cap Aug 21, 2023
58c3cf1
Merge remote-tracking branch 'origin/main' into THR-18-dev-feature-h5…
marode-cap Aug 21, 2023
9aa48c2
add missing translations to es and uk
SteKrause Aug 21, 2023
bdbaf27
Merge branch 'main' into THR-18-dev-feature-h5p-editor
SteKrause Aug 25, 2023
ca463cc
Include parent info when opening H5P editor (#3290)
marode-cap Aug 30, 2023
18df0a9
Merge branch 'main' into THR-preview
ssmid Sep 18, 2023
fe11f49
Merge branch 'main' into THR-18-dev-feature-h5p-editor
SteKrause Sep 29, 2023
fffe080
Merge branch 'main' into THR-18-dev-feature-h5p-editor
casparneumann-cap Oct 6, 2023
9ce0f49
Merge branch 'main' into THR-18-dev-feature-h5p-editor
casparneumann-cap Oct 10, 2023
cb9246b
Merge branch 'main' into THR-18-dev-feature-h5p-editor
casparneumann-cap Oct 12, 2023
af6aaf3
fix default.schema json syntax error
casparneumann-cap Oct 12, 2023
d875dad
Merge branch 'main' into THR-preview
MajedAlaitwniCap Oct 12, 2023
0a142e7
Merge branch 'main' of https://github.com/hpi-schul-cloud/schulcloud-…
MajedAlaitwniCap Oct 13, 2023
80b3266
Merge branch 'THR-preview' into THR-18-dev-feature-h5p-editor
casparneumann-cap Oct 13, 2023
82dc65a
Compare feature flag string instead of boolean
marode-cap Oct 13, 2023
d0d0d91
Revert Config
marode-cap Oct 16, 2023
d707c3e
Merge branch 'main' into THR-18-dev-feature-h5p-editor
casparneumann-cap Oct 18, 2023
476d664
Merge branch 'main' into THR-18-dev-feature-h5p-editor
MajedAlaitwniCap Nov 2, 2023
d5d2aff
Merge branch 'main' into THR-18-dev-feature-h5p-editor
MajedAlaitwniCap Nov 6, 2023
19d1360
use onKeyDown for openEditorBind
casparneumann-cap Nov 6, 2023
352dee7
Merge branch 'THR-18-dev-feature-h5p-editor' of https://github.com/hp…
casparneumann-cap Nov 6, 2023
000f8fd
add missing Line break
MajedAlaitwniCap Nov 6, 2023
135671a
Merge branch 'main' into THR-18-dev-feature-h5p-editor
casparneumann-cap Nov 14, 2023
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
5 changes: 5 additions & 0 deletions config/default.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,11 @@
"type": "boolean",
"default": false,
"description": "Changes the login flow to one that supports user login migrations"
},
"FEATURE_H5P_EDITOR_ENABLED": {
"type": "boolean",
"default": false,
"description": "If enabled, adds H5P editor to course topics."
}
},
"allOf": [
Expand Down
8 changes: 7 additions & 1 deletion locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -3179,7 +3179,8 @@
"geoGebraWorksheet": "GeoGebra Arbeitsblatt",
"material": "Lern-Material",
"neXboard": "neXboard",
"text": "Text"
"text": "Text",
"h5p": "H5P"
},
"input": {
"brainstormAboutXYZ": "Brainstorming zum Thema XYZ",
Expand Down Expand Up @@ -3220,5 +3221,10 @@
"text": {
"nextcloudLink": "Wir arbeiten an einem neuen Dateibereich. Dort können ab jetzt alle <b>neuen Dateien</b> gespeichert und verwaltet werden (Dateibereich öffnen). Alle Team-Mitglieder haben automatisch Zugriff auf die dort gespeicherten Dateien. Alle bereits <b>bestehenden Dateien</b> in der {{title}} sind weiterhin hier verfügbar."
}
},
"h5p": {
"text": {
"createAfterFirstSave": "H5P Inhalte können erst nach dem ersten Speichern erstellt werden."
}
}
}
8 changes: 7 additions & 1 deletion locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3179,7 +3179,8 @@
"geoGebraWorksheet": "GeoGebra worksheet",
"material": "Learning material",
"neXboard": "neXboard",
"text": "Text"
"text": "Text",
"h5p": "H5P"
},
"input": {
"brainstormAboutXYZ": "Brainstorming on the topic XYZ",
Expand Down Expand Up @@ -3220,5 +3221,10 @@
"text": {
"nextcloudLink": "We are working on a new file space. From now on, all <b>new files</b> can be saved and managed there (open file area). All team members automatically have access to the files stored there. All already <b>existing files</b> in the {{title}} are still available here."
}
},
"h5p": {
"text": {
"createAfterFirstSave": "H5P contents can only be created after the first save."
}
}
}
122 changes: 122 additions & 0 deletions static/scripts/topicEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ class TopicBlockList extends React.Component {
*/
render() {
const neXboardEnabled = ($contentBlocksContainer.data('nexboardenabled') === true);
const h5pEditorEnabled = ($contentBlocksContainer.data('h5peditorenabled') === true);
return (
<div>
<SortableList
Expand Down Expand Up @@ -395,6 +396,15 @@ class TopicBlockList extends React.Component {
onClick={this.addBlock.bind(this, TopicInternal)}>
{`+ ${$t('global.headline.task')}`}
</button>
{h5pEditorEnabled ? <button
type="button"
className="btn btn-secondary"
data-testid="topic-addcontent-h5p-btn"
aria-label={$t('global.button.add')}
onClick={this.addBlock.bind(this, TopicH5P)}>
{`+ ${$t('topic.topicEdit.button.h5p')}`}
</button> : ''
}
</div>
</div>
</div>
Expand Down Expand Up @@ -432,6 +442,8 @@ class TopicBlock extends React.Component {
return TopicNexboard;
case 'Etherpad':
return TopicEtherpad;
case 'H5P':
return TopicH5P;
case 'internal':
return TopicInternal;
}
Expand Down Expand Up @@ -1023,6 +1035,116 @@ class TopicNexboard extends TopicBlock {
}
}

/**
* Class representing H5P
* @extends React.Component<{ content: { contentId: string } }>
*/
class TopicH5P extends TopicBlock {
/**
* Initialize the topic.
* @param {Object} props - Properties from React Component.
*/
constructor(props) {
super(props);
}

/**
* This function returns the name of the component that will be used to render the block in view mode.
*/
static get component() {
return 'H5P';
}

openEditor(id) {
const w = 1280;
const h = 1080;

const x = window.top.outerWidth / 2 + window.top.screenX - (w / 2);
const y = window.top.outerHeight / 2 + window.top.screenY - (h / 2);

const editorPopup = window.open(
`/h5p/editor/${id ?? ''}?inline=1`,
'h5p-editor',
`width=${w}, height=${h}, left=${x}, top=${y},
fullscreen=yes, toolbar=no, location=no, directories=no, status=no, scrollbars=yes, resizable=yes`,
);

editorPopup.addEventListener('save-content', (event) => {
this.props.onUpdate({ content: event.detail });
});

editorPopup.focus();
}

/**
* Render the block (an textarea)
*/
render() {
const infoBox = <div class="alert info-custom">
<div className="fa fa-info-circle" />
{$t('h5p.text.createAfterFirstSave')}
</div>;

const saved = !!this.props.parentId;

const { contentId, title, contentType } = this.props.content;

const h5pPreview =
<div className="card-columns">
<div className="card">
<div className="card-block">
<h4 className="card-title">
<a href={`/h5p/player/${contentId}?inline=1`} target="_blank">
casparneumann-cap marked this conversation as resolved.
Dismissed
Show resolved Hide resolved
{title}
</a>
</h4>
<p className="card-text">{contentType}</p>
</div>
<div className="card-footer">
<a className="btn-edit-h5p" onClick={this.openEditor.bind(this, contentId)}>
<i className="fa fa-edit"></i>
</a>
</div>
<input
type="hidden"
value={contentId}
name={`contents[${this.props.position}][content][contentId]`}
/>
<input
type="hidden"
value={title}
name={`contents[${this.props.position}][content][title]`}
/>
<input
type="hidden"
value={contentType}
name={`contents[${this.props.position}][content][contentType]`}
/>
</div>
</div>;

return (
<div>
{saved || infoBox}
{contentId && h5pPreview}
{!contentId &&
<div>
<button
disabled={!saved}
type="button"
className="btn btn-secondary btn-add"
data-testid="topic-h5p-create-btn"
onClick={this.openEditor.bind(this, contentId)}
>
{`+ ${$t('topic.topicEdit.button.h5p')}`}
</button>
</div>
}
</div>
);
}
}

/**
* Render the virtual React DOM into an <div> in the current page.
*/
Expand Down
9 changes: 9 additions & 0 deletions static/styles/courses/course.scss
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,15 @@
}
}

.btn-edit-h5p {
float: right;
cursor: pointer;

i {
color: $primaryColor;
}
}

.courseGroup {
width: 100%;
list-style: none;
Expand Down
26 changes: 26 additions & 0 deletions views/topic/components/content-H5P.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<h2 class="h4">{{title}}</h2>

{{#if content.contentId}}
<div class="card-columns">
<div class="card">
<div class="card-block">
<h4 class="card-title">
<a
href="/h5p/player/{{content.contentId}}?inline=1"
target="_blank"
class="externalLink"
>
{{content.title}}
</a>
{{#ifeq @root.theme.name "brb"}}
<div class="external-source-warning">
<h5>{{$t "topic._topic.text.warningMain"}}</h5>
<h6>{{$t "topic._topic.text.warningFooter"}}</h6>
</div>
{{/ifeq}}
</h4>
<p class="card-text">{{content.contentType}}</p>
</div>
</div>
</div>
{{/if}}
MajedAlaitwniCap marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion views/topic/edit-topic.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

<!-- React Magic -->
<div id="content-blocks" data-value="{{lesson.contents}}" data-parent-id="{{lesson._id}}" data-school-id="{{schoolId}}" data-parent-type="lessons" data-etherpadbaseurl="{{etherpadBaseUrl}}"
data-iscoursegroup="{{courseGroupId}}" data-nexboardenabled="{{#ifEnv "FEATURE_NEXBOARD_ENABLED" "true"}}true{{/ifEnv}}"></div>
data-iscoursegroup="{{courseGroupId}}" data-nexboardenabled="{{#ifEnv "FEATURE_NEXBOARD_ENABLED" "true"}}true{{/ifEnv}}" data-h5peditorenabled="{{#ifConfig "FEATURE_H5P_EDITOR_ENABLED" true}}true{{/ifConfig}}"></div>
</div>
{{#ifneq 0 (arrayLength @root.lessonFilesStorageData.files)}}
<label>{{$t "topic._topic.label.embeddedFiles" }}</label>
Expand Down