diff --git a/src/app.html b/src/app.html index bb6ec87..05d3ce0 100644 --- a/src/app.html +++ b/src/app.html @@ -492,7 +492,7 @@ - + diff --git a/src/core/components/code-editor/CodeEditor.css b/src/core/components/code-editor/CodeEditor.css index aebd781..d9352d3 100644 --- a/src/core/components/code-editor/CodeEditor.css +++ b/src/core/components/code-editor/CodeEditor.css @@ -1,3 +1,7 @@ .CodeEditor__editor { width: 100%; -} \ No newline at end of file +} + +.CodeEditor__editor_disabled { + background-color: #e9ecefa6; +} diff --git a/src/core/components/code-editor/CodeEditor.js b/src/core/components/code-editor/CodeEditor.js index 957313b..7efe49c 100644 --- a/src/core/components/code-editor/CodeEditor.js +++ b/src/core/components/code-editor/CodeEditor.js @@ -30,7 +30,7 @@ export class CodeEditor extends Component { } setValue = (value) => { - this.editor.setValue(value); + this.editor.session.setValue(value); } getValue = () => { @@ -38,6 +38,8 @@ export class CodeEditor extends Component { } disabled = (value) => { + const method = value ? 'add' : 'remove'; + this.editorContainer.classList[method]('CodeEditor__editor_disabled'); this.editor.setReadOnly(value); } } diff --git a/src/core/components/modal-sidebar/ModalSibebar.js b/src/core/components/modal-sidebar/ModalSibebar.js index bef33f6..b715720 100644 --- a/src/core/components/modal-sidebar/ModalSibebar.js +++ b/src/core/components/modal-sidebar/ModalSibebar.js @@ -9,7 +9,7 @@ const HIDE_SHADOW_CLASS = 'ModalSidebar__shadow_hide'; const SHADOW_CLASS = 'ModalSidebar__shadow'; const CROSS_BUTTON_CLASS = 'ModalSidebar__close'; const WINDOW_CLASS = 'ModalSidebar__window'; - +const WINDOW_INIT_CLASS = 'invisible'; class ModalSidebar extends Component { constructor ({ content, @@ -56,6 +56,7 @@ class ModalSidebar extends Component { } show = () => { + this.mainNode.classList.remove(WINDOW_INIT_CLASS); this.mainNode.classList.add(SHOW_WINDOW_CLASS); this.shadow.classList.add(SHOW_SHADOW_CLASS); diff --git a/src/pages/storages/components/api-table-view-form/ApiTableViewForm.js b/src/pages/storages/components/api-table-view-form/ApiTableViewForm.js index a24a499..c70a4ce 100644 --- a/src/pages/storages/components/api-table-view-form/ApiTableViewForm.js +++ b/src/pages/storages/components/api-table-view-form/ApiTableViewForm.js @@ -1,12 +1,14 @@ import Component from '../../../../core/components/component/Component'; import ModalSidebar from '../../../../core/components/modal-sidebar/ModalSibebar'; import FormControl from '../../../../core/components/form-control/FormControl'; -import {EVENTS, MODES, CODE_EDITOR_MODE} from '../../../../core/consts'; +import {EVENTS, MODES, CODE_EDITOR_MODE, FORM_TYPES} from '../../../../core/consts'; import './ApiTableViewForm.css'; import storageApi from '../../api/StorageServiceAPI'; import routeService from '../../../../services/RouteService'; import {HooksComponent} from '../hooks-component/HooksComponent'; import {FormCodeEditor} from '../../../../core/components/form-code-editor/FormCodeEditor'; +import userInfoService from '../../../../services/UserInfoService'; +import usersServiceApi from '../../../users/api/UsersServiceAPI'; const TITLE_MODES = { [MODES.Create]: 'Создание нового хранилища', @@ -31,37 +33,6 @@ class ApiTableViewForm extends Component { this.title.textContent = 'Информация о хранилище'; - this.inputs = [ - this.keyInput = this.createComponent(FormControl, this.form, { - id: 'api-key-input', - label: 'Название хранилища', - pattern: '^[a-zA-Z][a-zA-Z0-9_-]{3,}$', - required: true, - }), - this.serviceNameInput = this.createComponent(FormControl, this.form, { - id: 'api-service-name-input', - label: 'Название сервиса', - required: true, - }), - this.authorInput = this.createComponent(FormControl, this.form, { - id: 'api-author-input', - label: 'Автор хранилища', - required: true, - }), - this.descriptionInput = this.createComponent(FormControl, this.form, { - id: 'api-description-input', - label: 'Краткое описание', - required: true, - }), - this.valueInput = this.createComponent(FormCodeEditor, this.form, { - id: 'api-value-input', - className: 'Api__value-input', - label: 'Содержимое хранилища', - mode: CODE_EDITOR_MODE.JSON, - required: true, - }), - ]; - this.buttons = [ { button: this.createButton = this.mainNode.querySelector('.ApiViewForm__create'), @@ -70,10 +41,12 @@ class ApiTableViewForm extends Component { { button: this.saveButton = this.mainNode.querySelector('.ApiViewForm__save'), modes: [MODES.Edit], + onlyOwner: true, }, { button: this.editButton = this.mainNode.querySelector('.ApiViewForm__edit'), modes: [MODES.View], + onlyOwner: true, }, { button: this.cancelButton = this.mainNode.querySelector('.ApiViewForm__cancel'), @@ -82,6 +55,7 @@ class ApiTableViewForm extends Component { { button: this.deleteButton = this.mainNode.querySelector('.ApiViewForm__delete'), modes: [MODES.View, MODES.Edit], + onlyOwner: true, } ]; @@ -97,31 +71,74 @@ class ApiTableViewForm extends Component { this.addEventListener(this.cancelButton, EVENTS.CLICK, this.handleCloseModal); + this.hooksContainer = this.createComponent(HooksComponent, this.mainNode); + this.form.insertAdjacentElement('afterend', this.hooksContainer.mainNode); + + this.addSubscribe(routeService, EVENTS.ROUTE_SEARCH_CHANGE, this.setForm); + + this.renderInputs(); + } + + renderInputs = async () => { + const users = await usersServiceApi.request(); + this.inputs = [ + this.keyInput = this.createComponent(FormControl, this.form, { + id: 'api-key-input', + label: 'Название хранилища', + pattern: '^[a-zA-Z][a-zA-Z0-9_-]{3,}$', + required: true, + }), + this.serviceNameInput = this.createComponent(FormControl, this.form, { + id: 'api-service-name-input', + label: 'Название сервиса', + required: true, + }), + this.authorInput = this.createComponent(FormControl, this.form, { + id: 'api-author-input', + label: 'Автор хранилища', + type: FORM_TYPES.SELECT, + options: users.map((user) => ({ + value: user.login, + text: user.login, + })), + }), + this.descriptionInput = this.createComponent(FormControl, this.form, { + id: 'api-description-input', + label: 'Краткое описание', + required: true, + }), + this.valueInput = this.createComponent(FormCodeEditor, this.form, { + id: 'api-value-input', + className: 'Api__value-input', + label: 'Содержимое хранилища', + mode: CODE_EDITOR_MODE.JSON, + required: true, + }), + this.hideSelect = this.createComponent(FormControl, this.form, { + id: 'api-hide-select', + label: 'Видимость хранилища', + type: FORM_TYPES.SELECT, + options: [ + {value: true, text: 'Скрыть'}, + {value: false, text: 'Показать'}, + ], + }), + ]; + this.inputs.forEach((input) => { input.disabled(true); }); - this.hooksContainer = this.createComponent(HooksComponent, this.mainNode); - this.form.insertAdjacentElement('afterend', this.hooksContainer.mainNode); - - this.addSubscribe(routeService, EVENTS.ROUTE_SEARCH_CHANGE, ({query}) => { - const {mode, key} = query; - this.setForm(mode, key); - this.setVisibleHooks(mode); - }); - - const {query: {mode, key}} = routeService.getUrlData(); - if (mode) { - this.setForm(mode, key); - } + this.setForm(); } handleCloseModal = () => { routeService.pushQuery({}, true); } - setVisibleHooks = (mode) => { - const method = mode !== MODES.View ? 'add' : 'remove'; + setVisibleHooks = (mode, isAvailable) => { + const isHide = mode !== MODES.View || !isAvailable; + const method = isHide ? 'add' : 'remove'; this.hooksContainer.mainNode.classList[method]('invisible'); } @@ -146,17 +163,26 @@ class ApiTableViewForm extends Component { }; } - setInputDisabled = (mode) => { + setInputDisabled = (mode, isAdmin) => { const disabled = !EDIT_MODES.includes(mode); this.inputs.forEach((input) => { - const disabledLogin = this.keyInput === input && mode === MODES.Edit; - input.disabled(disabled ? disabled : disabledLogin); + if (input === this.keyInput) { + const disabledKey = mode !== MODES.Create; + input.disabled(disabled ? disabled : disabledKey); + return; + } + if (input === this.authorInput) { + const disabledAuthor = mode !== MODES.Create || !isAdmin; + input.disabled(disabled ? disabled : disabledAuthor); + return; + } + input.disabled(disabled); }); } - showButtons = (mode) => { - this.buttons.forEach(({button, modes}) => { - const isShow = modes.includes(mode); + showButtons = (mode, isAvailable) => { + this.buttons.forEach(({button, modes, onlyOwner}) => { + const isShow = modes.includes(mode) && (onlyOwner ? isAvailable : true); button.style.display = isShow ? 'inline-block' : 'none'; }); } @@ -202,6 +228,7 @@ class ApiTableViewForm extends Component { service_name: this.serviceNameInput.getValue(), author: this.authorInput.getValue(), description: this.descriptionInput.getValue(), + hide: this.hideSelect.getValue(), }); this.clearForm(); @@ -217,6 +244,7 @@ class ApiTableViewForm extends Component { service_name: this.serviceNameInput.getValue(), author: this.authorInput.getValue(), description: this.descriptionInput.getValue(), + hide: this.hideSelect.getValue(), }); this.clearForm(); routeService.pushQuery({}, true); @@ -235,17 +263,22 @@ class ApiTableViewForm extends Component { this.keyInput.setValue(key); } - setForm = async (mode, storeKey) => { - const {key, value, description, service_name, author} = await this.loadStore(storeKey); + setForm = async () => { + const {query: {mode, key: storeKey}} = routeService.getUrlData(); + const {key, value, description, service_name, author, hide} = await this.loadStore(storeKey); + const {login, is_admin} = await userInfoService.getUserInfo(); + const isAvailableEdit = author === login || is_admin; this.setSidebarTitle(mode, storeKey); this.setKeyInput(mode, key); this.serviceNameInput.setValue(service_name); - this.authorInput.setValue(author); + this.authorInput.setValue(author || login); this.descriptionInput.setValue(description); this.valueInput.setValue(this.stringifyValue(value)); + this.hideSelect.setValue(hide); - this.setInputDisabled(mode); - this.showButtons(mode); + this.setInputDisabled(mode, is_admin); + this.showButtons(mode, isAvailableEdit); + this.setVisibleHooks(mode, isAvailableEdit); if (mode) { this.sidebar.show(); diff --git a/src/services/UserInfoService.js b/src/services/UserInfoService.js index 945aad3..e4e0d78 100644 --- a/src/services/UserInfoService.js +++ b/src/services/UserInfoService.js @@ -11,6 +11,7 @@ class UserInfoService extends EmitService { this.userInfo = { login: NOT_USER, avatar: DEFAULT_AVATAR, + is_admin: false, }; }