mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-29 07:09:48 +03:00
56029ff096
refs https://github.com/TryGhost/Team/issues/1408 - flag for gating access to "Name" and "Email" members filters that use NQL's contains operators
437 lines
22 KiB
Handlebars
437 lines
22 KiB
Handlebars
<section class="gh-canvas">
|
|
<GhCanvasHeader class="gh-canvas-header">
|
|
<h2 class="gh-canvas-title" data-test-screen-title>
|
|
<LinkTo @route="settings">Settings</LinkTo>
|
|
<span>{{svg-jar "arrow-right"}}</span>
|
|
Labs
|
|
</h2>
|
|
</GhCanvasHeader>
|
|
|
|
<section class="view-container settings-debug">
|
|
<p class="gh-box gh-box-tip">{{svg-jar "idea"}}This is a testing ground for new or experimental features. They may change, break or inexplicably disappear at any time.</p>
|
|
|
|
<div class="gh-main-section">
|
|
<h4 class="gh-main-section-header small bn">Migration options</h4>
|
|
<div class="gh-expandable">
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Import content</h4>
|
|
<p class="gh-expandable-description">Import posts from another Ghost installation</p>
|
|
</div>
|
|
<form id="settings-import" enctype="multipart/form-data">
|
|
<GhFileUpload
|
|
@id="importfile"
|
|
@classNames="flex"
|
|
@uploadButtonText={{this.uploadButtonText}}
|
|
@onUpload={{action "onUpload"}}
|
|
@acceptEncoding={{this.importMimeType}}
|
|
data-test-file-input="import"
|
|
/>
|
|
</form>
|
|
</div>
|
|
{{#if this.importErrors}}
|
|
<div class="gh-import-errors {{if this.importSuccessful "gh-import-errors-alert"}}" data-test-import-errors>
|
|
<div class="gh-import-errors-title">
|
|
{{#if this.importSuccessful}}
|
|
Import successful with warnings
|
|
{{else}}
|
|
Import failed
|
|
{{/if}}
|
|
</div>
|
|
|
|
{{#each this.importErrors as |error|}}
|
|
<div class="gh-import-error" data-test-import-error>
|
|
<p class="gh-import-error-message" data-test-import-error-message>
|
|
{{#if error.help}}{{error.help}}: {{/if}}{{error.message}}
|
|
</p>
|
|
|
|
{{#if error.context}}
|
|
<div class="gh-import-error-entry" data-test-import-error-context>
|
|
<pre>{{error.context}}</pre>
|
|
</div>
|
|
{{/if}}
|
|
</div>
|
|
{{/each}}
|
|
</div>
|
|
{{/if}}
|
|
</div>
|
|
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Export your content</h4>
|
|
<p class="gh-expandable-description">Download all of your posts and settings in a single, glorious JSON file</p>
|
|
</div>
|
|
<button type="button" class="gh-btn" {{action "downloadFile" "db"}}><span>Export</span></button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Delete all content</h4>
|
|
<p class="gh-expandable-description">Permanently delete all posts and tags from the database, a hard reset</p>
|
|
</div>
|
|
<button type="button" class="gh-btn gh-btn-red js-delete" {{action "toggleDeleteAllModal"}}><span>Delete</span></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="gh-main-section">
|
|
<h4 class="gh-main-section-header small bn">Beta features</h4>
|
|
<div class="gh-expandable">
|
|
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Tiers</h4>
|
|
<p class="gh-expandable-description">
|
|
Add additional tiers to your paid memberships (e.g. Bronze, Silver, Gold). <a href="http://ghost.org/help/tiers" target="_blank" rel="noopener noreferrer">Learn more here</a>
|
|
</p>
|
|
</div>
|
|
{{#if (feature "multipleProducts")}}
|
|
<span class="gh-badge">Enabled</span>
|
|
{{else}}
|
|
<button type="button" class="gh-btn" {{action "toggleEnableTiersModal"}}><span>Enable</span></button>
|
|
{{/if}}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="gh-expandable-block">
|
|
<GhUploader
|
|
@extensions={{this.redirectsFileExtensions}}
|
|
@uploadUrl="/redirects/upload/"
|
|
@paramName="redirects"
|
|
@onUploadSuccess={{perform this.redirectUploadResult true}}
|
|
@onUploadFailure={{perform this.redirectUploadResult false}}
|
|
as |uploader|
|
|
>
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Redirects</h4>
|
|
<p class="gh-expandable-description">Configure redirects for old or moved content, more info in <a href="https://ghost.org/docs/tutorials/implementing-redirects/" target="_blank" rel="noopener noreferrer">the docs</a></p>
|
|
</div>
|
|
<div class="gh-setting-action flex flex-column items-end">
|
|
{{#if uploader.isUploading}}
|
|
{{uploader.progressBar}}
|
|
{{else}}
|
|
<button
|
|
type="button"
|
|
class="gh-btn gh-btn-icon {{if this.redirectSuccess "gh-btn-green"}} {{if this.redirectFailure "gh-btn-red"}}"
|
|
onclick={{action "triggerFileDialog"}}
|
|
data-test-button="upload-redirects"
|
|
>
|
|
<span>
|
|
{{#if this.redirectSuccess}}
|
|
{{svg-jar "check-circle"}} Uploaded
|
|
{{else if this.redirectFailure}}
|
|
{{svg-jar "retry"}} Upload Failed
|
|
{{else}}
|
|
Upload redirects YAML/JSON
|
|
{{/if}}
|
|
</span>
|
|
</button>
|
|
<div><a href="#" {{action "downloadFile" "redirects/download"}} data-test-link="download-redirects">Download current redirects</a></div>
|
|
{{/if}}
|
|
|
|
{{#each uploader.errors as |error|}}
|
|
<div class="gh-setting-error" data-test-error="redirects">{{or error.context error.message}}</div>
|
|
{{/each}}
|
|
|
|
<div style="display:none">
|
|
<GhFileInput @multiple={{false}} @action={{uploader.setFiles}} @accept={{this.redirectsFileMimeTypes}} data-test-file-input="redirects" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</GhUploader>
|
|
</div>
|
|
|
|
<div class="gh-expandable-block">
|
|
<GhUploader
|
|
@extensions={{this.yamlExtension}}
|
|
@uploadUrl="/settings/routes/yaml/"
|
|
@paramName="routes"
|
|
@onUploadSuccess={{perform this.routesUploadResult true}}
|
|
@onUploadFailure={{perform this.routesUploadResult false}}
|
|
as |uploader|
|
|
>
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Routes</h4>
|
|
<p class="gh-expandable-description">Configure dynamic routing by modifying the routes.yaml file</p>
|
|
</div>
|
|
<div class="gh-setting-action flex flex-column items-end">
|
|
{{#if uploader.isUploading}}
|
|
{{uploader.progressBar}}
|
|
{{else}}
|
|
<button
|
|
type="button"
|
|
class="gh-btn gh-btn-icon {{if this.routesSuccess "gh-btn-green"}} {{if this.routesFailure "gh-btn-red"}}"
|
|
onclick={{action "triggerFileDialog"}}
|
|
data-test-button="upload-routes"
|
|
>
|
|
<span>
|
|
{{#if this.routesSuccess}}
|
|
{{svg-jar "check-circle"}} Uploaded
|
|
{{else if this.routesFailure}}
|
|
{{svg-jar "retry"}} Upload Failed
|
|
{{else}}
|
|
Upload routes YAML
|
|
{{/if}}
|
|
</span>
|
|
</button>
|
|
<div><a href="#" {{action "downloadFile" "settings/routes/yaml"}} data-test-link="download-routes">Download current routes.yaml</a></div>
|
|
{{/if}}
|
|
|
|
{{#each uploader.errors as |error|}}
|
|
<div class="gh-setting-error" data-test-error="routes">{{or error.context error.message}}</div>
|
|
{{/each}}
|
|
|
|
<div style="display:none">
|
|
<GhFileInput @multiple={{false}} @action={{uploader.setFiles}} @accept={{this.yamlAccept}} data-test-file-input="routes" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</GhUploader>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
{{#if (enable-developer-experiments)}}
|
|
<div class="gh-main-section">
|
|
<h4 class="gh-main-section-header small bn">Alpha Features</h4>
|
|
<div class="gh-expandable">
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Google OAuth for staff users</h4>
|
|
<p class="gh-expandable-description">
|
|
Allow people to sign into Ghost Admin using Google SSO,
|
|
<a href="https://ghost.org/docs/tutorials/setting-up-oauth/" target="_blank" rel="noopener noreferrer">docs here</a>
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="oauthLogin" />
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-content">
|
|
{{#if this.feature.oauthLogin}}
|
|
<div class="gh-setting-content-extended gh-labs-sso-settings pt2 pb4">
|
|
<a href="https://console.developers.google.com/" target="_blank" rel="noopener noreferrer" class="gh-btn gh-btn-white mb4"><span>{{svg-jar "google-favicon"}}Configure Google OAuth</span></a>
|
|
<GhFormGroup @class="no-margin pt2" @errors={{this.settings.errors}} @hasValidated={{this.settings.hasValidated}} @property="password">
|
|
<div class="form-group">
|
|
<label for="aouth-client-id">Google OAuth Client ID</label>
|
|
<GhTextInput
|
|
id="oauth-client-id"
|
|
@value={{readonly this.settings.oauthClientId}}
|
|
@name="oauth-client-id"
|
|
@focus-out={{action "saveOAuthSettings"}}
|
|
@input={{action (mut this.settings.oauthClientId) value="target.value"}}
|
|
/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="oauth-client-secret">Google OAuth Client Secret</label>
|
|
<GhTextInput
|
|
id="oauth-client-secret"
|
|
@value={{readonly this.settings.oauthClientSecret}}
|
|
@name="oauth-client-secret"
|
|
@focus-out={{action "saveOAuthSettings"}}
|
|
@input={{action (mut this.settings.oauthClientSecret) value="target.value"}}
|
|
/>
|
|
</div>
|
|
</GhFormGroup>
|
|
</div>
|
|
{{/if}}
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Members Activity</h4>
|
|
<p class="gh-expandable-description">
|
|
Enable recording of member activity for analytics
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="membersActivity" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">URL Cache</h4>
|
|
<p class="gh-expandable-description">
|
|
Enable URL Caching
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="urlCache" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Cardmageddon - Before/After</h4>
|
|
<p class="gh-expandable-description">
|
|
Card for comparing two images
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="beforeAfterCard" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Cardmageddon - Tweet grid</h4>
|
|
<p class="gh-expandable-description">
|
|
Card for displaying a group of related tweets
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="tweetGridCard" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Members activity feed</h4>
|
|
<p class="gh-expandable-description">
|
|
Separate activity feed screen showing all member activity.
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="membersActivityFeed" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Tier welcome pages</h4>
|
|
<p class="gh-expandable-description">
|
|
Add welcome pages per Tier (requires Tiers enabled)
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="tierWelcomePages" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Improved onboarding flow</h4>
|
|
<p class="gh-expandable-description">
|
|
Various tweaks to streamline the site creation and getting started flows.
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="improvedOnboarding" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Tier name</h4>
|
|
<p class="gh-expandable-description">
|
|
Add Tier names in Account settings (requires Tiers enabled)
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="tierName" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Members table status</h4>
|
|
<p class="gh-expandable-description">
|
|
Add member status/tier to the member's index table
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="membersTableStatus" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Members "Last seen" filter</h4>
|
|
<p class="gh-expandable-description">
|
|
Filter members by the date they were last seen (logged in or read an email)
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="membersLastSeenFilter" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Members time based filters</h4>
|
|
<p class="gh-expandable-description">
|
|
Filter members by date fields to answer time-based questions
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="membersTimeFilters" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Members "Contains" filters</h4>
|
|
<p class="gh-expandable-description">
|
|
Filter members by matching parts of their name and email fields
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="membersContainsFilters" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gh-expandable-block">
|
|
<div class="gh-expandable-header">
|
|
<div>
|
|
<h4 class="gh-expandable-title">Selectable portal links</h4>
|
|
<p class="gh-expandable-description">
|
|
Allow users to copy the full paths in portal settings
|
|
</p>
|
|
</div>
|
|
<div class="for-switch">
|
|
<GhFeatureFlag @flag="selectablePortalLinks" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
</section>
|
|
</section>
|
|
|
|
{{#if this.showDeleteAllModal}}
|
|
<GhFullscreenModal @modal="delete-all"
|
|
@close={{action "toggleDeleteAllModal"}}
|
|
@modifier="action wide" />
|
|
{{/if}}
|
|
|
|
{{#if this.showEnableTiersModal}}
|
|
<GhFullscreenModal @modal="enable-tiers"
|
|
@close={{action "toggleEnableTiersModal"}}
|
|
@modifier="action wide" />
|
|
{{/if}}
|