diff --git a/backend/locales/en.json b/backend/locales/en.json index b88ff119d..2359c0df9 100644 --- a/backend/locales/en.json +++ b/backend/locales/en.json @@ -1885,6 +1885,7 @@ "editor.redirect.pickerTitle": "Select Redirection Target", "editor.redirect.showInterstitial": "Show Interstitial", "editor.redirect.showInterstitialHint": "Show a short notice saying where the reader is going before taking them there. Off sends them straight on.", + "editor.redirect.showInTreeHint": "List this redirection in the site's browse menu. Off keeps it out, which is usually what a doorway left behind for an old path should do. It is listed in the file manager either way.", "editor.redirect.summaryDirect": "Readers arriving at this page are sent to {target} right away.", "editor.redirect.summaryIncomplete": "This redirection has no target yet, and cannot be saved until it does.", "editor.redirect.summaryInterstitial": "Readers arriving at this page are told they are being sent to {target}, then taken there a few seconds later.", diff --git a/backend/models/pages.ts b/backend/models/pages.ts index a32d8b787..66788e2ad 100644 --- a/backend/models/pages.ts +++ b/backend/models/pages.ts @@ -894,7 +894,13 @@ class Pages { editor, hash, icon: input.icon ?? '', - isBrowsable: input.isBrowsable ?? true, + /* + A redirection is a doorway rather than a destination, so it stays out of the browse menu + unless its author says otherwise -- the same default the redirect editor's own toggle + opens on. Unlike `isSearchable` below this is a choice and not a rule: a redirection that + IS the name readers look for belongs in the menu, and saying so is all it takes. + */ + isBrowsable: input.isBrowsable ?? !isRedirect, // -> A redirection has nothing to find: a result for it would be a result whose page is a // doorway to the page the reader actually wanted, which is the one search should offer isSearchable: isRedirect ? false : (input.isSearchable ?? true), diff --git a/frontend/public/_assets/icons/blueprint-analytics.svg b/frontend/public/_assets/icons/blueprint-analytics.svg new file mode 100644 index 000000000..4759ed170 --- /dev/null +++ b/frontend/public/_assets/icons/blueprint-analytics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/_assets/icons/blueprint-comment.svg b/frontend/public/_assets/icons/blueprint-comment.svg new file mode 100644 index 000000000..6ac9a75fb --- /dev/null +++ b/frontend/public/_assets/icons/blueprint-comment.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/_assets/icons/blueprint-module.svg b/frontend/public/_assets/icons/blueprint-module.svg new file mode 100644 index 000000000..de6b17764 --- /dev/null +++ b/frontend/public/_assets/icons/blueprint-module.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/_assets/icons/blueprint-plugin.svg b/frontend/public/_assets/icons/blueprint-plugin.svg new file mode 100644 index 000000000..0c614f30a --- /dev/null +++ b/frontend/public/_assets/icons/blueprint-plugin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/_assets/icons/blueprint-security-lock.svg b/frontend/public/_assets/icons/blueprint-security-lock.svg new file mode 100644 index 000000000..0abb10725 --- /dev/null +++ b/frontend/public/_assets/icons/blueprint-security-lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/_assets/icons/blueprint-ssd.svg b/frontend/public/_assets/icons/blueprint-ssd.svg new file mode 100644 index 000000000..1e38a003b --- /dev/null +++ b/frontend/public/_assets/icons/blueprint-ssd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/_assets/icons/fluent-buoy.svg b/frontend/public/_assets/icons/fluent-buoy.svg new file mode 100644 index 000000000..6d5f9b0d9 --- /dev/null +++ b/frontend/public/_assets/icons/fluent-buoy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/_assets/icons/fluent-edit-property.svg b/frontend/public/_assets/icons/fluent-edit-property.svg new file mode 100644 index 000000000..420346062 --- /dev/null +++ b/frontend/public/_assets/icons/fluent-edit-property.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/EditorRedirect.vue b/frontend/src/components/EditorRedirect.vue index a081576d2..fd342b0d8 100644 --- a/frontend/src/components/EditorRedirect.vue +++ b/frontend/src/components/EditorRedirect.vue @@ -69,6 +69,23 @@ + + + + + + {{ t('editor.props.showInTree') }} + {{ t('editor.redirect.showInTreeHint') }} + + + + + + + @@ -126,8 +143,9 @@ import { usePageStore } from '@/stores/page' * The `redirect` editor: a page that sends its reader somewhere else. * * There is no content to write, so this is a form rather than an editor — a title, where the page - * points, and whether the reader is told about it on the way. All three are the page's own fields: - * the title is the page's, and the other two are its content, as JSON. See `helpers/pageRedirect.js`. + * points, whether it is offered in the browse menu, and whether the reader is told about it on the + * way. Two of those are the page's own fields — the title and `isBrowsable`, which the properties + * panel also edits — and the other two are its content, as JSON. See `helpers/pageRedirect.js`. * * What the page then DOES with that is `PageRedirect.vue`, which is what the page view draws in place * of an article. @@ -181,6 +199,18 @@ function setTitle(title) { touch() } +/** + * Whether the page is offered in the browse menu, which is the page's `isBrowsable` field rather than + * anything about the redirection — the same toggle the properties panel carries, put here because it + * is the question a redirection actually raises. Off for a new one: a redirection is usually a doorway + * left behind for an old path, and a menu of those is a menu of the same pages twice. The file manager + * lists it either way; this is the reader's menu, not the author's. + */ +function setIsBrowsable(isBrowsable) { + pageStore.isBrowsable = isBrowsable + touch() +} + function setShowInterstitial(showInterstitial) { state.showInterstitial = showInterstitial touch() diff --git a/frontend/src/stores/page.js b/frontend/src/stores/page.js index bd1ed2f4f..e5fc4f4f4 100644 --- a/frontend/src/stores/page.js +++ b/frontend/src/stores/page.js @@ -437,13 +437,15 @@ export const usePageStore = defineStore('page', { // -> A page being created has no stored source to lose: whatever it starts with IS the source contentLoaded: true, render: '', - isBrowsable: true, /* - A redirection is browsable like any other page and findable in none: a search result for one - would stand in front of the page the reader actually wanted. The server settles this either - way -- see `createPage` in `models/pages.ts` -- so this is the store agreeing with it rather - than deciding it. + A redirection is in neither the browse menu nor search by default: the first because it is a + doorway rather than a page to land on, the second because a result for one would stand in + front of the page the reader actually wanted. The server settles both the same way -- see + `createPage` in `models/pages.ts` -- so this is the store agreeing with it rather than + deciding it. The difference is that browsing is a choice the author can turn back on, in the + redirect editor or the properties panel, and searching is not offered at all. */ + isBrowsable: editor !== 'redirect', isSearchable: editor !== 'redirect', // -> The page being created is very often the one that was missing, and it is not missing now notFound: false,