Skip to content

Commit

Permalink
Merge pull request #9 from andrehoffmann30/Issue-6-ux-imporvements
Browse files Browse the repository at this point in the history
FEATURE: always show link preview when editing link
  • Loading branch information
mficzel authored May 6, 2022
2 parents 11318bd + f1ba1e3 commit 6248838
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Configuration/Settings.Neos.Ui.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ Neos:
resources:
javascript:
'@sitegeist/archaeopteryx-plugin':
resource: 'resource://Sitegeist.Archaeopteryx/Public/JavaScript/Plugin.js'
resource: 'resource://Sitegeist.Archaeopteryx/Public/JavaScript/Plugin.js'
92 changes: 52 additions & 40 deletions Neos.Ui/core/src/application/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {ErrorBoundary} from '@sitegeist/archaeopteryx-error-handling';

import {Field} from '../../framework';
import {ILink, ILinkOptions, useEditorState, useEditorTransactions, useLinkTypes, useLinkTypeForHref} from '../../domain';
import {Layout, Form as StyledForm, Modal, Tabs, Deletable} from '../../presentation';
import {Layout, Form as StyledForm, Modal, Tabs, Deletable as Deletable} from '../../presentation';

import {LinkEditor} from './LinkEditor';
import {Settings} from './Settings';
Expand Down Expand Up @@ -187,59 +187,71 @@ const DialogWithValue: React.FC<{
const {enabledLinkOptions, editorOptions} = useEditorState();
const linkType = useLinkTypeForHref(props.value.href)!;
const {result} = linkType.useResolvedModel(props.value);
const {Preview} = linkType;
const exitingPreview = linkType.Preview;
const state = form.getState();
const model = (state.valid
const existingModel = (state.valid
? state.values.linkTypeProps?.[linkType.id.split('.').join('_')]
: result) ?? result;
const linkTypes = useLinkTypes();
const filteredLinkTypes = linkTypes.filter(linkType => editorOptions.linkTypes?.[linkType.id] && Object.keys(editorOptions.linkTypes?.[linkType.id]).includes('enabled') ? editorOptions.linkTypes?.[linkType.id].enabled : true);

return (
<Field name="linkTypeId" initialValue={linkType.id}>{() => (
<Field name="linkTypeId" initialValue={linkType.id}>{({input}) => (
<Tabs
lazy
from={[linkType]}
activeItemKey={linkType.id}
from={filteredLinkTypes}
activeItemKey={input.value || linkType.id}
getKey={linkType => linkType.id}
renderHeader={({id, TabHeader}) => (
<TabHeader
options={editorOptions.linkTypes?.[id] as any ?? {}}
/>
)}
renderPanel={linkType => (
<Layout.Stack>
{model ? (
<Deletable
onDelete={() => {
props.onDelete();
form.change('linkTypeProps', null);
}}
>
<ErrorBoundary>
<Preview
model={model}
options={editorOptions.linkTypes?.[linkType.id] as any ?? {}}
link={props.value}
/>
</ErrorBoundary>
</Deletable>
) : null}

<LinkEditor
key={linkType.id}
link={props.value}
linkType={linkType}
/>

{enabledLinkOptions.length && linkType.supportedLinkOptions.length ? (
<Settings
initialValue={props.value.options}
enabledLinkOptions={enabledLinkOptions.filter(
option => linkType.supportedLinkOptions.includes(option)
)}
renderPanel={linkType => {
const modelFromState = form.getState().values.linkTypeProps?.[linkType.id.split('.').join('_')]
let Preview = linkType.Preview;
let model = modelFromState;
if (!modelFromState || (linkType.id === 'Sitegeist.Archaeopteryx:Web' && !modelFromState?.urlWithoutProtocol) || (linkType.id === 'Sitegeist.Archaeopteryx:PhoneNumber' && !modelFromState?.phoneNumber)) {
Preview = exitingPreview;
model = existingModel;
}

return (
<Layout.Stack>
{model ? (
<Deletable
onDelete={() => {
props.onDelete();
form.change('linkTypeProps', null);
}}
>
<ErrorBoundary>
<Preview
model={model}
options={editorOptions.linkTypes?.[linkType.id] as any ?? {}}
link={props.value}
/>
</ErrorBoundary>
</Deletable>
) : null}

<LinkEditor
key={linkType.id}
link={linkType.isSuitableFor(props.value) ? props.value : null}
linkType={linkType}
/>
) : null}
</Layout.Stack>
)}

{enabledLinkOptions.length && linkType.supportedLinkOptions.length ? (
<Settings
initialValue={props.value.options}
enabledLinkOptions={enabledLinkOptions.filter(
option => linkType.supportedLinkOptions.includes(option)
)}
/>
) : null}
</Layout.Stack>
)}}
onSwitchTab={input.onChange}
/>
)}</Field>
);
Expand Down
7 changes: 6 additions & 1 deletion Neos.Ui/core/src/application/LinkTypes/MailTo/MailTo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ type MailToOptions = {
}
}

export const MailTo = makeLinkType<MailToLinkModel, MailToOptions>('Sitegeist.Archaeopteryx:MailTo', () => ({
export const MailTo = makeLinkType<MailToLinkModel, MailToOptions>('Sitegeist.Archaeopteryx:MailTo', ({createError}) => ({
isSuitableFor: (link: ILink) => link.href.startsWith('mailto:'),

useResolvedModel: (link: ILink) => {
if (!link.href.startsWith('mailto:')) {
return Process.error(
createError(`Cannot handle href "${link.href}".`)
);
}
const url = new URL(link.href);

return Process.success({
Expand Down
32 changes: 24 additions & 8 deletions Resources/Public/JavaScript/Plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -42568,26 +42568,38 @@ var DialogWithValue = function DialogWithValue(props) {
editorOptions = _c.editorOptions;
var linkType = domain_1.useLinkTypeForHref(props.value.href);
var result = linkType.useResolvedModel(props.value).result;
var Preview = linkType.Preview;
var exitingPreview = linkType.Preview;
var state = form.getState();
var model = (_b = state.valid ? (_a = state.values.linkTypeProps) === null || _a === void 0 ? void 0 : _a[linkType.id.split('.').join('_')] : result) !== null && _b !== void 0 ? _b : result;
return React.createElement(framework_1.Field, { name: "linkTypeId", initialValue: linkType.id }, function () {
return React.createElement(presentation_1.Tabs, { lazy: true, from: [linkType], activeItemKey: linkType.id, getKey: function getKey(linkType) {
var existingModel = (_b = state.valid ? (_a = state.values.linkTypeProps) === null || _a === void 0 ? void 0 : _a[linkType.id.split('.').join('_')] : result) !== null && _b !== void 0 ? _b : result;
var linkTypes = domain_1.useLinkTypes();
var filteredLinkTypes = linkTypes.filter(function (linkType) {
var _a, _b, _c;return ((_a = editorOptions.linkTypes) === null || _a === void 0 ? void 0 : _a[linkType.id]) && Object.keys((_b = editorOptions.linkTypes) === null || _b === void 0 ? void 0 : _b[linkType.id]).includes('enabled') ? (_c = editorOptions.linkTypes) === null || _c === void 0 ? void 0 : _c[linkType.id].enabled : true;
});
return React.createElement(framework_1.Field, { name: "linkTypeId", initialValue: linkType.id }, function (_a) {
var input = _a.input;
return React.createElement(presentation_1.Tabs, { lazy: true, from: filteredLinkTypes, activeItemKey: input.value || linkType.id, getKey: function getKey(linkType) {
return linkType.id;
}, renderHeader: function renderHeader(_a) {
var _b, _c;
var id = _a.id,
TabHeader = _a.TabHeader;
return React.createElement(TabHeader, { options: (_c = (_b = editorOptions.linkTypes) === null || _b === void 0 ? void 0 : _b[id]) !== null && _c !== void 0 ? _c : {} });
}, renderPanel: function renderPanel(linkType) {
var _a, _b;
var _a, _b, _c;
var modelFromState = (_a = form.getState().values.linkTypeProps) === null || _a === void 0 ? void 0 : _a[linkType.id.split('.').join('_')];
var Preview = linkType.Preview;
var model = modelFromState;
if (!modelFromState || linkType.id === 'Sitegeist.Archaeopteryx:Web' && !(modelFromState === null || modelFromState === void 0 ? void 0 : modelFromState.urlWithoutProtocol) || linkType.id === 'Sitegeist.Archaeopteryx:PhoneNumber' && !(modelFromState === null || modelFromState === void 0 ? void 0 : modelFromState.phoneNumber)) {
Preview = exitingPreview;
model = existingModel;
}
return React.createElement(presentation_1.Layout.Stack, null, model ? React.createElement(presentation_1.Deletable, { onDelete: function onDelete() {
props.onDelete();
form.change('linkTypeProps', null);
} }, React.createElement(archaeopteryx_error_handling_1.ErrorBoundary, null, React.createElement(Preview, { model: model, options: (_b = (_a = editorOptions.linkTypes) === null || _a === void 0 ? void 0 : _a[linkType.id]) !== null && _b !== void 0 ? _b : {}, link: props.value }))) : null, React.createElement(LinkEditor_1.LinkEditor, { key: linkType.id, link: props.value, linkType: linkType }), enabledLinkOptions.length && linkType.supportedLinkOptions.length ? React.createElement(Settings_1.Settings, { initialValue: props.value.options, enabledLinkOptions: enabledLinkOptions.filter(function (option) {
} }, React.createElement(archaeopteryx_error_handling_1.ErrorBoundary, null, React.createElement(Preview, { model: model, options: (_c = (_b = editorOptions.linkTypes) === null || _b === void 0 ? void 0 : _b[linkType.id]) !== null && _c !== void 0 ? _c : {}, link: props.value }))) : null, React.createElement(LinkEditor_1.LinkEditor, { key: linkType.id, link: linkType.isSuitableFor(props.value) ? props.value : null, linkType: linkType }), enabledLinkOptions.length && linkType.supportedLinkOptions.length ? React.createElement(Settings_1.Settings, { initialValue: props.value.options, enabledLinkOptions: enabledLinkOptions.filter(function (option) {
return linkType.supportedLinkOptions.includes(option);
}) }) : null);
} });
}, onSwitchTab: input.onChange });
});
};
//# sourceMappingURL=Dialog.js.map
Expand Down Expand Up @@ -43027,13 +43039,17 @@ var framework_1 = __webpack_require__(/*! ../../../framework */ "../core/lib/fra
var domain_1 = __webpack_require__(/*! ../../../domain */ "../core/lib/domain/index.js");
var presentation_1 = __webpack_require__(/*! ../../../presentation */ "../core/lib/presentation/index.js");
var simpleEmailRegex = /^[^\s@]+@[^\s@]+$/;
exports.MailTo = domain_1.makeLinkType('Sitegeist.Archaeopteryx:MailTo', function () {
exports.MailTo = domain_1.makeLinkType('Sitegeist.Archaeopteryx:MailTo', function (_a) {
var createError = _a.createError;
return {
isSuitableFor: function isSuitableFor(link) {
return link.href.startsWith('mailto:');
},
useResolvedModel: function useResolvedModel(link) {
var _a, _b, _c, _d;
if (!link.href.startsWith('mailto:')) {
return framework_1.Process.error(createError("Cannot handle href \"" + link.href + "\"."));
}
var url = new URL(link.href);
return framework_1.Process.success({
recipient: url.pathname,
Expand Down
2 changes: 1 addition & 1 deletion Resources/Public/JavaScript/Plugin.js.map

Large diffs are not rendered by default.

0 comments on commit 6248838

Please sign in to comment.