1
0
Fork 0
mirror of https://github.com/TryGhost/Ghost-Admin.git synced 2023-12-14 02:33:04 +01:00

Added UI for setting tag metadata (#1632)

no-issue

* Updated tag model with new metadata fields
* Updated Tag setting UI to handle metadata

Co-authored-by: Peter Zimon <zimo@ghost.org>
This commit is contained in:
Fabien 'egg' O'Carroll 2020-07-13 14:58:13 +02:00 committed by GitHub
parent 8d3f4af03b
commit bd477449f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 471 additions and 79 deletions

View file

@ -1,21 +1,42 @@
<h4 class="midlightgrey f-small fw5 ttu">Basic settings</h4>
<div class="pa5 pt4 br4 shadow-1 bg-grouped-table mt2 flex flex-column flex-row-ns items-start justify-between gh-tag-basic-settings-form">
<div class="order-1 flex flex-column items-start mr5 w-100 w-50-m w-two-thirds-l">
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="name">
<label for="tag-name">Name</label>
<GhTextInput
@id="tag-name"
@name="name"
@value={{this.scratchTag.name}}
@tabindex="1"
@focus-out={{action "setProperty" "name" this.scratchTag.name}}
/>
<p class="description">
Start with # to create internal tags
<a href="https://ghost.org/docs/concepts/tags/#internal-tag" target="_blank" rel="noreferrer">Learn more</a>
</p>
<GhErrorMessage @errors={{this.tag.errors}} @property="name" />
</GhFormGroup>
<div class="gh-tag-settings-multiprop">
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="name" class="mr2 flex-auto">
<label for="tag-name">Name</label>
<GhTextInput
@id="tag-name"
@name="name"
@value={{this.scratchTag.name}}
@tabindex="1"
@focus-out={{action "setProperty" "name" this.scratchTag.name}}
/>
<span class="error">
<GhErrorMessage @errors={{this.tag.errors}} @property="name" />
<GhErrorMessage @errors={{this.tag.errors}} @property="accentColor" data-test-error="accentColor" />
</span>
<p class="description">
Start with # to create internal tags
<a href="https://ghost.org/docs/concepts/tags/#internal-tag" target="_blank" rel="noreferrer">Learn more</a>
</p>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="accentColor" class="gh-tag-settings-colorcontainer">
<label for="accent-color">Color</label>
<div class="input-color">
<GhTextInput
@name="accent-color"
@placeholder="abcdef"
@autocorrect="off"
@maxlength="6"
@focus-out={{action "validateAccentColor"}}
@value={{accentColor}}
data-test-input="accentColor"
/>
<div class="color-box" style={{this.accentColorBackgroundStyle}}></div>
</div>
</GhFormGroup>
</div>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="slug">
<label for="tag-slug">Slug</label>
@ -45,58 +66,280 @@
</GhFormGroup>
</div>
<div class="order-0 mb6 mb0-ns order-2-ns w-100 w-50-m w-third-l">
<label for="tag-image">Tag image</label>
<GhImageUploaderWithPreview
@image={{this.tag.featureImage}}
@text="Upload tag image"
@class="gh-tag-image-uploader"
@allowUnsplash={{true}}
@update={{action "setCoverImage"}}
@remove={{action "clearCoverImage"}}
/>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="featureImage">
<label for="tag-image">Tag image</label>
<GhImageUploaderWithPreview
@image={{this.tag.featureImage}}
@text="Upload tag image"
@class="gh-tag-image-uploader"
@allowUnsplash={{true}}
@update={{action "setCoverImage"}}
@remove={{action "clearCoverImage"}}
/>
</GhFormGroup>
</div>
</div>
<h4 class="midlightgrey f-small fw5 ttu mt15">Meta data</h4>
<div class="pa5 pt4 br4 shadow-1 bg-grouped-table mt2 flex flex-column flex-row-ns items-start justify-between">
<div class="flex flex-column items-start mr5 w-100 w-50-m w-two-thirds-l">
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="metaTitle">
<label for="meta-title">Meta Title</label>
<GhTextInput
@id="meta-title"
@name="metaTitle"
@placeholder={{this.scratchTag.name}}
@tabindex="4"
@value={{this.scratchTag.metaTitle}}
@focus-out={{action "setProperty" "metaTitle" this.scratchTag.metaTitle}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="metaTitle" />
<p>Recommended: <b>70</b> characters. Youve used {{gh-count-down-characters this.scratchTag.metaTitle 70}}</p>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="metaDescription">
<label for="meta-description">Meta Description</label>
<GhTextarea
@id="meta-description"
@name="metaDescription"
@class="gh-tag-details-textarea"
@placeholder={{this.scratchTag.description}}
@tabindex="5"
@value={{this.scratchTag.metaDescription}}
@focus-out={{action "setProperty" "metaDescription" this.scratchTag.metaDescription}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="metaDescription" />
<p>Recommended: <b>156</b> characters. Youve used {{gh-count-down-characters this.scratchTag.metaDescription 156}}</p>
</GhFormGroup>
</div>
<div class="w-100 w-50-m w-third-l">
<div class="form-group">
<label>Search Engine Result Preview</label>
<div class="seo-preview">
<div class="seo-preview-title">{{this.seoTitle}}</div>
<div class="seo-preview-link">{{this.seoURL}}</div>
<div class="seo-preview-description">{{this.seoDescription}}</div>
<div class="flex flex-column br3 shadow-1 bg-grouped-table mt2">
<section class="bb b--whitegrey pa5">
<div class="flex justify-between">
<div>
<h4 class="gh-setting-title">Metadata</h4>
<p class="gh-setting-desc pa0 ma0">Extra content for search engines.</p>
</div>
<div>
<button type="button" class="gh-btn" {{action (toggle "metadataOpen" this)}}><span>{{if this.metadataOpen "Close" "Expand"}}</span></button>
</div>
</div>
</div>
{{#liquid-if this.metadataOpen}}
<div class="mt6 flex flex-column flex-row-ns items-start justify-between">
<div class="flex flex-column items-start mr5 w-100 w-50-m w-two-thirds-l">
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="metaTitle">
<label for="meta-title">Meta Title</label>
<GhTextInput
@id="meta-title"
@name="metaTitle"
@placeholder={{this.scratchTag.name}}
@tabindex="4"
@value={{this.scratchTag.metaTitle}}
@focus-out={{action "setProperty" "metaTitle" this.scratchTag.metaTitle}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="metaTitle" />
<p>Recommended: <b>70</b> characters. Youve used {{gh-count-down-characters this.scratchTag.metaTitle 70}}</p>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="metaDescription">
<label for="meta-description">Meta Description</label>
<GhTextarea
@id="meta-description"
@name="metaDescription"
@class="gh-tag-details-textarea"
@placeholder={{this.scratchTag.description}}
@tabindex="5"
@value={{this.scratchTag.metaDescription}}
@focus-out={{action "setProperty" "metaDescription" this.scratchTag.metaDescription}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="metaDescription" />
<p>Recommended: <b>156</b> characters. Youve used {{gh-count-down-characters this.scratchTag.metaDescription 156}}</p>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="canonicalUrl">
<label for="canonical-url">Canonical URL</label>
<GhTextInput
@id="canonical-url"
@name="canonicalUrl"
@tabindex="4"
@value={{this.scratchTag.canonicalUrl}}
@focus-out={{action "validateCanonicalUrl"}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="canonicalUrl" />
</GhFormGroup>
</div>
<div class="w-100 w-50-m w-third-l">
<div class="form-group">
<label>Search Engine Result Preview</label>
<div class="seo-preview">
<div class="seo-preview-title">{{this.seoTitle}}</div>2.1
<div class="seo-preview-link">{{this.seoURL}}</div>
<div class="seo-preview-description">{{this.seoDescription}}</div>
</div>
</div>
</div>
</div>
{{/liquid-if}}
</section>
<section class="bb b--whitegrey pa5">
<div class="flex justify-between">
<div>
<h4 class="gh-setting-title">Twitter Card</h4>
<p class="gh-setting-desc pa0 ma0">Customised structured data for Twitter.</p>
</div>
<div>
<button type="button" class="gh-btn" {{action (toggle "twitterMetadataOpen" this)}}><span>{{if this.twitterMetadataOpen "Close" "Expand"}}</span></button>
</div>
</div>
{{#liquid-if this.twitterMetadataOpen}}
<div class="mt6 flex flex-column flex-row-ns items-start justify-between">
<div class="flex flex-column items-start mr5 w-100 w-50-m w-two-thirds-l">
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="twitterImage">
<label for="twitter-image">Twitter image</label>
<GhImageUploaderWithPreview
@image={{this.tag.twitterImage}}
@text="Add Twitter image"
@class="gh-tag-image-uploader"
@allowUnsplash={{true}}
@update={{action "setTwitterImage"}}
@remove={{action "clearTwitterImage"}}
/>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="twitterTitle">
<label for="twitter-title">Twitter title</label>
<GhTextInput
@id="twitter-title"
@name="twitterTitle"
@placeholder={{this.scratchTag.name}}
@tabindex="4"
@value={{this.scratchTag.twitterTitle}}
@focus-out={{action "setProperty" "twitterTitle" this.scratchTag.twitterTitle}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="twitterTitle" />
<p>Recommended: <b>70</b> characters. Youve used {{gh-count-down-characters this.scratchTag.twitterTitle 70}}</p>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="twitterDesctiption">
<label for="twitter-description">Twitter Description</label>
<GhTextarea
@id="twitter-description"
@name="twitterDescription"
@class="gh-tag-details-textarea"
@placeholder={{this.scratchTag.description}}
@tabindex="5"
@value={{this.scratchTag.twitterDescription}}
@focus-out={{action "setProperty" "twitterDescription" this.scratchTag.twitterDescription}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="twitterDescription" />
<p>Recommended: <b>156</b> characters. Youve used {{gh-count-down-characters this.scratchTag.twitterDescription 156}}</p>
</GhFormGroup>
</div>
<div class="w-100 w-50-m w-third-l">
<div class="form-group">
<label>Preview</label>
<div class="gh-twitter-preview">
{{#if this.twitterImage}}
<div class="gh-twitter-preview-image" style={{background-image-style this.twitterImage}}></div>
{{/if}}
<div class="gh-twitter-preview-content">
<div class="gh-twitter-preview-title">{{this.twitterTitle}}</div>
<div class="gh-twitter-preview-description">{{truncate this.twitterDescription 155}}</div>
<div class="gh-twitter-preview-footer">
<div class="gh-twitter-preview-footer-left">
{{this.config.blogDomain}}
</div>
<div class="gh-twitter-preview-footer-right">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{/liquid-if}}
</section>
<section class="bb b--whitegrey pa5">
<div class="flex justify-between">
<div>
<h4 class="gh-setting-title">Facebook card</h4>
<p class="gh-setting-desc pa0 ma0">Customise Open Graph data.</p>
</div>
<div>
<button type="button" class="gh-btn" {{action (toggle "facebookMetadataOpen" this)}}><span>{{if this.facebookMetadataOpen "Close" "Expand"}}</span></button>
</div>
</div>
{{#liquid-if this.facebookMetadataOpen}}
<div class="mt6 flex flex-column flex-row-ns items-start justify-between">
<div class="flex flex-column items-start mr5 w-100 w-50-m w-two-thirds-l">
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="ogImage">
<label for="og-image">Facebook image</label>
<GhImageUploaderWithPreview
@image={{this.tag.ogImage}}
@text="Add Facebook image"
@class="gh-tag-image-uploader"
@allowUnsplash={{true}}
@update={{action "setOgImage"}}
@remove={{action "clearOgImage"}}
/>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="metaTitle">
<label for="og-title">Facebook Title</label>
<GhTextInput
@id="og-title"
@name="ogTitle"
@placeholder={{this.scratchTag.name}}
@tabindex="4"
@value={{this.scratchTag.ogTitle}}
@focus-out={{action "setProperty" "ogTitle" this.scratchTag.ogTitle}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="ogTitle" />
<p>Recommended: <b>70</b> characters. Youve used {{gh-count-down-characters this.scratchTag.ogTitle 70}}</p>
</GhFormGroup>
<GhFormGroup @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="ogDescription">
<label for="og-description">Facebook Description</label>
<GhTextarea
@id="og-description"
@name="ogDescription"
@class="gh-tag-details-textarea"
@placeholder={{this.scratchTag.description}}
@tabindex="5"
@value={{this.scratchTag.ogDescription}}
@focus-out={{action "setProperty" "ogDescription" this.scratchTag.ogDescription}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="ogDescription" />
<p>Recommended: <b>156</b> characters. Youve used {{gh-count-down-characters this.scratchTag.ogDescription 156}}</p>
</GhFormGroup>
</div>
<div class="w-100 w-50-m w-third-l">
<div class="form-group">
<label>Preview</label>
<div class="gh-og-preview">
{{#if this.facebookImage}}
<div class="gh-og-preview-image" style={{background-image-style this.facebookImage}}></div>
{{/if}}
<div class="gh-og-preview-content">
<div class="gh-og-preview-title">{{truncate this.facebookTitle 88}}</div>
<div class="gh-og-preview-description">{{truncate this.facebookDescription 300}}</div>
<div class="gh-og-preview-footer">
<div class="gh-og-preview-footer-left">
{{this.config.blogDomain}} <span class="gh-og-preview-footer-left-divider">|</span> by <span class="gh-og-preview-footer-author">{{author-names this.post.authors}}</span>
</div>
<div class="gh-og-preview-footer-right">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{/liquid-if}}
</section>
<section class="bb b--whitegrey pa5">
<div class="flex justify-between">
<div>
<h4 class="gh-setting-title">Code injection</h4>
<p class="gh-setting-desc pa0 ma0">Add styles/scripts to the header and footer.</p>
</div>
<div>
<button type="button" class="gh-btn" {{action (toggle "codeInjectionOpen" this)}}><span>{{if this.codeInjectionOpen "Close" "Expand"}}</span></button>
</div>
</div>
{{#liquid-if this.codeInjectionOpen}}
<div class="mt6 flex flex-column flex-row-ns flex-wrap items-start justify-between">
<GhFormGroup @class="settings-code" @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="codeinjectionHead">
<label for="codeinjection-head" class="gh-tag-setting-codeheader">Tag header <code class="fw4 ml1">\{{ghost_head}}</code></label>
<GhCmEditor @value={{this.codeinjectionHeadScratch}}
@id="tag-setting-codeinjection-head"
@class="gh-tag-setting-codeinjection"
@name="tag-setting-codeinjection-head"
@focusOut={{action "setProperty" "codeinjectionHead" this.codeinjectionHeadScratch}}
@stopEnterKeyDownPropagation="true"
@update={{action (mut this.codeinjectionHeadScratch)}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="codeinjectionHead"/>
</GhFormGroup>
<GhFormGroup @class="settings-code" @errors={{this.tag.errors}} @hasValidated={{this.tag.hasValidated}} @property="codeinjectionFoot">
<label for="codeinjection-foot"class="gh-tag-setting-codeheader">Tag footer <code class="fw4 ml1">\{{ghost_foot}}</code></label>
<GhCmEditor @value={{this.codeinjectionfootScratch}}
@id="tag-setting-codeinjection-foot"
@class="gh-tag-setting-codeinjection"
@name="tag-setting-codeinjection-foot"
@focusOut={{action "setProperty" "codeinjectionFoot" this.codeinjectionFootScratch}}
@stopEnterKeyDownPropagation="true"
@update={{action (mut this.codeinjectionFootScratch)}}
/>
<GhErrorMessage @errors={{this.tag.errors}} @property="codeinjectionFoot"/>
</GhFormGroup>
</div>
{{/liquid-if}}
</section>
</div>

View file

@ -2,6 +2,8 @@ import Component from '@ember/component';
import Ember from 'ember';
import {computed} from '@ember/object';
import {htmlSafe} from '@ember/string';
import {or} from '@ember/object/computed';
import {run} from '@ember/runloop';
import {inject as service} from '@ember/service';
const {Handlebars} = Ember;
@ -16,6 +18,27 @@ export default Component.extend({
// Allowed actions
setProperty: () => {},
twitterTitle: or('scratchTag.twitterTitle', 'seoTitle'),
twitterDescription: or('scratchTag.twitterDescription', 'seoDescription'),
twitterImage: or('tag.twitterImage', 'tag.featureImage'),
facebookTitle: or('scratchTag.ogTitle', 'seoTitle'),
facebookDescription: or('scratchTag.ogDescription', 'seoDescription'),
facebookImage: or('tag.ogImage', 'tag.featureImage'),
accentColor: computed('tag.accentColor', function () {
let color = this.get('tag.accentColor');
if (color && color[0] === '#') {
return color.slice(1);
}
return color;
}),
accentColorBackgroundStyle: computed('tag.accentColor', function () {
let color = this.get('tag.accentColor') || '#ffffff';
return htmlSafe(`background-color: ${color}`);
}),
title: computed('tag.isNew', function () {
if (this.get('tag.isNew')) {
return 'New tag';
@ -24,10 +47,8 @@ export default Component.extend({
}
}),
seoTitle: computed('scratchTag.{title,metaTitle}', function () {
let metaTitle = this.scratchTag.metaTitle || '';
metaTitle = metaTitle.length > 0 ? metaTitle : this.scratchTag.title;
seoTitle: computed('scratchTag.{name,metaTitle}', function () {
let metaTitle = this.scratchTag.metaTitle || this.scratchTag.name;
if (metaTitle && metaTitle.length > 70) {
metaTitle = metaTitle.substring(0, 70).trim();
@ -38,14 +59,15 @@ export default Component.extend({
return metaTitle;
}),
seoURL: computed('scratchTag.slug', function () {
seoURL: computed('scratchTag.{canonicalUrl,slug}', function () {
let blogUrl = this.get('config.blogUrl');
let seoSlug = this.scratchTag.slug || '';
let seoURL = `${blogUrl}/tag/${seoSlug}`;
let seoURL = this.scratchTag.canonicalUrl || `${blogUrl}/tag/${seoSlug}`;
// only append a slash to the URL if the slug exists
if (seoSlug) {
if (!seoURL.endsWith('/')) {
seoURL += '/';
}
@ -77,12 +99,91 @@ export default Component.extend({
this.setProperty(property, value);
},
setTwitterImage(image) {
this.setProperty('twitterImage', image);
},
clearTwitterImage() {
this.setProperty('twitterImage', '');
},
setOgImage(image) {
this.setProperty('ogImage', image);
},
clearOgImage() {
this.setProperty('ogImage', '');
},
setCoverImage(image) {
this.setProperty('featureImage', image);
},
clearCoverImage() {
this.setProperty('featureImage', '');
},
validateCanonicalUrl() {
let newUrl = this.get('scratchTag.canonicalUrl');
let oldUrl = this.get('tag.canonicalUrl');
let errMessage = '';
this.get('tag.errors').remove('canonicalUrl');
this.get('tag.hasValidated').removeObject('canonicalUrl');
if (newUrl === '') {
this.setProperty('canonicalUrl', '');
return;
}
if (!newUrl) {
newUrl = oldUrl;
}
try {
new URL(newUrl);
this.setProperty('canonicalUrl', '');
run.schedule('afterRender', this, function () {
this.setProperty('canonicalUrl', newUrl);
});
} catch (err) {
errMessage = 'The url should be a valid url';
this.get('tag.errors').add('canonicalUrl', errMessage);
this.get('tag.hasValidated').pushObject('canonicalUrl');
}
},
validateAccentColor() {
let newColor = this.get('accentColor');
let oldColor = this.get('tag.accentColor');
let errMessage = '';
this.get('tag.errors').remove('accentColor');
this.get('tag.hasValidated').removeObject('accentColor');
if (newColor === '') {
this.setProperty('accentColor', '');
return;
}
if (!newColor) {
newColor = oldColor;
}
if (newColor[0] !== '#') {
newColor = `#${newColor}`;
}
if (newColor.match(/#[0-9A-Fa-f]{6}$/)) {
this.setProperty('accentColor', '');
run.schedule('afterRender', this, function () {
this.setProperty('accentColor', newColor);
});
} else {
errMessage = 'The color should be in valid hex format';
this.get('tag.errors').add('accentColor', errMessage);
this.get('tag.hasValidated').pushObject('accentColor');
}
}
}
});

View file

@ -88,6 +88,9 @@ export default Controller.extend({
tag.setProperties(scratchProps);
try {
if (tag.get('errors').length !== 0) {
return;
}
yield tag.save();
// replace 'new' route with 'tag' route

View file

@ -12,6 +12,16 @@ export default Model.extend(ValidationEngine, {
parent: attr('string'), // unused
metaTitle: attr('string'),
metaDescription: attr('string'),
twitterImage: attr('string'),
twitterTitle: attr('string'),
twitterDescription: attr('string'),
ogImage: attr('string'),
ogTitle: attr('string'),
ogDescription: attr('string'),
codeinjectionHead: attr('string'),
codeinjectionFoot: attr('string'),
canonicalUrl: attr('string'),
accentColor: attr('string'),
featureImage: attr('string'),
visibility: attr('string', {defaultValue: 'public'}),
createdAtUTC: attr('moment-utc'),

View file

@ -813,8 +813,8 @@ p.theme-validation-details {
.input-color:after {
content: "#";
position: absolute;
top: 6px;
left: 40px;
top: 9px;
left: 43px;
color: var(--midlightgrey);
font-family: "Consolas", monaco, monospace;
font-size: 13px;
@ -825,9 +825,9 @@ p.theme-validation-details {
}
.input-color input {
padding-left: 48px;
width: 110px;
height: 33px;
padding-left: 52px;
width: 112px;
height: 38px;
padding-right: 8px;
font-family: "Consolas", monaco, monospace;
font-size: 13px;
@ -837,8 +837,8 @@ p.theme-validation-details {
position: absolute;
top: 1px;
left: 1px;
width: 31px;
height: 31px;
width: 36px;
height: 36px;
display: inline-block;
background-color: var(--lightgrey);
border-top-left-radius: 4px;
@ -850,8 +850,8 @@ p.theme-validation-details {
.input-color input:focus + .color-box {
top: 2px;
left: 2px;
width: 30px;
height: 29px;
width: 35px;
height: 34px;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}

View file

@ -138,4 +138,39 @@ textarea.gh-tag-details-textarea {
margin: 4px 0 0;
border: 1px solid var(--lightgrey);
min-height: 147px;
}
.gh-tag-setting-codeinjection .CodeMirror {
padding: 0 !important;
min-height: 240px;
}
.gh-tag-setting-codeinjection .CodeMirror-scroll {
min-height: 240px;
}
label.gh-tag-setting-codeheader {
font-size: 1.3rem;
display: flex;
align-items: center;
}
.gh-tag-settings-multiprop {
display: flex;
max-width: 620px;
width: 100%;
}
.gh-tag-settings-colorcontainer {
flex-basis: 112px;
}
@media (max-width: 1080px) {
.gh-tag-settings-multiprop {
flex-direction: column;
}
.gh-tag-settings-colorcontainer {
flex-basis: unset;
}
}