[NEW] Rocketapps inputs (#10394)

[FIX] Missing RocketApps input types
pull/10225/head^2
Guilherme Gazzo 8 years ago committed by Rodrigo Nascimento
parent f64e03c3f6
commit c978136fd4
  1. 2
      package-lock.json
  2. 336
      packages/rocketchat-apps/client/admin/appManage.html
  3. 42
      packages/rocketchat-apps/client/admin/appManage.js
  4. 4
      packages/rocketchat-theme/client/imports/forms/input.css
  5. 8
      packages/rocketchat-theme/client/imports/forms/select.css
  6. 4
      packages/rocketchat-theme/client/imports/general/apps.css
  7. 2
      packages/rocketchat-ui-master/public/icons.svg
  8. 6
      packages/rocketchat-ui/client/views/app/directory.html
  9. 8
      packages/rocketchat-ui/client/views/app/directory.js

2
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "Rocket.Chat",
"version": "0.63.0-rc.1",
"version": "0.64.0-develop",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

@ -55,31 +55,31 @@
<div class="rc-apps-settings__item">
{{#if $eq type 'string'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-input__wrapper">
{{#if multiline}}
<textarea class="rc-input__element" name="{{id}}" rows="4" style="height: auto">{{value}}</textarea>
{{else}}
<input class="rc-input__element" type="text" name="{{id}}" value="{{value}}" placeholder="{{_ i18nPlaceholder}}" />
{{/if}}
</div>
</label>
{{# if i18nDescription}}
<div class="rc-input__description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{# if i18nAlert}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-input__wrapper">
{{#if multiline}}
<textarea class="rc-input__element" name="{{id}}" rows="4" style="height: auto">{{value}}</textarea>
{{else}}
<input class="rc-input__element" type="text" name="{{id}}" value="{{value}}" placeholder="{{_ i18nPlaceholder}}" />
{{/if}}
</div>
</label>
{{# if i18nDescription}}
<div class="rc-input__description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{# if i18nAlert}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
</div>
<div class="rc-input__error-message">{{_ "i18nAlert"}}</div>
</div>
<div class="rc-input__error-message">{{_ "i18nAlert"}}</div>
{{/if}}
</div>
{{/if}}
</div>
{{else if $eq type 'boolean'}}
<div class="rc-switch rc-switch--blue">
<div class="rc-switch rc-switch--blue">
<label class="rc-switch__label" tabindex="-1" for="{{id}}">
<input type="checkbox" class="rc-switch__input" name="{{id}}" id="{{id}}" checked="{{$eq value true}}">
<span class="rc-switch__button">
@ -91,7 +91,7 @@
</label>
<span class="rc-switch__description">{{{parseDescription i18nDescription}}}</span>
</div>
{{else if $eq type 'int'}}
{{else if $eq type 'int'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
@ -115,7 +115,7 @@
</div>
{{/if}}
</div>
{{else if $eq type 'password'}}
{{else if $eq type 'password'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
@ -139,129 +139,237 @@
</div>
{{/if}}
</div>
{{else}}
<div class="input-line double-col">
<label class="setting-label">{{_ i18nLabel}}</label>
<div class="setting-field">
{{#if $eq type 'relativeUrl'}}
<input class="input-monitor" type="text" name="{{id}}" value="{{relativeUrl value}}" placeholder="{{_ i18nPlaceholder}}" {{isReadonly}}/>
{{else if $eq type 'relativeUrl'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-input__wrapper">
{{#if $eq type 'relativeUrl'}}
<input class="rc-input__element" type="text" name="{{id}}" value="{{relativeUrl value}}" placeholder="{{_ i18nPlaceholder}}" {{isReadonly}}/>
{{/if}}
</div>
</label>
{{# if i18nDescription}}
<div class="rc-input__description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{#if $eq type 'select'}}
<div class="select-arrow">
<i class="icon-down-open secondary-font-color"></i>
{{# if i18nAlert}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
</div>
<div class="rc-input__error-message">{{_ "i18nAlert"}}</div>
</div>
<select class="input-monitor" name="{{id}}">
{{#each values}}
<option value="{{key}}" selected="{{selectedOption ../id key}}">{{_ i18nLabel}}</option>
{{/each}}
</select>
{{/if}}
{{#if $eq type 'language'}}
<div class="select-arrow">
<i class="icon-down-open secondary-font-color"></i>
</div>
{{else if $eq type 'font'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-input__wrapper">
{{#if multiline}}
<textarea class="rc-input__element" name="{{id}}" rows="4" style="height: auto">{{value}}</textarea>
{{else}}
<input class="rc-input__element" type="text" name="{{id}}" value="{{value}}" placeholder="{{_ i18nPlaceholder}}" />
{{/if}}
</div>
</label>
{{# if i18nDescription}}
<div class="rc-input__description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{# if i18nAlert}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
</div>
<div class="rc-input__error-message">{{_ "i18nAlert"}}</div>
</div>
<select class="input-monitor" name="{{id}}">
{{#each languages}}
<option value="{{key}}" selected="{{appLanguage key}}" dir="auto">{{name}}</option>
{{/each}}
</select>
{{/if}}
{{#if $eq type 'color'}}
<div class="horizontal">
{{#if $eq editor 'color'}}
<div class="flex-grow-1">
<input class="input-monitor colorpicker-input" type="text" name="{{id}}" value="{{value}}" autocomplete="off"/>
<span class="colorpicker-swatch border-component-color" style="background-color: {{value}}"></span>
</div>
{{else if $eq type 'code'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-input__wrapper">
{{#if isDisabled.disabled}}
{{> CodeMirror name=id options=(getEditorOptions true) code=(i18nDefaultValue) }}
{{else}}
<div class="code-mirror-box" data-editor-id="{{id}}">
<div class="title">
{{label}}
</div>
{{> CodeMirror name=id options=getEditorOptions code=value }}
<div class="buttons">
<button class="button primary button-fullscreen">Full Screen</button>
<button class="button primary button-restore">Exit Full Screen</button>
</div>
</div>
{{/if}}
</div>
{{/if}}
{{#if $eq editor 'expression'}}
<div class="flex-grow-1">
<input class="input-monitor" type="text" name="{{id}}" value="{{value}}"/>
</label>
{{# if i18nDescription}}
<div class="rc-input__description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{# if i18nAlert}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
</div>
{{/if}}
<div class="color-editor">
<div class="select-arrow">
<i class="icon-down-open secondary-font-color"></i>
</div>
<select name="color-editor">
{{#each allowedTypes}}
<option value="{{.}}" selected="{{$eq ../editor .}}">{{_ .}}</option>
<div class="rc-input__error-message">{{_ "i18nAlert"}}</div>
</div>
{{/if}}
</div>
{{else if $eq type 'select'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-select">
<select class="rc-select__element" name="{{id}}">
{{#each values}}
<option class="rc-select__option" value="{{key}}" selected="{{selectedOption ../id key}}">{{_ i18nLabel}}</option>
{{/each}}
</select>
{{> icon block="rc-select__arrow" icon="arrow-down" }}
</div>
</label>
{{# if i18nDescription}}
<div class="rc-input__description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{# if i18nAlert}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
</div>
<div class="rc-input__error-message">{{_ "i18nAlert"}}</div>
</div>
<div class="settings-description">Variable name: {{getColorVariable id}}</div>
{{/if}}
</div>
{{#if $eq type 'font'}}
<input class="input-monitor" type="text" name="{{id}}" value="{{value}}"/>
{{/if}}
{{else if $eq type 'color'}}
{{#if $eq type 'code'}}
{{#if isDisabled.disabled}}
{{> CodeMirror name=id options=(getEditorOptions true) code=(i18nDefaultValue) }}
{{else}}
<div class="code-mirror-box" data-editor-id="{{id}}">
<div class="title">
{{label}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-input__wrapper">
{{#if multiline}}
<textarea class="rc-input__element" name="{{id}}" rows="4" style="height: auto">{{value}}</textarea>
{{else}}
<input class="rc-input__element" type="color" name="{{id}}" value="{{value}}" placeholder="{{_ i18nPlaceholder}}" />
{{/if}}
</div>
{{> CodeMirror name=id options=getEditorOptions code=value }}
{{setEditorOnBlur id}}
<div class="buttons">
<button class="button primary button-fullscreen">Full Screen</button>
<button class="button primary button-restore">Exit Full Screen</button>
</label>
{{# if i18nDescription}}
<div class="rc-input__description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{# if i18nAlert}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
</div>
<div class="rc-input__error-message">{{_ "i18nAlert"}}</div>
</div>
{{/if}}
</div>
<!-- <div class="horizontal">
{{#if $eq editor 'color'}}
<div class="flex-grow-1">
<input class="input-monitor colorpicker-input" type="text" name="{{id}}" value="{{value}}" autocomplete="off"/>
<span class="colorpicker-swatch border-component-color" style="background-color: {{value}}"></span>
</div>
{{/if}}
{{#if $eq editor 'expression'}}
<div class="flex-grow-1">
<input class="input-monitor" type="" name="{{id}}" value="{{value}}"/>
</div>
{{/if}}
<div class="color-editor">
<div class="select-arrow">
<i class="icon-down-open secondary-font-color"></i>
</div>
<select name="color-editor">
{{#each allowedTypes}}
<option value="{{.}}" selected="{{$eq ../editor .}}">{{_ .}}</option>
{{/each}}
</select>
</div>
</div>
<div class="settings-description">Variable name: {{getColorVariable id}}</div> -->
{{ else if $eq type 'language'}}
{{#if $eq type 'action'}}
{{#if hasChanges section}}
<span style="line-height: 40px" class="secondary-font-color">{{_ "Save_to_enable_this_action"}}</span>
{{else}}
<button type="button" class="button primary action" data-setting="{{id}}" data-action="{{value}}">{{_ actionText}}</button>
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-select">
<select class="rc-select__element" name="{{id}}">
{{#each languages}}
<option class="rc-select__option" value="{{key}}" selected="{{selectedOption key}}">{{_ name}}</option>
{{/each}}
</select>
{{> icon block="rc-select__arrow" icon="arrow-down" }}
</div>
</label>
{{# if i18nDescription}}
<div class="rc-input__description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{# if i18nAlert}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
</div>
<div class="rc-input__error-message">{{_ "i18nAlert"}}</div>
</div>
{{/if}}
</div>
{{else}}
<div class="input-line double-col">
<label class="setting-label">{{_ i18nLabel}}</label>
<div class="setting-field">
{{#if $eq type 'action'}}
{{#if hasChanges section}}
<span style="line-height: 40px" class="secondary-font-color">{{_ "Save_to_enable_this_action"}}</span>
{{else}}
<button type="button" class="button primary action" data-setting="{{id}}" data-action="{{value}}">{{_ actionText}}</button>
{{/if}}
{{/if}}
{{#if $eq type 'asset'}}
{{#if value.url}}
<div class="settings-file-preview">
<div class="preview" style="background-image:url({{value.url}}?_dc={{random}});"></div>
<div class="action">
<button type="button" class="button danger delete-asset"><i class="icon-trash secondary-font-color"></i>{{_ 'Delete'}}</button>
{{#if value.url}}
<div class="settings-file-preview">
<div class="preview" style="background-image:url({{value.url}}?_dc={{random}});"></div>
<div class="action">
<button type="button" class="button danger delete-asset"><i class="icon-trash secondary-font-color"></i>{{_ 'Delete'}}</button>
</div>
</div>
</div>
{{else}}
<div class="settings-file-preview">
<div class="preview no-file background-transparent-light secondary-font-color"><i class="icon-upload secondary-font-color"></i></div>
<div class="action">
<div class="button primary">{{_ 'Select_file'}}
<input type="file" accept="{{assetAccept fileConstraints}}" />
{{else}}
<div class="settings-file-preview">
<div class="preview no-file background-transparent-light secondary-font-color"><i class="icon-upload secondary-font-color"></i></div>
<div class="action">
<div class="button primary">{{_ 'Select_file'}}
<input type="file" accept="{{assetAccept fileConstraints}}" />
</div>
</div>
</div>
</div>
{{/if}}
{{/if}}
{{/if}}
{{#if $eq type 'roomPick'}}
<div>
{{> inputAutocomplete settings=autocompleteRoom id=id name=id class="search autocomplete" autocomplete="off" disabled=isDisabled.disabled}}
<ul class="selected-rooms">
{{#each selectedRooms}}
<li class="remove-room" data-setting={{../id}}>{{name}} <i class="icon-cancel secondary-font-color"></i></li>
{{/each}}
</ul>
</div>
<div>
{{> inputAutocomplete settings=autocompleteRoom id=id name=id class="search autocomplete" autocomplete="off" disabled=isDisabled.disabled}}
<ul class="selected-rooms">
{{#each selectedRooms}}
<li class="remove-room" data-setting={{../id}}>{{name}} <i class="icon-cancel secondary-font-color"></i></li>
{{/each}}
</ul>
</div>
{{/if}}
{{#if i18nDescription}}
<div class="settings-description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{#if i18nAlert}}
<div class="settings-alert pending-color pending-background pending-border"><i class="icon-attention secondary-font-color"></i>{{{_ i18nAlert}}}</div>
<div class="settings-description">{{{parseDescription i18nDescription}}}</div>
{{/if}}
{{#if i18nAlert}}
<div class="settings-alert pending-color pending-background pending-border"><i class="icon-attention secondary-font-color"></i>{{{_ i18nAlert}}}</div>
{{/if}}
</div>
</div>

@ -74,6 +74,33 @@ Template.apps.onDestroyed(function() {
});
Template.appManage.helpers({
languages() {
const languages = TAPi18n.getLanguages();
let result = Object.keys(languages).map(key => {
const language = languages[key];
return _.extend(language, { key });
});
result = _.sortBy(result, 'key');
result.unshift({
'name': 'Default',
'en': 'Default',
'key': ''
});
return result;
},
appLanguage(key) {
const setting = RocketChat.settings.get('Language');
return setting && setting.split('-').shift().toLowerCase() === key;
},
selectedOption(_id, val) {
const settings = Template.instance().settings.get();
return settings[_id].value === val;
},
getColorVariable(color) {
return color.replace(/theme-color-/, '@');
},
disabled() {
const t = Template.instance();
const settings = t.settings.get();
@ -240,7 +267,20 @@ Template.appManage.events({
}
},
'input input': _.throttle(function(e, t) {
'change .rc-select__element' : (e, t) => {
const labelFor = $(e.currentTarget).attr('name');
const value = $(e.currentTarget).val();
const setting = t.settings.get()[labelFor];
if (setting) {
setting.value = value;
t.settings.get()[labelFor].hasChanged = setting.oldValue !== setting.value;
t.settings.set(t.settings.get());
}
},
'input input, input textarea, change input[type="color"]': _.throttle(function(e, t) {
let value = s.trim($(e.target).val());
switch (this.type) {
case 'int':

@ -67,6 +67,10 @@
&::placeholder {
color: var(--input-placeholder-color);
}
&[type=color] {
height: 45px;
}
}
&__description {

@ -6,6 +6,8 @@
flex: 0 0 auto;
margin: 0.5rem 0;
color: var(--input-text-color);
border-width: var(--input-border-width);
@ -17,6 +19,10 @@
align-items: center;
justify-content: flex-end;
&__option {
text-align: right;
}
&__arrow {
position: absolute;
z-index: -1;
@ -37,6 +43,8 @@
appearance: none;
width: 100%;
&::-ms-expand {
display: none;
}

@ -1,6 +1,5 @@
.rc-apps {
&-settings {
padding: 25px;
flex-direction: column;
&__item {
@ -10,6 +9,7 @@
}
&-container {
padding: 25px 0;
max-width: 705px;
margin: auto;
width: 100%;
@ -73,6 +73,8 @@
@media (width <= 500px) {
.rc-apps {
&-container {
padding: 25px;
flex-direction: column;
align-items: center;
}

@ -103,4 +103,6 @@
<symbol id="icon-circle-cross" viewBox="0 0 256 256"><path d="M183.191,174.141c2.5,2.498,2.5,6.552,0,9.05c-1.249,1.25-2.889,1.875-4.525,1.875c-1.638,0-3.277-0.625-4.525-1.875 l-46.142-46.142L81.856,183.19c-1.249,1.25-2.888,1.875-4.525,1.875c-1.638,0-3.277-0.625-4.525-1.875c-2.5-2.498-2.5-6.552,0-9.05 l46.143-46.143L72.806,81.856c-2.5-2.499-2.5-6.552,0-9.05c2.497-2.5,6.553-2.5,9.05,0l46.142,46.142l46.142-46.142 c2.497-2.5,6.553-2.5,9.051,0c2.5,2.499,2.5,6.552,0,9.05l-46.143,46.142L183.191,174.141z M256,128C256,57.42,198.58,0,128,0 C57.42,0,0,57.42,0,128c0,70.58,57.42,128,128,128C198.58,256,256,198.58,256,128z M243.2,128c0,63.521-51.679,115.2-115.2,115.2 c-63.522,0-115.2-51.679-115.2-115.2C12.8,64.478,64.478,12.8,128,12.8C191.521,12.8,243.2,64.478,243.2,128z" fill="#ef0e0e"/></symbol>
<symbol id="icon-circle-check" viewBox="0 0 32 32"><g><path d="M16,0C7.163,0,0,7.163,0,16c0,8.837,7.163,16,16,16c8.836,0,16-7.164,16-16C32,7.163,24.836,0,16,0z M16,30 C8.268,30,2,23.732,2,16C2,8.268,8.268,2,16,2s14,6.268,14,14C30,23.732,23.732,30,16,30z" fill="#2db730"/><path d="M23.3,10.393L13.012,20.589l-4.281-4.196c-0.394-0.391-1.034-0.391-1.428,0 c-0.395,0.391-0.395,1.024,0,1.414l4.999,4.899c0.41,0.361,1.023,0.401,1.428,0l10.999-10.899c0.394-0.39,0.394-1.024,0-1.414 C24.334,10.003,23.695,10.003,23.3,10.393z" fill="#2db730"/></g><g/><g/><g/><g/><g/><g/></symbol>
<symbol id="icon-loading" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-rolling"><circle cx="50" cy="50" fill="none" stroke="currentColor" stroke-width="5" r="26" stroke-dasharray="122.52211349000194 42.840704496667314" transform="rotate(150 50 50)"><animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 50;360 50 50" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform></circle></symbol>
<symbol id="icon-sort-down" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M287.968 288H32.038c-28.425 0-42.767 34.488-22.627 54.627l127.962 128c12.496 12.496 32.758 12.497 45.255 0l127.968-128C330.695 322.528 316.45 288 287.968 288zM160 448L32 320h256L160 448z"/></symbol>
<symbol id="icon-sort-up" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M32.032 224h255.93c28.425 0 42.767-34.488 22.627-54.627l-127.962-128c-12.496-12.496-32.758-12.497-45.255 0l-127.968 128C-10.695 189.472 3.55 224 32.032 224zM160 64l128 128H32L160 64z"/></symbol>
</svg>

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 60 KiB

@ -22,9 +22,9 @@
<table class="rc-table">
<thead class="rc-table-head">
<tr class="rc-table-tr">
<td class="rc-table-td js-sort" data-sort="name">Name {{> icon icon="sort" }}</td>
<td class="rc-table-td js-sort" data-sort="usernames">Users {{> icon icon="sort" }}</td>
<td class="rc-table-td js-sort" data-sort="createdAt">Created At {{> icon icon="sort" }}</td>
<td class="rc-table-td js-sort" data-sort="name">Name {{> icon icon=(sortIcon 'name')}}</td>
<td class="rc-table-td js-sort" data-sort="usernames">Users {{> icon icon=(sortIcon 'usernames') }}</td>
<td class="rc-table-td js-sort" data-sort="createdAt">Created At {{> icon icon=(sortIcon 'createdAt') }}</td>
</tr>
</thead>
<tbody class="rc-table-body">

@ -41,6 +41,14 @@ Template.directory.helpers({
},
searchType() {
return Template.instance().searchType.get();
},
sortIcon(key) {
const {
sortDirection,
searchSortBy
} = Template.instance();
return key === searchSortBy.get() && sortDirection.get() !== 'asc' ? 'sort-up' : 'sort-down';
}
});

Loading…
Cancel
Save