Merge branch 'PR-41'

Добавлен SASS (django-sass-processor)
Добавлен сборщик js  webpack(node.js)
remotes/origin/PR-9
booblegum 9 years ago
commit 0b8c803dad
  1. 6
      api/urls.py
  2. 25
      api/views.py
  3. 43
      archilance/settings/base.py
  4. 1
      archilance/views.py
  5. 2
      assets/css/extra.css
  6. 86
      assets/css/main.css
  7. 12
      assets/css/reset.css
  8. BIN
      assets/img/days.png
  9. BIN
      assets/img/rub.png
  10. 283
      assets/js/build/create_project.js
  11. 1941
      assets/js/build/init_customer_project_create.js
  12. 223
      assets/js/build/user.js
  13. 27
      assets/js/src/customer_project_create.js
  14. 140
      assets/js/src/init_customer_project_create.js
  15. 0
      assets/js/src/seeds/components_script.js
  16. 19
      assets/js/src/seeds/custom_check.js
  17. 20
      assets/js/src/seeds/extended_field.js
  18. 57
      assets/js/src/seeds/file_upload.js
  19. 21
      assets/js/src/seeds/only_one_checkbox.js
  20. 16
      assets/js/src/seeds/read_more.js
  21. 5
      assets/js/src/seeds/test_seeds.js
  22. 56
      assets/js/src/user.js
  23. 7
      assets/lib/proekton-components/bash/browserify.sh
  24. 1402
      assets/lib/proekton-components/js/build/init_customer_project_create.js
  25. 11
      assets/lib/proekton-components/js/src/NoTreeSelect.js
  26. 137
      assets/lib/proekton-components/js/src/SelectOrCreate.js
  27. 25
      assets/lib/proekton-components/js/src/SelectedContainer.js
  28. 28
      assets/lib/proekton-components/js/src/SelectedContainerCreate.js
  29. 4
      assets/lib/proekton-components/js/src/SingleTreeSelect.js
  30. 5
      assets/lib/proekton-components/js/src/TreeSelect.js
  31. 50
      assets/lib/proekton-components/js/src/base/AbsBaseSelect.js
  32. 5
      assets/lib/proekton-components/js/src/decorators.js
  33. 0
      assets/lib/proekton-components/js/src/examples/init.js
  34. 0
      assets/lib/proekton-components/js/src/examples/init_example.js
  35. 0
      assets/lib/proekton-components/js/src/examples/init_user_profile.js
  36. 4
      assets/lib/proekton-components/sass/components.sass
  37. 11
      assets/lib/proekton-components/sass/parts/_editable-container.sass
  38. 18
      assets/lib/proekton-components/sass/parts/_fonts.sass
  39. 166
      assets/lib/proekton-components/sass/parts/_select-box.sass
  40. 44
      assets/lib/proekton-components/sass/parts/_selected-container.sass
  41. 6
      assets/sass/base/_colors.sass
  42. 29
      assets/sass/base/_fonts.sass
  43. 1
      assets/sass/base/_variavles.sass
  44. 22
      assets/sass/common/_parts.sass
  45. 233
      assets/sass/components/custom-components.sass
  46. 72
      assets/sass/main.sass
  47. 6
      assets/sass/modules/_mods.sass
  48. 10
      assets/sass/utils/_functions.sass
  49. 7
      package.json
  50. 79
      projects/forms.py
  51. 47
      projects/migrations/0048_auto_20161201_2003.py
  52. 25
      projects/migrations/0049_auto_20161201_2157.py
  53. 31
      projects/models.py
  54. 62
      projects/static/css/customer_project_create.css
  55. 11
      projects/static/css/project_filter.css
  56. 74
      projects/static/img/circle_cross.svg
  57. BIN
      projects/static/img/paper-clip_icon._g.png
  58. BIN
      projects/static/img/paper-clip_icon.png
  59. 14
      projects/static/js/textarea_additional.js
  60. 411
      projects/templates/_trash/customer_project_create.html
  61. 769
      projects/templates/customer_project_create.html
  62. 10
      projects/templates/project_filter.html
  63. 3
      projects/urls.py
  64. 95
      projects/views.py
  65. 84
      requirements/new.txt
  66. 24
      templates/home_modular.html
  67. 255
      templates/partials/base.html
  68. 4
      templates/partials/footer.html
  69. 5
      templates/partials/header.html
  70. 91
      templates/partials/sass/footer.sass
  71. 334
      templates/partials/sass/header.sass
  72. 10
      users/templates/user_profile_edit.html
  73. 9
      wallets/admin.py
  74. 63
      webpack.config.js
  75. 20
      work_sell/migrations/0019_auto_20161201_2003.py

@ -53,3 +53,9 @@ router.register(r'work-sell-photos', WorkSellPhotoViewSet)
router.register(r'work-sells', WorkSellViewSet) router.register(r'work-sells', WorkSellViewSet)
urlpatterns = router.urls urlpatterns = router.urls
# urlpatterns = [
# url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
# ]
#
# urlpatterns += router.url

@ -3,6 +3,8 @@ from django.db.models import Q, F
from rest_framework import permissions from rest_framework import permissions
from rest_framework.pagination import PageNumberPagination from rest_framework.pagination import PageNumberPagination
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from chat.filters import MessageFilterSet, NoteFilterSet, DocumentFilterSet from chat.filters import MessageFilterSet, NoteFilterSet, DocumentFilterSet
from chat.models import Message, Notes, Documents, NewMessage from chat.models import Message, Notes, Documents, NewMessage
@ -148,9 +150,28 @@ class MessageViewSet(ModelViewSet):
class RealtyViewSet(ModelViewSet): class RealtyViewSet(ModelViewSet):
queryset = Realty.objects.all() queryset = Realty.objects.filter(is_virtual=False)
serializer_class = RealtySerializer serializer_class = RealtySerializer
filter_class = RealtyFilterSet # filter_class = RealtyFilterSet
# TODO: довести до ума
def get_queryset(self):
# TODO: сделать универсальный фильтр
queryset = self.queryset
user_param = self.request.query_params.get('user', None)
if user_param:
queryset = queryset.filter(user=self.request.user)
id_param = self.request.query_params.get('id', None)
if id_param:
queryset = queryset.filter(id=id_param)
return queryset
@list_route(methods=['get'])
def current_user(self, request, *args, **kwargs):
queryset = self.queryset.filter(user=self.request.user)
serialiser = self.serializer_class(queryset, many=True)
return Response(serialiser.data)
class BuildingClassificationViewSet(ModelViewSet): class BuildingClassificationViewSet(ModelViewSet):

@ -43,6 +43,7 @@ THIRD_PARTY_APPS = [
'django_activeurl', 'django_activeurl',
'import_export', 'import_export',
'captcha', 'captcha',
'sass_processor'
] ]
LOCAL_APPS = [ LOCAL_APPS = [
@ -128,6 +129,7 @@ TEMPLATES = [
'mathfilters.templatetags.mathfilters', 'mathfilters.templatetags.mathfilters',
], ],
'debug': DEBUG,
# 'loaders': [ # 'loaders': [
# ('django.template.loaders.cached.Loader', [ # ('django.template.loaders.cached.Loader', [
# 'django.template.loaders.filesystem.Loader', # 'django.template.loaders.filesystem.Loader',
@ -265,9 +267,46 @@ MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(ROOT_DIR, 'static') STATIC_ROOT = os.path.join(ROOT_DIR, 'static')
MEDIA_ROOT = os.path.join(ROOT_DIR, 'media') MEDIA_ROOT = os.path.join(ROOT_DIR, 'media')
STATICFILES_DIRS = ( STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'sass_processor.finders.CssFinder',
]
STATICFILES_DIRS = [
os.path.join(ROOT_DIR, 'templates'),
os.path.join(ROOT_DIR, 'assets'), os.path.join(ROOT_DIR, 'assets'),
) os.path.join(ROOT_DIR, 'assets/lib/proekton-components'),
]
SASS_PROCESSOR_INCLUDE_DIRS = [
os.path.join(ROOT_DIR, 'assets/sass'),
]
# print("SASS = ", SASS_PROCESSOR_INCLUDE_DIRS)
# SASS_PROCESSOR_AUTO_INCLUDE = False
# SASS_PROCESSOR_INCLUDE_FILE_PATTERN = r'^.+\.sass$'
SASS_PROCESSOR_ENABLED = DEBUG
# SASS_PRECISION = 8
# SASS_OUTPUT_STYLE = 'compact'
# SASS_PROCESSOR_ROOT = os.path.join(ROOT_DIR, 'assets')
# SASS_PROCESSOR_INCLUDE_DIRS = [
# os.path.join(ROOT_DIR, 'assets'),
# os.path.join(ROOT_DIR, 'assets/sass/modules'),
# os.path.join(ROOT_DIR, 'templates'),
# ]
# SASS_PROCESSOR_AUTO_INCLUDE = False
# print(SASS_PROCESSOR_INCLUDE_DIRS)
# STATICFILES_FINDERS = (
# 'django.contrib.staticfiles.finders.FileSystemFinder',
# 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'sass_processor.finders.CssFinder',
# # 'compressor.finders.CompressorFinder',
# )
AUTH_USER_MODEL = 'users.User' AUTH_USER_MODEL = 'users.User'
ACCOUNT_ACTIVATION_DAYS = 7 ACCOUNT_ACTIVATION_DAYS = 7

@ -13,6 +13,7 @@ from users.models import User
from work_sell.models import Picture from work_sell.models import Picture
class HomeTemplateView(BaseMixin, View): class HomeTemplateView(BaseMixin, View):
template_name = 'home.html' template_name = 'home.html'

@ -247,7 +247,7 @@ li a:active .count-tab, li a:hover .count-tab {
.mainContainer { .mainContainer {
background-repeat: repeat; background-repeat: repeat;
height: 100%; /*height: 100%;*/
} }
.nameExecutor a:link, .nameExecutor:visited, .nameExecutor a { .nameExecutor a:link, .nameExecutor:visited, .nameExecutor a {

@ -1331,7 +1331,7 @@ footer:after {
.titleResF1, div p.titleResF1 { .titleResF1, div p.titleResF1 {
font-size: 14pt; font-size: 14pt;
font-family: 'Arial-MT-Regular', sans-serif; font-family: 'Arial-MT-Regular', sans-serif;
/*font-weight: bold;*/ font-weight: bold;
color: #000000; color: #000000;
float: left; float: left;
} }
@ -1376,35 +1376,35 @@ footer:after {
margin: 33px 0 28px 0; margin: 33px 0 28px 0;
} }
/*label {*/ label {
/*width: 23px;*/ width: 23px;
/*height: 23px;*/ height: 23px;
/*display: block;*/ display: block;
/*position: relative;*/ position: relative;
/*float: left;*/ float: left;
/*margin-right: 10px;*/ margin-right: 10px;
/*}*/ }
/*input[type="checkbox"] + span {*/
/*position: absolute;*/
/*left: 0;*/
/*top: 0;*/
/*width: 100%;*/
/*height: 100%;*/
/*background: url('../img/check.png') no-repeat center;*/
/*background-position: 0 0;*/
/*background-size: cover;*/
/*cursor: pointer;*/
/*}*/
.sro input[type="checkbox"] { input[type="checkbox"] + span {
opacity: 0; position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url('../img/check.png') no-repeat center;
background-position: 0 0;
background-size: cover;
cursor: pointer;
} }
/*input[type="checkbox"]:checked + span {*/ /*.sro input[type="checkbox"] {*/
/*background-position: 0 -23px;*/ /*opacity: 0;*/
/*}*/ /*}*/
input[type="checkbox"]:checked + span {
background-position: 0 -23px;
}
.sro p { .sro p {
font-size: 15px; font-size: 15px;
font-family: 'Arial-MT-Regular', sans-serif; font-family: 'Arial-MT-Regular', sans-serif;
@ -4514,26 +4514,26 @@ footer:after {
color: #009DD9; color: #009DD9;
} }
/*label {*/ label {
/*width: 23px;*/ width: 23px;
/*height: 23px;*/ height: 23px;
/*display: block;*/ display: block;
/*position: relative;*/ position: relative;
/*}*/ }
/*input[type="checkbox"] + span {*/ input[type="checkbox"] + span {
/*position: absolute;*/ position: absolute;
/*left: 0;*/ left: 0;
/*top: 0;*/ top: 0;
/*width: 100%;*/ width: 100%;
/*height: 100%;*/ height: 100%;
/*background: url('../img/check.png') no-repeat;*/ background: url('../img/check.png') no-repeat;
/*cursor: pointer;*/ cursor: pointer;
/*}*/ }
/*input[type="checkbox"]:checked + span {*/ input[type="checkbox"]:checked + span {
/*background-position: 0 -23px;*/ background-position: 0 -23px;
/*}*/ }
.text-block { .text-block {
width: 100%; width: 100%;

@ -17,17 +17,17 @@ body, code, dl, dd, form, pre {
margin: 0; margin: 0;
} }
/*a:link {*/ a:link {
/*color: #009;*/ color: #009;
/*}*/ }
a:link, a:visited, ins { a:link, a:visited, ins {
text-decoration: none; text-decoration: none;
} }
/*a:visited {*/ a:visited {
/*color: #505;*/ color: #505;
/*}*/ }
a:link img, a:visited img, object, fieldset, abbr, acronym { a:link img, a:visited img, object, fieldset, abbr, acronym {
border: none; border: none;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,283 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _file_upload = __webpack_require__(1);
var _file_upload2 = _interopRequireDefault(_file_upload);
var _extended_field = __webpack_require__(2);
var _custom_check = __webpack_require__(3);
var _read_more = __webpack_require__(4);
var _only_one_checkbox = __webpack_require__(5);
var _test_seeds = __webpack_require__(6);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function showHideRealry() {
var check = $('#checkbox-sb-realty');
check.on("click", function (e) {
var $realty = $('#sb-realty');
if ($(e.target).prop("checked")) {
$realty.show();
} else {
$realty.hide();
}
});
}
$(function () {
(0, _file_upload2.default)();
(0, _extended_field.extendedFieldInit)();
(0, _custom_check.customCheckInit)();
showHideRealry();
(0, _read_more.readMoreInit)();
(0, _only_one_checkbox.onlyOneCheckboxInit)('#safe', '#by_agreement');
});
/***/ },
/* 1 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = fileUploadInit;
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) return bytes + ' B';
var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
function fileUploadInit() {
var $fileUploadContainer = $('#fileUploadContainer');
$('#fileUploadAddBtn').on('click', function ($evt) {
$fileUploadContainer.find('.file-upload-widget').last().find('.file-upload-input').click();
});
$fileUploadContainer.on('change', '.file-upload-input', function ($evt) {
var $fileInput = $(this);
var $fileUploadWidget = $fileInput.closest('.file-upload-widget');
var filePath = $fileInput.val().replace(/\\/g, '/');
var fileName = path.basename(filePath);
//var fileExt = path.extname(filePath)
var fileSize = $fileInput.get(0).files && humanFileSize($fileInput.get(0).files[0].size);
if (fileName) {
$fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize);
var $newFileUploadWidget = $fileUploadWidget.clone();
$newFileUploadWidget.find('.file-upload-label').text('');
$fileUploadContainer.find('ul').first().append($newFileUploadWidget);
$fileUploadWidget.css('display', 'block');
}
});
$fileUploadContainer.on('click', '.file-upload-remove-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.file-upload-widget').remove();
});
$fileUploadContainer.on('click', '.existing-file-remove-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.existing-file-widget').remove();
});
}
/***/ },
/* 2 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function extendedFieldInit() {
var $buttonF1 = $('.resButton');
if ($('.slide').hasClass("active")) $buttonF1.css('transform', 'rotate(0deg)');
$buttonF1.on("click", function (e) {
e.preventDefault();
var $slide = $('.slide');
if ($slide.hasClass("active")) {
$buttonF1.css('transform', 'rotate(180deg)');
$slide.slideUp(300);
} else {
$buttonF1.css('transform', 'rotate(0deg)');
$slide.slideDown(300);
}
$slide.toggleClass("active");
});
}
exports.extendedFieldInit = extendedFieldInit;
/***/ },
/* 3 */
/***/ function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function customCheckInit() {
function tuneCheckBoxes($boxes) {
var currentState = $boxes.find("input").prop("checked") ? 'checked' : 'not-checked';
$boxes.find("div").hide();
$boxes.find("div." + currentState).show();
}
var $boxes = $('.custom-check');
tuneCheckBoxes($boxes);
$boxes.on("click", function (e) {
var inside_checkBox = $(e.target).parent().find("input");
inside_checkBox.prop("checked", !inside_checkBox.prop("checked"));
tuneCheckBoxes($boxes);
e.preventDefault();
return false;
});
}
exports.customCheckInit = customCheckInit;
/***/ },
/* 4 */
/***/ function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function readMoreInit() {
$('.description .more').on("click", function (e) {
var $target = $(e.target);
$target.siblings(".complete").toggle();
$target.toggleClass("less");
});
// $(".more").toggle(function () {
// $(this).text("less..").siblings(".complete").show();
// }, function () {
// $(this).text("more..").siblings(".complete").hide();
// });
}
exports.readMoreInit = readMoreInit;
/***/ },
/* 5 */
/***/ function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function onlyOneCheckboxInit(selector_first, selector_second) {
//TODO: need refactoring...
var $first = $(selector_first);
var $second = $(selector_second);
$first.change(function () {
if ($first.prop("checked")) {
$second.prop("checked", false);
} else {
$second.attr("checked", true);
}
});
$second.change(function () {
if ($second.prop("checked")) {
$first.attr("checked", false);
} else {
$first.attr("checked", true);
}
});
}
exports.onlyOneCheckboxInit = onlyOneCheckboxInit;
/***/ },
/* 6 */
/***/ function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function print(text) {
console.log(text);
}
exports.print = print;
/***/ }
/******/ ]);

File diff suppressed because it is too large Load Diff

@ -0,0 +1,223 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _typeof2 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
var _desc, _value, _class;
var _typeof = typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol" ? function (obj) {
return typeof obj === "undefined" ? "undefined" : _typeof2(obj);
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj === "undefined" ? "undefined" : _typeof2(obj);
};
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
function onBind(target, name, descriptor) {
var method = descriptor.value;
descriptor.value = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var binds = [];
args = Array.from(args);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = args.slice()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var arg = _step.value;
if ((typeof arg === 'undefined' ? 'undefined' : _typeof(arg)) === 'object') {
binds.push(arg);
args.splice(args.indexOf(arg), 1);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
method.apply(this, args);
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = binds[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var bind = _step2.value;
bind.func.bind(this)();
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return this;
};
}
var Base = (_class = function () {
function Base() {
_classCallCheck(this, Base);
this.attr1 = 'attr1';
console.log("Constructor");
}
_createClass(Base, [{
key: 'method1',
value: function method1() {
var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
console.log("this.attr1 = ", this.attr1);
console.log("a = ", a, "b = ", b);
}
}, {
key: 'on',
value: function on(methodName, func) {
this[methodName] = this[methodName].bind(this, { func: func });
}
}]);
return Base;
}(), _applyDecoratedDescriptor(_class.prototype, 'method1', [onBind], Object.getOwnPropertyDescriptor(_class.prototype, 'method1'), _class.prototype), _class);
var b = new Base();
b.on("method1", function () {
return console.log("Another message...");
});
b.on("method1", function () {
console.log("bind this.attr1 =", this.attr1);
});
b.method1("one", 2);
b.method1("bbb");
if (true) {
console.log("Dev mode message");
}
function a(_ref) {
var _ref$a = _ref.a,
a = _ref$a === undefined ? 2 : _ref$a,
_ref$b = _ref.b,
b = _ref$b === undefined ? a + 4 : _ref$b;
}
/***/ }
/******/ ]);

@ -0,0 +1,27 @@
import fileUploadInit from './seeds/file_upload'
import {extendedFieldInit} from './seeds/extended_field'
import {customCheckInit} from './seeds/custom_check'
import {readMoreInit} from './seeds/read_more'
import {onlyOneCheckboxInit} from './seeds/only_one_checkbox'
import {print} from './seeds/test_seeds'
function showHideRealry() {
let check = $('#checkbox-sb-realty');
check.on("click", function (e) {
let $realty = $('#sb-realty');
if ($(e.target).prop("checked")) {
$realty.show();
} else {
$realty.hide();
}
})
}
$(function () {
fileUploadInit();
extendedFieldInit();
customCheckInit();
showHideRealry();
readMoreInit();
onlyOneCheckboxInit('#safe', '#by_agreement');
});

@ -0,0 +1,140 @@
import SelectedContainer from 'components/SelectedContainer';
import SelectedContainerCreate from 'components/SelectedContainerCreate';
import NoTreeSelect from 'components/NoTreeSelect';
import TreeSelect from 'components/TreeSelect';
import SingleTreeSelect from 'components/SingleTreeSelect'
import SelectOrCreate from 'components/SelectOrCreate'
$(function () {
function createSpecs(url) {
// SPECIALIZATIONS
let sb_main = new TreeSelect($('#select-box-1'), {url, visible: true, required: true});
sb_main.setHeader("Специальность");
let select_container = new SelectedContainer($('#selected-spec'),
{
obj: sb_main,
onlyOne: true
});
sb_main.connectSelectedContainer(select_container);
let sb_1 = new TreeSelect($('#select-box-2'), {obj: sb_main});
let sb_2 = new TreeSelect($('#select-box-3'), {obj: sb_main});
let sb_3 = new TreeSelect($('#select-box-4'), {obj: sb_main});
let sb_4 = new TreeSelect($('#select-box-5'), {obj: sb_main});
select_container.on("add", () => {
let $container = $('#spec-value');
$container.html($('#selected-spec').find(".selected-element").find(".name").html());
});
sb_main.setNearbySelectBox(sb_1);
sb_1.setNearbySelectBox(sb_2, sb_main);
sb_2.setNearbySelectBox(sb_3, sb_1);
sb_3.setNearbySelectBox(sb_4, sb_2);
sb_4.setNearbySelectBox("", sb_3);
}
function createBuildingClass(url) {
// BUILDING-CLASSIFICATION
sb_build_main = new TreeSelect($('#sb-building-classification'), {url, visible: true});
sb_build_main.setHeader("Классификация здания");
let sb_build_1 = new TreeSelect($('#sb-building-sub-classification'), {obj: sb_build_main});
let select_build_container = new SelectedContainer($('#selected-building-classification'),
{
obj: sb_build_main,
onlyOne: true
});
sb_build_main.connectSelectedContainer(select_build_container);
sb_build_main.setNearbySelectBox(sb_build_1);
sb_build_1.setNearbySelectBox("", sb_build_main);
}
function createConstructionType(url) {
sb_constr_main = new NoTreeSelect($('#sb-construction-type'), {url, visible: true});
sb_constr_main.setHeader("Вид строительства");
let select_constr_type = new SelectedContainer($('#selected-construction-type'), {
obj: sb_constr_main,
noTree: true,
onlyOne: true
});
sb_constr_main.connectSelectedContainer(select_constr_type);
}
function createLocations(url) {
sb_loc_main = new TreeSelect($('#sb-location-1'), {url, visible: true});
sb_loc_main.setHeader("Местоположение");
let select_loc = new SelectedContainer($('#selected-location'),
{
obj: sb_loc_main,
onlyOne: true
});
sb_loc_main.connectSelectedContainer(select_loc);
let sb_loc_1 = new TreeSelect($('#sb-location-2'), {obj: sb_loc_main});
let sb_loc_2 = new TreeSelect($('#sb-location-3'), {obj: sb_loc_main});
sb_loc_main.setNearbySelectBox(sb_loc_1);
sb_loc_1.setNearbySelectBox(sb_loc_2, sb_loc_main);
sb_loc_2.setNearbySelectBox("", sb_loc_1);
}
function createRealty(url) {
let sb_realty = new SelectOrCreate($('#sb-realty'), {url, visible: true});
sb_realty.setHeader(" ");
let select_realty = new SelectedContainerCreate($('#selected-realty'),
{
obj: sb_realty,
noTree: true,
onlyOne: true,
noHeader: true
});
sb_realty.connectSelectedContainer(select_realty);
sb_realty.setLinkBoxes([sb_loc_main, sb_constr_main, sb_build_main]);
select_realty.on("add", () => {
$('#checkbox-sb-realty').attr("disabled", true)
});
select_realty.on("remove", () => {
$('#checkbox-sb-realty').attr("disabled", false)
});
sb_realty.dataPromise.then(function () {
let $realty = $('#sb-realty');
let check = $('#checkbox-sb-realty');
if (!check.prop("checked")) {
$realty.hide();
}
}
);
let sb_realty_top = new NoTreeSelect($('#sb-realty-top'), {url, visible: true});
sb_realty_top.setHeader("Объект");
sb_realty_top.connectSelectedContainer(select_realty);
sb_realty_top.dataPromise.then(function () {
if (!sb_realty_top.dataTree.data.length) sb_realty_top.hide();
});
select_realty.on("add", (args)=> {
//TODO: Костыли!!!
$('#checkbox-sb-realty').prop("checked", true);
sb_realty.show();
let id = args[0];
if (id.text) return;
let el = sb_realty.dataTree.getElementById(id);
sb_realty_top.$searchInput.val(el.name);
sb_realty_top.selectedEl.id = id;
sb_realty_top.selectedEl.value = el.name;
sb_realty.selectedEl.id = id;
sb_realty._fillBoxes();
})
}
let sb_loc_main, sb_constr_main, sb_build_main;
createSpecs('/api/specializations_flat');
createBuildingClass('/api/building_classifications');
createConstructionType('/api/construction_type');
createLocations('/api/locations_flat');
createRealty('/api/realties/current_user')
});

@ -0,0 +1,19 @@
function customCheckInit() {
function tuneCheckBoxes($boxes) {
let currentState = $boxes.find("input").prop("checked") ? 'checked' : 'not-checked';
$boxes.find("div").hide();
$boxes.find("div." + currentState).show();
}
let $boxes = $('.custom-check');
tuneCheckBoxes($boxes);
$boxes.on("click", function (e) {
let inside_checkBox = $(e.target).parent().find("input");
inside_checkBox.prop("checked", !inside_checkBox.prop("checked"));
tuneCheckBoxes($boxes);
e.preventDefault();
return false;
});
}
export {customCheckInit}

@ -0,0 +1,20 @@
function extendedFieldInit() {
let $buttonF1 = $('.resButton');
if ($('.slide').hasClass("active")) $buttonF1.css('transform', 'rotate(0deg)');
$buttonF1.on("click", function (e) {
e.preventDefault();
let $slide = $('.slide');
if ($slide.hasClass("active")) {
$buttonF1.css('transform', 'rotate(180deg)');
$slide.slideUp(300);
} else {
$buttonF1.css('transform', 'rotate(0deg)');
$slide.slideDown(300);
}
$slide.toggleClass("active");
});
}
export {extendedFieldInit}

@ -0,0 +1,57 @@
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh)
return bytes + ' B';
var units = si
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u]
}
export default function fileUploadInit() {
var $fileUploadContainer = $('#fileUploadContainer');
$('#fileUploadAddBtn').on('click', function ($evt) {
$fileUploadContainer.find('.file-upload-widget').last().find('.file-upload-input').click()
});
$fileUploadContainer.on('change', '.file-upload-input', function ($evt) {
var $fileInput = $(this);
var $fileUploadWidget = $fileInput.closest('.file-upload-widget');
var filePath = $fileInput.val().replace(/\\/g, '/');
var fileName = path.basename(filePath);
//var fileExt = path.extname(filePath)
var fileSize = $fileInput.get(0).files && humanFileSize($fileInput.get(0).files[0].size);
if (fileName) {
$fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize);
var $newFileUploadWidget = $fileUploadWidget.clone();
$newFileUploadWidget.find('.file-upload-label').text('');
$fileUploadContainer.find('ul').first().append($newFileUploadWidget);
$fileUploadWidget.css('display', 'block')
}
});
$fileUploadContainer.on('click', '.file-upload-remove-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.file-upload-widget').remove()
});
$fileUploadContainer.on('click', '.existing-file-remove-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.existing-file-widget').remove()
});
}

@ -0,0 +1,21 @@
function onlyOneCheckboxInit(selector_first, selector_second) {
//TODO: need refactoring...
let $first = $(selector_first);
let $second = $(selector_second);
$first.change(()=> {
if ($first.prop("checked")){
$second.prop("checked", false)
}else {
$second.attr("checked", true)
}
});
$second.change(()=> {
if ($second.prop("checked")){
$first.attr("checked", false)
}else {
$first.attr("checked", true)
}
})
}
export {onlyOneCheckboxInit}

@ -0,0 +1,16 @@
function readMoreInit() {
$('.description .more').on("click", function (e) {
let $target = $(e.target);
$target.siblings(".complete").toggle();
$target.toggleClass("less");
});
// $(".more").toggle(function () {
// $(this).text("less..").siblings(".complete").show();
// }, function () {
// $(this).text("more..").siblings(".complete").hide();
// });
}
export {readMoreInit}

@ -0,0 +1,5 @@
function print(text) {
console.log(text);
}
export {print}

@ -0,0 +1,56 @@
function onBind(target, name, descriptor) {
const method = descriptor.value;
descriptor.value = function (...args) {
let binds = [];
args = Array.from(args);
for (let arg of args.slice()) {
if (typeof arg === 'object') {
binds.push(arg);
args.splice(args.indexOf(arg), 1);
}
}
method.apply(this, args);
for (let bind of binds) {
bind.func.bind(this)();
}
return this;
}
}
class Base {
constructor() {
this.attr1 = 'attr1';
console.log("Constructor")
}
@onBind
method1(a = 1, b = 2) {
console.log("this.attr1 = ", this.attr1);
console.log("a = ", a, "b = ", b);
}
on(methodName, func) {
this[methodName] = this[methodName].bind(this, {func});
}
}
let b = new Base();
b.on("method1", () => console.log("Another message..."));
b.on("method1", function () {
console.log("bind this.attr1 =", this.attr1);
});
b.method1("one", 2);
b.method1("bbb");
if (NODE_ENV == 'dev') {
console.log("Dev mode message")
}
function a({a=2, b=a+4}) {
}

@ -1,7 +0,0 @@
#!/usr/bin/env bash
echo "run browserify"
cd ..
source ~/venv/proekton/bin/activate
browserify ./js/src/init.js -o ./js/build/init.js -t babelify
browserify ./js/src/init_user_profile.js -o ./js/build/init_user_profile.js -t babelify
#watchify ./js/src/init.js -t babelify -o ./js/build/init.js

@ -2,29 +2,30 @@ import {AbsBaseSelect} from './base/AbsBaseSelect'
import NoTreeData from './data/NoTreeData' import NoTreeData from './data/NoTreeData'
export default class NoTreeSelect extends AbsBaseSelect{ export default class NoTreeSelect extends AbsBaseSelect{
constructor($container, {url, obj, visible=true}){ constructor($container, {url, obj, visible=true, required = false}){
//TODO: сделать автоматическую передачу всех параметров родителю //TODO: сделать автоматическую передачу всех параметров родителю
super($container, {url, obj, visible}); super($container, {url, obj, visible, required});
} }
_buildComponents(data) { _buildComponents(data) {
super._buildComponents(data); super._buildComponents(data);
this.dataTree = this.dataTree || new NoTreeData(data.results); this.dataTree = this.dataTree || new NoTreeData(data.results || data);
this.$buttonAddOptions.hide(); this.$buttonAddOptions.hide();
this._fillOptionsData(); this._fillOptionsData();
this._bindEvents(); this._bindEvents();
} }
_onclickOptionsElement(e) { _onclickOptionsElement(e) {
this.selectedEl.id = $(e.target).data("id"); let id = $(e.target).data("id");
this.selectedEl.id = id;
this.selectedEl.value = $(e.target).html(); this.selectedEl.value = $(e.target).html();
this.$searchInput.val($(e.target).html()); this.$searchInput.val($(e.target).html());
this.$buttonAddOptions.show(); this.$buttonAddOptions.show();
this.$optionsBox.hide(); this.$optionsBox.hide();
this.selectedContainer.add(this.selectedEl.id);
this.clear(); this.clear();
this.selectedContainer.add(id);
e.preventDefault(); e.preventDefault();
return false; return false;
} }

@ -0,0 +1,137 @@
import {
tmpl_selectBoxOptions,
tmpl_selectBoxEditCont,
tmpl_selectBox,
AbsBaseSelect
} from './base/AbsBaseSelect'
import NoTreeData from './data/NoTreeData'
const htmlTemplate = ({header, selectBox, id = "", classes = "", tmpl_selectBoxOptions = () => "", tmpl_selectBoxResults = () => ""}) =>
`
<div class="select-box-container ${classes}" id="${id}">
<div class="select-box-search">
${selectBox}
</div>
${tmpl_selectBoxOptions()}
${tmpl_selectBoxResults()}
<span style="clear: both"></span>
</div>
`;
const tmpl_selectBoxResults = () =>
`
<div style="width: 100%; max-width: 95%" class="select-box-results">
<button class="button-add create">СОЗДАТЬ</button>
</div>
`;
// const tmpl_elementResult = (el, id, header) =>
// `<li data-id="${id}">
// ${el}
// </li>`;
export default class SelectOrCreate extends AbsBaseSelect {
getTemplate(classes) {
let selectBox = this.hasEditableContainer ? tmpl_selectBoxEditCont() : tmpl_selectBox();
classes = classes ? classes.join(" ") : "";
return htmlTemplate({
header: "TestHeader", selectBox, id: this.containerId, classes,
tmpl_selectBoxOptions, tmpl_selectBoxResults
})
}
setLinkBoxes(boxes = []) {
this.boxes = boxes;
}
_buildComponents(data) {
super._buildComponents(data);
const self = this;
//TODO: Изменять свойство visible при show/hide
if (!this.visible) this.hide();
if (this.hasEditableContainer) this.$editableContainer.hide();
this.dataTree = this.dataTree || new NoTreeData(data);
this.$buttonCreate = this.$resultsBox.find('.create');
// console.log("$buttonCreate = ", $buttonCreate);
this.$buttonCreate.on("click", () => console.log('Button Create'));
this.$buttonCreate.on("click", this._onButtonCreate.bind(self));
this._fillOptionsData();
this._bindEvents();
}
getData(url, data = {}) {
return Promise.resolve($.ajax({
url: url,
dataType: 'json',
data: data,
}))
}
_onLoadDataError(error) {
console.log("Error loading data -->", error);
}
_fillBoxes() {
const self = this;
let id = this.selectedEl.id;
this.getData(`/api/realties?id=${id}`)
.then((_data)=> {
let data = _data.results[0] || _data[0];
// this._addToSelectedContainer(this.selectedEl.id);
// console.log("res data = ", data);
for (let box of this.boxes) {
box.selectedContainer.removeAll();
//TODO: Костыль!
if (box.type == 'building_classifications' && data['building_classification']) {
// console.log("building_classification = ",data['building_classification']);
box._addToSelectedContainer(data['building_classification'].id)
} else if (box.type == 'locations_flat' && data['location']) {
// console.log("location = ",data['location']);
box._addToSelectedContainer(data['location'].id)
} else if (box.type == 'construction_type' && data['construction_type']) {
// console.log("construction_type = ",data['construction_type']);
box._addToSelectedContainer(data['construction_type'].id)
} else {
console.log("Нет совпадений для ", box.type);
}
}
}
)
.catch(this._onLoadDataError.bind(self));
}
_onButtonAddOptions(e) {
this._fillBoxes();
super._onButtonAddOptions(e);
}
_onButtonCreate(e) {
this.selectedContainer.add({text: this.$searchInput.val()});
if (this.boxes) {
for (let box of this.boxes) {
console.log('box clear');
box.selectedContainer.removeAll();
}
}
e.preventDefault();
this.$buttonCreate.hide();
this.$searchInput.val("");
}
_onInput_searchInput(e) {
// this._fillResultsData(self .$searchInput.val());
this.$buttonAddOptions.hide();
this.$buttonCreate.show();
// console.log("on input");
this.$resultsBox.show();
this.$optionsBox.hide();
}
_onClick_searchInput(e) {
this.$optionsBox.show();
this.$resultsBox.hide();
this.$searchInput.val("");
}
}

@ -5,8 +5,8 @@ import onBind from './decorators'
let tmpl_selectedElement = (header, name, id) => let tmpl_selectedElement = (header, name, id) =>
` `
<div class="selected-element"> <div class="selected-element" style="${header ? '': 'display:flex; align-items: center;' }">
<div class="header"> <div class="${header ? 'header' : ''}">
${header} ${header}
</div> </div>
<div class="name"> <div class="name">
@ -17,19 +17,23 @@ let tmpl_selectedElement = (header, name, id) =>
`; `;
export default class SelectedContainer { export default class SelectedContainer {
constructor($container, {obj, noTree = false, onlyOne = false}) { constructor($container, {obj, noTree = false, noHeader = false, onlyOne = false}) {
// TODO: rename variables to camelCase // TODO: rename variables to camelCase
this.$self = $container; this.$self = $container;
this.elements_id = []; // [spec_id, spec_id, ...] this.elements_id = []; // [spec_id, spec_id, ...]
this.onlyOne = onlyOne; this.onlyOne = onlyOne;
this.options = {noHeader};
const self = this; const self = this;
this.$self.hide(); this.$self.hide();
obj.dataPromise obj.dataPromise
.then( .then(
(data) => { (data) => {
this.dataTree = noTree ? new NoTreeData(data.results) : new DataTree(data.results); data = data.results ? data.results : data;
this.dataTree = noTree ? new NoTreeData(data) : new DataTree(data);
this.$input = this.$self.find('input[type="hidden"]'); this.$input = this.$self.find('input[type="hidden"]');
if (this.$input.length == 0) throw new URIError(`input for ${this.$self.attr("class")} not found`);
this.restoreElements(); this.restoreElements();
} }
) )
@ -86,6 +90,12 @@ export default class SelectedContainer {
console.log("Error loading data -->", error); console.log("Error loading data -->", error);
} }
removeAll() {
for (let id of this.elements_id){
this._removeById(id);
}
}
@onBind @onBind
remove(e) { remove(e) {
let spec_id = $(e.target).data("id"); let spec_id = $(e.target).data("id");
@ -111,7 +121,8 @@ export default class SelectedContainer {
const name = this.dataTree.getElementById(id).name; const name = this.dataTree.getElementById(id).name;
this.elements_id.push(id); this.elements_id.push(id);
if (this.$input) this.$input.val(this.elements_id.join(',')); if (this.$input) this.$input.val(this.elements_id.join(','));
this.$self.append(SelectedContainer.getTemplate(header || "&nbsp;", name, id)); // console.log("header = ", header);
this.$self.append(SelectedContainer.getTemplate(header || (this.options.noHeader ? "" : "&nbsp;") , name, id));
this.btn_remove = this.$self.find('.icon-remove'); this.btn_remove = this.$self.find('.icon-remove');
this.btn_remove.on("click", this.remove.bind(self)); this.btn_remove.on("click", this.remove.bind(self));
if (this.elements_id.length) this.$self.show(); if (this.elements_id.length) this.$self.show();
@ -120,6 +131,10 @@ export default class SelectedContainer {
@onBind @onBind
add(_id, max_len) { add(_id, max_len) {
const id = Number(_id); const id = Number(_id);
const el = this.dataTree.getElementById(id);
if (!el){
throw new Error(`Элемент с id = ${_id} не найден и не может быть добавлен`)
}
let self = this; let self = this;
if (this.onlyOne) { if (this.onlyOne) {
this.replace(_id, max_len); this.replace(_id, max_len);

@ -0,0 +1,28 @@
import SelectedContainer from './SelectedContainer'
import onBind from './decorators'
/**
* Контэйнер - позволяющий принимать/отправлять новый объект для создания
*/
//TODO: попробовать реализовать как Mixin
export default class SelectedContainerCreate extends SelectedContainer {
@onBind
add(_id, max_len) {
console.log("_id = ", _id);
const self = this;
if (_id.text) {
this._removeById(this.elements_id[0]);
this.elements_id = [0];
this.$input_id = this.$self.find('input[type="hidden"].-id');
this.$input_id.val();
this.$input_name = this.$self.find('input[type="hidden"].-name');
this.$input_name.val(_id.text);
this.$self.append(SelectedContainer.getTemplate("", _id.text, 0));
this.btn_remove = this.$self.find('.icon-remove');
this.btn_remove.on("click", this.remove.bind(self));
if (this.elements_id.length) this.$self.show();
return
}
super.add(_id, max_len)
}
}

@ -17,7 +17,9 @@ const tmpl_elementResult = (el, id, header) =>
`<li data-id="${id}"> `<li data-id="${id}">
${el} ${el}
</li>`; </li>`;
/**
* Поиск только в своей категории, отсутствует множественный выбор
*/
export default class SingleTreeSelect extends TreeSelect { export default class SingleTreeSelect extends TreeSelect {
getTemplate(classes) { getTemplate(classes) {
let selectBox = this.hasEditableContainer ? tmpl_selectBoxEditCont() : tmpl_selectBox(); let selectBox = this.hasEditableContainer ? tmpl_selectBoxEditCont() : tmpl_selectBox();

@ -2,11 +2,6 @@ import {AbsBaseSelect} from './base/AbsBaseSelect'
import DataTree from './data/DataTree' import DataTree from './data/DataTree'
export default class TreeSelect extends AbsBaseSelect{ export default class TreeSelect extends AbsBaseSelect{
constructor($container, {url, obj, hasEditableContainer = false, visible = hasEditableContainer}){
//TODO: сделать автоматическую передачу всех параметров родителю
super($container, {url, obj, hasEditableContainer, visible});
}
setNearbySelectBox(next, prev) { setNearbySelectBox(next, prev) {
this.nextSelectBox = next; this.nextSelectBox = next;
this.prevSelectBox = prev; this.prevSelectBox = prev;

@ -19,7 +19,7 @@ const tmpl_selectBoxEditCont = ({preloaderTemplate = ""}={}) =>
const tmpl_selectBox = ({preloaderTemplate = ""}={}) => const tmpl_selectBox = ({preloaderTemplate = ""}={}) =>
` `
${preloaderTemplate} ${preloaderTemplate}
<input class="select-box-search" type="text" placeholder="Выберите/Поиск"> <input class="select-box-search" type="text" placeholder="Выберите/Поиск" value="">
<button style="display: none" class="button-add options">ПРИМЕНИТЬ</button> <button style="display: none" class="button-add options">ПРИМЕНИТЬ</button>
`; `;
@ -65,12 +65,13 @@ const tmpl_selectBoxResults = () =>
</div> </div>
`; `;
const htmlTemplate = ({header, selectBox, id = "", classes = "", tmpl_selectBoxOptions = () => "", tmpl_selectBoxResults = () => ""}) => const htmlTemplate = ({header, selectBox, required = false, id = "", classes = "", tmpl_selectBoxOptions = () => "", tmpl_selectBoxResults = () => ""}) =>
` `
<div class="select-box-container ${classes}" id="${id}"> <div class="select-box-container ${classes}" id="${id}">
<div class="select-box-header"> <div class="select-box-header">
<div class="header">${header}</div> <div class="header">${header}</div>
<i class="fa fa-question-circle-o" aria-hidden="true" title="bla-bla-bla..."></i> <i class="fa fa-question-circle-o" aria-hidden="true" title="bla-bla-bla..."></i>
${required ? '<span class="required">Обязательно</span>': ''}
</div> </div>
<div class="select-box-search"> <div class="select-box-search">
${selectBox} ${selectBox}
@ -86,7 +87,7 @@ let tmpl_light = (el) => `<span class="highlight">${el}</span>`;
let tmpl_preloader = () => `<div id="component-preloader"><span class="spinner"></span></div>`; let tmpl_preloader = () => `<div id="component-preloader"><span class="spinner"></span></div>`;
export default class AbsBaseSelect { export default class AbsBaseSelect {
constructor($container, {url, obj, hasEditableContainer = false, visible = false}) { constructor($container, {url, obj, hasEditableContainer = false, visible = false, required = false}) {
if (new.target === AbsBaseSelect) { if (new.target === AbsBaseSelect) {
throw new TypeError("Cannot construct Abstract instances directly"); throw new TypeError("Cannot construct Abstract instances directly");
} }
@ -100,6 +101,7 @@ export default class AbsBaseSelect {
this.$container = $container; this.$container = $container;
this.hasEditableContainer = hasEditableContainer; this.hasEditableContainer = hasEditableContainer;
this.visible = visible; this.visible = visible;
this.required = required;
// Быстрая заглушка, до отображения данных // Быстрая заглушка, до отображения данных
if (visible) { if (visible) {
let preloaderTemplate = tmpl_preloader(); let preloaderTemplate = tmpl_preloader();
@ -112,7 +114,11 @@ export default class AbsBaseSelect {
this.$preloader = $container.find('#component-preloader'); this.$preloader = $container.find('#component-preloader');
this.$spinner = this.$preloader.find('.spinner'); this.$spinner = this.$preloader.find('.spinner');
} }
if (url) this.dataPromise = this.getData(url); if (url) {
this.dataPromise = this.getData(url);
//TODO: дописать нормальную обработку url
this.type = url.split("/")[2]
}
let _dataPromise; let _dataPromise;
if (url) { if (url) {
_dataPromise = this.dataPromise; _dataPromise = this.dataPromise;
@ -137,7 +143,7 @@ export default class AbsBaseSelect {
let selectBox = this.hasEditableContainer ? tmpl_selectBoxEditCont() : tmpl_selectBox(); let selectBox = this.hasEditableContainer ? tmpl_selectBoxEditCont() : tmpl_selectBox();
classes = classes ? classes.join(" ") : ""; classes = classes ? classes.join(" ") : "";
return htmlTemplate({ return htmlTemplate({
header: "TestHeader", selectBox, id: this.containerId, classes, header: "TestHeader", selectBox, required: this.required, id: this.containerId, classes,
tmpl_selectBoxOptions, tmpl_selectBoxResults tmpl_selectBoxOptions, tmpl_selectBoxResults
}) })
} }
@ -278,11 +284,10 @@ export default class AbsBaseSelect {
this.$resultsBox.hide(); this.$resultsBox.hide();
this.$optionsBox.hide(); this.$optionsBox.hide();
this.$buttonAddOptions.hide(); this.$buttonAddOptions.hide();
//TODO: реализовать нормальное show/hide + visible
if (!this.visible) this.hide();
// TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select // TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select
// REDEFINE IN CHILD
// this.dataTree = data;
// this._bindEvents();
} }
_fillOptionsData() { _fillOptionsData() {
@ -392,6 +397,18 @@ export default class AbsBaseSelect {
this.selectedContainer.add(id) this.selectedContainer.add(id)
} }
_onInput_searchInput(e) {
this._fillResultsData(this.$searchInput.val());
this.$resultsBox.show();
this.$optionsBox.hide();
}
_onClick_searchInput(e) {
this.$optionsBox.show();
this.$resultsBox.hide();
this.$searchInput.val("");
}
_bindEvents() { _bindEvents() {
let self = this; let self = this;
$(document).click(function (event) { $(document).click(function (event) {
@ -401,22 +418,11 @@ export default class AbsBaseSelect {
self._looseFocus(); self._looseFocus();
}); });
// RESULTS BOX // RESULTS BOX
this.$searchInput.on("input", function (e) { this.$searchInput.on("input", this._onInput_searchInput.bind(self));
self._fillResultsData(self.$searchInput.val());
self.$resultsBox.show();
self.$optionsBox.hide();
});
// OPTIONS BOX // OPTIONS BOX
this.$searchInput.on("click", function (e) { this.$searchInput.on("click", this._onClick_searchInput.bind(self));
self.$optionsBox.show();
self.$resultsBox.hide();
self.$searchInput.val("");
});
this.$buttonAdd.on("click", function (e) { this.$buttonAdd.on("click", this._onButtonAdd.bind(self));
self._onButtonAdd(e);
});
this.$buttonAddOptions.on("click", this._onButtonAddOptions.bind(self)) this.$buttonAddOptions.on("click", this._onButtonAddOptions.bind(self))
} }

@ -4,18 +4,19 @@ export default function onBind(target, name, descriptor) {
descriptor.value = function (...args) { descriptor.value = function (...args) {
let binds = []; let binds = [];
args = Array.from(args); args = Array.from(args);
// console.log("args -->", args.slice());
for (let arg of args.slice()) { for (let arg of args.slice()) {
// console.log("onBind -->", typeof arg, "arg = ", arg); // console.log("onBind -->", typeof arg, "arg = ", arg);
// console.log("arg.func -->", typeof arg.originalEvent); // console.log("arg.func -->", typeof arg.originalEvent);
// typeof arg === 'object' && !(arg.originalEvent) // typeof arg === 'object' && !(arg.originalEvent)
if (arg.bindFunc) { if (arg && arg.bindFunc) {
binds.push(arg); binds.push(arg);
args.splice(args.indexOf(arg), 1); args.splice(args.indexOf(arg), 1);
} }
} }
method.apply(this, args); method.apply(this, args);
for (let bind of binds) { for (let bind of binds) {
bind.func.bind(this)(); bind.func.bind(this)(args);
} }
return this; return this;
} }

@ -0,0 +1,4 @@
@import "parts/fonts.sass"
@import "parts/select-box"
@import "parts/selected-container"
@import "parts/editable-container"

@ -0,0 +1,11 @@
.editable-container
display: block
float: left
background-color: #e5e5e5
color: #585858
font-size: 9pt
padding: 5px 10px
height: 51px
margin-left: 8px
position: relative
left: -30px

@ -0,0 +1,18 @@
@import "base/variavles"
@font-face
font-family: "Myriad"
src: url('#{$static}/fonts/MyriadPro/MyriadPro-Cond.otf')
font-weight: normal
font-style: normal
@font-face
font-family: "Myriad"
src: url("#{$static}/fonts/MyriadPro/MyriadPro-BoldCond.otf")
font-weight: bold
font-style: normal
@font-face
font-family: "Myriad"
src: url("#{$static}/fonts/MyriadPro/MyriadPro-CondIt.otf")
font-weight: normal
font-style: italic

@ -0,0 +1,166 @@
@import "base/variavles"
@import "base/colors"
@import "common/parts"
.select-box-container
display: block
.select-box-header
white-space: nowrap
word-wrap: break-word
.header
@extend %header
.select-box-bottom
clear: both
.select-box-results, .select-box-options
position: absolute
z-index: 99999
opacity: 0.95
.box-wrapper
display: block
max-height: 200px
overflow-y: auto
border: 1px solid #{map_get($component_colors, border)}
background-color: #F2F2F2
box-shadow: 12px 12px 10px -6px rgba(0, 0, 0, 0.2)
.select-box-results
input[type=checkbox]
margin: 0 5px 0 5px
.header
font-size: 8pt
color: #757575
pointer-events: none
margin: 0
padding: 0
.select-box-options li, ul
margin: 0
padding: 0
.select-box-options ul
border-right: 1px solid #{map_get($component_colors, border)}
.select-box-results
ul:last-child
border-bottom: none
li
padding: 2px 10px
border-bottom: 1px solid #{map_get($component_colors, border)}
list-style: none
font-size: 9pt
color: #494546
.select-box-options li
padding: 2px 10px
border-bottom: 1px solid #{map_get($component_colors, border)}
list-style: none
font-size: 9pt
color: #494546
.select-box-results label, .select-box-options label, .select-box-results li, .select-box-options li
cursor: pointer
display: inline-block
font-weight: normal
width: 100%
.select-box-results li:hover, .select-box-options li:hover
background-color: #dcdcdc
border-left: 2px solid #{map_get($component_colors, select)}
color: #0e0e0e
.select-box-search
position: relative
input.select-box-search
height: 51px
width: 100%
border: 1px solid #{map_get($component_colors, border)}
outline: none
padding: 5px 40px 5px 20px
background:
image: url("#{$static}/img/zoom.svg")
repeat: no-repeat
position-x: right
position-y: center
size: 40px 40px
color: white
margin-bottom: -1px
&.active
border: 1px solid #{map_get($component_colors, select)}
&:-webkit-autofill
transition: background-color 5000s ease-in-out 0s
&:hover, &:focus
transition: background-color 5000s ease-in-out 0s
.select-box-results
.main-part
display: block
border-right: 1px solid #{map_get($component_colors, border)}
.other-part
border-right: 1px solid #{map_get($component_colors, border)}
border-top: 1px solid #000000
color: darkgray
.other-header
color: #000
font-weight: bold
margin-left: 10px
/*???
.select-box-options .box-wrapper, .select-box-results
min-width: 300px
max-width: 400px
button.button-add
box-shadow: none
border: none
.button-add
position: absolute
bottom: -30px
right: 0
z-index: 999
font:
family: Myriad
weight: normal
style: normal
size: 10pt
-moz-border-radius: 15px
/* Firefox
-webkit-border-radius: 15px
/* Safari 4
border-radius: 15px
/* IE 9, Safari 5, Chrome
background-color: #{map_get($component_colors, select)}
padding: 4px 15px 2px 15px
text-decoration: none
color: white
&.results
position: relative
float: right
bottom: 0
.highlight
color: #{map_get($component_colors, select)}
#component-preloader
position: absolute
left: 0
top: 0
right: 0
bottom: 0
background: #9fa4a4
opacity: 0.2
z-index: 100500
.spinner
width: 32px
height: 32px
position: absolute
left: 50%
top: 50%
background: url('#{$static}/img/ajax-loader.gif') no-repeat 50% 50%
margin: -16px 0 0 -16px

@ -0,0 +1,44 @@
@import "base/variavles"
.selected-container
min-height: 40px
//padding-bottom: 20px
.selected-element
padding: 5px 35px 5px 10px
margin-top: 8px
min-height: 45px
background-color: #e3e3e3
border: 1px solid #dbdbdb
position: relative
-moz-border-radius: 10px
-webkit-border-radius: 10px
border-radius: 10px
.header,
.name
white-space: nowrap
text-overflow: ellipsis
overflow: hidden
width: 100%
.header
font-size: 7pt
color: #676363
.name
font-size: 11pt
display: inline-block
.icon-remove
background-image: url('#{$static}/img/cross01.png')
background-size: 20px 20px
position: absolute
right: 5px
top: 15px
width: 20px
height: 20px
cursor: pointer
margin-left: -20px
.horizontal
&.selected-container
display: inline-block
max-width: 300px
.header, .name
max-width: 300px

@ -0,0 +1,6 @@
$col_component_headers: #000
//$colors: (c_red: #ff0000, c_green: #00FF00, c_blue: #0000FF)
$component_colors: (header: #000, header_favicon: #5e5e5e, border: #cccccc, select: #FF0029)
// #{map_get($component_colors, border)}

@ -0,0 +1,29 @@
$static : '/static'
@font-face
font-family: 'pfbeausanspro-reg'
src: url('#{$static}/fonts/PFBeauSansPro-Regular/PFBeauSansPro-Regular.eot?#iefix') format("embedded-opentype"), url('#{$static}/fonts/PFBeauSansPro-Regular/PFBeauSansPro-Regular.woff') format("woff"), url('#{$static}/fonts/PFBeauSansPro-Regular/PFBeauSansPro-Regular.ttf') format("truetype"), url('#{$static}/fonts/PFBeauSansPro-Regular/PFBeauSansPro-Regular.svg#PFBeauSansPro-Regular') format("svg")
font-weight: normal
font-style: normal
@font-face
font-family: 'pfbeausanspro-thin'
src: url('#{$static}/fonts/PFBeauSansPro-Thin/PFBeauSansPro-Thin.eot?#iefix') format("embedded-opentype"), url('#{$static}/fonts/PFBeauSansPro-Thin/PFBeauSansPro-Thin.woff') format("woff"), url('#{$static}/fonts/PFBeauSansPro-Thin/PFBeauSansPro-Thin.ttf') format("truetype"), url('#{$static}/fonts/PFBeauSansPro-Thin/PFBeauSansPro-Thin.svg#PFBeauSansPro-Thin') format("svg")
font-weight: normal
font-style: normal
@font-face
font-family: 'pfdintextcomppro-regular'
src: url('#{$static}/fonts/PFDinTextCompPro-Regular/PFDinTextCompPro-Regular.eot?#iefix') format("embedded-opentype"), url('#{$static}/fonts/PFDinTextCompPro-Regular/PFDinTextCompPro-Regular.woff') format("woff"), url('#{$static}/fonts/PFDinTextCompPro-Regular/PFDinTextCompPro-Regular.ttf') format("truetype"), url('#{$static}/fonts/PFDinTextCompPro-Regular/PFDinTextCompPro-Regular.svg#PFDinTextCompPro-Regular') format("svg")
font-weight: normal
font-style: normal
@font-face
font-family: 'Arial-MT-Regular'
src: url('#{$static}/fonts/Arial-MT-Regular/Arial-MT-Regular.eot')
src: url('#{$static}/fonts/Arial-MT-Regular/Arial-MT-Regular.eot?#iefix') format("embedded-opentype"), url('#{$static}/fonts/Arial-MT-Regular/Arial-MT-Regular.woff') format("woff"), url('#{$static}/fonts/Arial-MT-Regular/Arial-MT-Regular.ttf') format("truetype"), url('#{$static}/fonts/Arial-MT-Regular/Arial-MT-Regular.svg#Arial-MT-Regular') format("svg")
font-weight: normal
font-style: normal

@ -0,0 +1 @@
$static : '/static'

@ -0,0 +1,22 @@
@import "base/colors"
%header
display: inline-block
text-overflow: ellipsis
overflow: hidden
word-wrap: break-word
vertical-align: bottom
font-size: 12pt
color: #{map_get($component_colors, header)}
max-width: 220px
.fa
color: #{map_get($component_colors, header_favicon)}
position: relative
padding-left: 2px
padding-right: 2px
&:hover
cursor: pointer
.required
font:
size: 10pt
color: #9f9f9f

@ -0,0 +1,233 @@
@import "common/parts"
@import "base/colors"
@import "base/variavles"
.simple-field
.header
@extend %header
max-width: 100%
label
font-weight: normal
.simple-input
height: 51px
width: 100%
border: 1px solid #{map_get($component_colors, border)}
outline: none
padding: 5px 40px 5px 20px
background-color: white
margin-bottom: -1px
&:-webkit-autofill
-webkit-box-shadow: 0 0 0 1000px white inset
//transition: background-color 5000s ease-in-out 0s
&.icon-rub
background:
image: url("#{$static}/img/rub.png")
repeat: no-repeat
position-x: 95%
position-y: center
size: 16px 16px
color: white
&.icon-days
background:
image: url("#{$static}/img/days.png")
repeat: no-repeat
position-x: 95%
position-y: center
size: 40px 14px
color: white
&.italic::-webkit-input-placeholder
font-style: italic
.simple-select
height: 51px
width: 100%
border: 1px solid #{map_get($component_colors, border)}
outline: none
padding: 5px 40px 5px 20px
background-color: white
margin-bottom: -1px
display: flex
align-items: center
text-align: center
select
background-color: darkgray
&.fill
background-color: #F2F2F2
.text
color: #a3a3a3
textarea.description
max-width: 100%
width: 100%
&::-webkit-input-placeholder
font-style: italic
.btn-simple
border-radius: 40px
padding: 10px 15px
border: 1px solid #FF0029
background: none
font-family: Myriad, sans-serif
font-weight: normal
font-style: normal
font-size: 14pt
&:hover
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2)
-webkit-transform: scale(1.04)
-moz-transform: scale(1.04)
transform: scale(1.04)
&:focus
outline: none
&:active
outline: 0 !important
.upload-new, .btn-simple
transition: all 0.3s
cursor: pointer
.upload-new
width: 50%
height: 30px
overflow: hidden
cursor: pointer
border-radius: 40px
border: 1px solid #FF0029
box-sizing: border-box
&:hover
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2)
-webkit-transform: scale(1.04)
-moz-transform: scale(1.04)
transform: scale(1.04)
input
display: block !important
width: 100% !important
height: 30px !important
opacity: 0 !important
cursor: pointer
p
line-height: 30px
text-transform: uppercase
margin: -30px 0 0 0
text-align: center
p,
& + span
font-size: 10pt
font-family: Myriad, sans-serif
.upload-new.paper-clip
padding-left: 40px
padding-right: 15px
background:
image: url("#{$static}/img/paper-clip_icon._g.png")
repeat: no-repeat
position-x: 5%
position-y: center
size: 30px 30px
color: white
//background: no-repeat left
//background-size: 30px 30px
width: auto
.upload-new.paper-clip p
//font-size: 10pt
width: auto
text-align: right
.separator
margin-top: 35px
margin-bottom: 15px
display: flex
.header
@extend %header
max-width: 100%
.resButton
position: relative
top: -15px
width: 50px
height: 50px
background-color: white
border: 1px solid #CFCFCF
color: #FF0029
text-align: center
font-size: 16px
border-radius: 50%
margin-left: 25px
-webkit-transition: all 0.3s ease-out
-moz-transition: all 0.3s ease-out
transition: all 0.3s ease-out
transform: rotate(180deg)
&:focus
outline: none
.border
flex: 1 1 auto
margin: 10px 0 0 25px
border-top: 1px solid #CFCFCF
.btn-plus
white-space: normal
padding-left: 18%
color: #FF0029
line-height: 1em
font-family: Arial-MT-Regular, sans-serif
font-size: 10pt
.btn-plus:hover
color: #FF0029
.btn-plus
background: url("#{$static}/img/circle_cross.svg") no-repeat left
background-position-x: 5px
.custom-checkbox
width: 20px
height: 20px
.custom-radio
width: 20px
height: 20px
.custom-check
cursor: pointer
display: inline-block
width: 100%
.checked
background: url("#{$static}/img/checkbox_Check.png.png") no-repeat center
background-size: 100% 51px
width: 100%
height: 51px
.not-checked
background: url("#{$static}/img/checkbox_notCheck.png") no-repeat center
background-size: 100% 51px
width: 100%
height: 51px
.documentsChat
.file-upload-label
color: darkgray
.file-upload-remove-btn
display: inline-block
//position: absolute
width: 11px
height: 11px
background: url('#{$static}/img/delDoc.png') no-repeat center
//background-size: cover
//right: -20px !important
//top: 2px
cursor: pointer
.complete
display: none
.more
font-style: italic
color: #{map_get($component_colors, select)}
padding: 3px
cursor: pointer
&:before
content: '...читать далее'
&.less
&:before
content: 'свернуть'

@ -0,0 +1,72 @@
@import "base/fonts.sass"
@import "base/colors.sass"
@import "common/parts"
body
font-size: 11pt
font-family: Arial-MT-Regular, Arial, sans-serif
.main-scope
> .row
border-right: 1px solid #{map_get($component_colors, border)}
border-left: 1px solid #{map_get($component_colors, border)}
.main-content
padding: 43px 25px 40px 25px
.title-scope
line-height: 36px
padding: 0 100px
text-align: center
border-bottom: 1px solid #{map_get($component_colors, border)}
//width: 100%
h1
font:
family: 'pfbeausanspro-thin', sans-serif
size: 36px
style: normal
variant-ligatures: normal
variant-caps: normal
variant-numeric: normal
weight: normal
stretch: normal
letter-spacing: 2px
.vertical-child
margin-top: 30px
.header
@extend %header
max-width: 100%
// TODO: move to modules/_mods.sass
.mod-align-bottom
display: flex
//-ms-flex-align: center
//-webkit-align-items: center
//-webkit-box-align: center
align-items: flex-end
.mod-align-center
display: flex
//-ms-flex-align: center
//-webkit-align-items: center
//-webkit-box-align: center
align-items: center
.logical-block
$pad: 30px
padding-top: $pad
padding-bottom: $pad
margin-top: $pad
border-top: 1px solid #{map_get($component_colors, border)}
border-bottom: 1px solid #{map_get($component_colors, border)}
.select-text
color: #{map_get($component_colors, select)}
.slide
display: none
.slide.active
display: block

@ -0,0 +1,6 @@
.vertical-bottom
display: flex
-ms-flex-align: center
-webkit-align-items: center
-webkit-box-align: center
align-items: flex-end

@ -0,0 +1,10 @@
//TODO: Заготовка, на будущее
//http://www.creative-seo.ru/blog/sass-maps/
@import "base/colors"
@function component_colors($key)
@if map-has-key($component_colors, $key)
@return map-get($component_colors, $key)
@warn "Unknown `#{$key}` in $component_colors."
@return null

@ -3,14 +3,13 @@
"version": "0.0.3", "version": "0.0.3",
"description": "curl http://nodejs.org/dist/node-latest.tar.gz | tar xvz cd node-v* python2 ./configure --prefix=~/venv/proekton/(or $VIRTUAL_ENV) make install", "description": "curl http://nodejs.org/dist/node-latest.tar.gz | tar xvz cd node-v* python2 ./configure --prefix=~/venv/proekton/(or $VIRTUAL_ENV) make install",
"main": "init.js", "main": "init.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Booblegum", "author": "Booblegum",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"babel-core": "^6.18.2",
"babel-loader": "^6.2.8",
"babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.18.0", "babel-preset-es2015": "^6.18.0",
"babelify": "^7.3.0" "webpack": "^1.13.3"
} }
} }

@ -116,6 +116,7 @@ class CustomerProjectEditForm(forms.ModelForm):
'price_and_term_required', 'price_and_term_required',
'realty', 'realty',
'specialization', 'specialization',
'term',
'term_type', 'term_type',
'text', 'text',
'work_type', 'work_type',
@ -155,6 +156,50 @@ class CustomerProjectEditForm(forms.ModelForm):
return cleaned_data return cleaned_data
class CustomerProjectEditFormNew(forms.ModelForm):
# Define a form field manually for a reverse model vield:
files = forms.ModelMultipleChoiceField(
queryset=ProjectFile.objects.none(),
widget=forms.CheckboxSelectMultiple,
required=False,
)
class Meta:
model = Project
fields = (
'budget',
'budget_by_agreement',
'cro',
# 'currency',
'deal_type',
'files',
'name',
'price_and_term_required',
'realty',
'specialization',
'term',
# 'term_type',
'text',
# 'work_type',
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
# self.fields['realty'].queryset = self.request.user.realties.all()
# self.fields['budget'].required = False
# self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants()
# self.fields['specialization'].queryset = Specialization.objects # Migrate with this enabled
# print("files = ", self.instance.files)
# if self.instance.pk:
# self.fields['files'].queryset = self.instance.files
class RealtyForm(forms.ModelForm): class RealtyForm(forms.ModelForm):
building_classification = TreeNodeChoiceField( building_classification = TreeNodeChoiceField(
BuildingClassfication.objects.exclude(name='_root'), BuildingClassfication.objects.exclude(name='_root'),
@ -193,6 +238,40 @@ class RealtyForm(forms.ModelForm):
# self.fields['location'].queryset = Location.objects # Migrate with this enabled # self.fields['location'].queryset = Location.objects # Migrate with this enabled
class RealtyFormNew(forms.ModelForm):
# building_classification = TreeNodeChoiceField(
# BuildingClassfication.objects.exclude(name='_root'),
# label="ll", initial='',
# widget=forms.Select(attrs={
# 'class': 'selectpicker',
# 'id': 'realtyBuildingClassificationId'
# }),
# level_indicator='',
# )
class Meta:
model = Realty
fields = (
'building_classification',
'construction_type',
'location',
'name',
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
# if not self.data.get('extra_fields'):
# self.fields['name'].required = False
#
# self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants()
# self.fields['building_classification'].queryset = BuildingClassfication.objects.root_nodes()[
# 0].get_descendants()
# self.fields['location'].queryset = Location.objects # Migrate with this enabled
class PortfolioForm(forms.ModelForm): class PortfolioForm(forms.ModelForm):
building_classification = TreeNodeChoiceField( building_classification = TreeNodeChoiceField(
BuildingClassfication.objects.exclude(name='_root'), BuildingClassfication.objects.exclude(name='_root'),

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-12-01 17:03
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import mptt.fields
class Migration(migrations.Migration):
dependencies = [
('projects', '0047_auto_20161014_2349'),
]
operations = [
migrations.AddField(
model_name='realty',
name='is_virtual',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='portfolio',
name='work_type',
field=models.IntegerField(choices=[(403, 'Проектирование777'), (87, 'Техническое сопровождение666')], default=1),
),
migrations.AlterField(
model_name='project',
name='term_type',
field=models.CharField(choices=[('day', 'день'), ('hour', 'час'), ('month', 'месяц'), ('project', 'проект')], default='day', max_length=20),
),
migrations.AlterField(
model_name='project',
name='work_type',
field=models.IntegerField(choices=[(403, 'Проектирование777'), (87, 'Техническое сопровождение666')], default=1),
),
migrations.AlterField(
model_name='realty',
name='building_classification',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='projects.BuildingClassfication'),
),
migrations.AlterField(
model_name='realty',
name='construction_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='realties', to='projects.ConstructionType'),
),
]

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-12-01 18:57
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0048_auto_20161201_2003'),
]
operations = [
migrations.AlterField(
model_name='realty',
name='is_virtual',
field=models.BooleanField(default=False, editable=False),
),
migrations.AlterField(
model_name='realty',
name='name',
field=models.CharField(blank=True, max_length=255),
),
]

@ -68,10 +68,12 @@ class ConstructionType(models.Model):
class Realty(models.Model): class Realty(models.Model):
building_classification = TreeForeignKey(BuildingClassfication, related_name='realties') building_classification = TreeForeignKey(BuildingClassfication, related_name='realties', null=True, blank=True)
construction_type = models.ForeignKey(ConstructionType, related_name='realties') construction_type = models.ForeignKey(ConstructionType, related_name='realties', null=True, blank=True)
location = TreeForeignKey('common.Location', related_name='realties', null=True, blank=True) location = TreeForeignKey('common.Location', related_name='realties', null=True, blank=True)
name = models.CharField(max_length=255) name = models.CharField(max_length=255, blank=True)
# Виртуальные объекты привязываются к Проектам, для которых Объект не создан явно
is_virtual = models.BooleanField(default=False, editable=False)
user = models.ForeignKey(User, related_name='realties') # Do we actually need this field? user = models.ForeignKey(User, related_name='realties') # Do we actually need this field?
def __str__(self): def __str__(self):
@ -97,21 +99,26 @@ class Project(models.Model, HitCountMixin):
('deleted', 'Удален'), ('deleted', 'Удален'),
) )
name = models.CharField(max_length=255)
text = models.TextField(blank=True)
customer = models.ForeignKey(User, related_name='customer_projects')
state = models.CharField(default='active', max_length=20, choices=STATES)
specialization = TreeForeignKey(Specialization, related_name='projects')
budget = models.DecimalField(max_digits=10, decimal_places=0) budget = models.DecimalField(max_digits=10, decimal_places=0)
budget_by_agreement = models.BooleanField(default=False) budget_by_agreement = models.BooleanField(default=False)
created = models.DateTimeField(default=timezone.now)
cro = models.BooleanField(default=False)
currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES) currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES)
customer = models.ForeignKey(User, related_name='customer_projects')
deal_type = models.CharField(max_length=20, default='secure_deal', choices=DEAL_TYPES) deal_type = models.CharField(max_length=20, default='secure_deal', choices=DEAL_TYPES)
name = models.CharField(max_length=255)
price_and_term_required = models.BooleanField(default=False) price_and_term_required = models.BooleanField(default=False)
realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects')
specialization = TreeForeignKey(Specialization, related_name='projects')
state = models.CharField(default='active', max_length=20, choices=STATES)
term = models.IntegerField(default=0) term = models.IntegerField(default=0)
term_type = models.CharField(max_length=20, choices=TERM_TYPES, default='hour') term_type = models.CharField(max_length=20, choices=TERM_TYPES, default='day')
text = models.TextField(blank=True)
realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects')
cro = models.BooleanField(default=False)
created = models.DateTimeField(default=timezone.now)
# FIXME: set deprecated http://djbook.ru/rel1.8/topics/migrations.html#considerations-when-removing-model-fields # FIXME: set deprecated http://djbook.ru/rel1.8/topics/migrations.html#considerations-when-removing-model-fields
work_type = models.IntegerField(default=1, choices=WORK_TYPES) work_type = models.IntegerField(default=1, choices=WORK_TYPES)

@ -0,0 +1,62 @@
.description {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4; /* number of lines to show */
line-height: 1.8em; /* fallback */
max-height: 7.2em; /* fallback */
}
textarea.description {
width: 100%;
min-height: 200px;
}
textarea.auto-hint {
color: darkgray;
}
.btn-plus {
/*width: 300px;*/
/*text-overflow: clip;*/
white-space: normal;
padding-left: 18%;
color: #FF0029;
/*height: 80%;*/
line-height: 1em;
font-family: Arial-MT-Regular;
font-size: 12pt;
}
.btn-plus:hover {
color: #FF0029;
}
.btn-plus {
background: url("../img/circle_cross.svg") no-repeat left;
background-position-x: 5px;
}
.upload-new.paper-clip {
padding-left: 45px;
padding-right: 5px;
background: url("../img/paper-clip_icon._g.png") no-repeat left;
background-size: 30px 30px;
width: auto;
}
.upload-new.paper-clip p {
font-size: 12pt;
width: auto;
text-align: right;
}
.documentsChat.mod {
width: auto;
float: none;
display: inline-block;
vertical-align: inherit;
padding: 0;
margin: 0;
}

@ -22,11 +22,6 @@ body {
margin-top: 30px; margin-top: 30px;
} }
.custom-check {
cursor: pointer;
display: inline-block;
width: 100%;
}
.header { .header {
font-size: 12pt; font-size: 12pt;
@ -38,6 +33,12 @@ body {
padding-top: 10px; padding-top: 10px;
} }
.custom-check {
cursor: pointer;
display: inline-block;
width: 100%;
}
.custom-check .checked { .custom-check .checked {
background: url("../img/checkbox_Check.png.png") no-repeat center; background: url("../img/checkbox_Check.png.png") no-repeat center;
background-size: 100% 51px; background-size: 100% 51px;

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="40"
height="40"
viewBox="0 0 39.999999 39.999999"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="circle_cross.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="-1.6481695"
inkscape:cy="84.391007"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="975"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
units="px" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1012.3622)">
<circle
style="fill:none;fill-opacity:1;stroke:#ff0029;stroke-width:1;stroke-opacity:0.94117647;stroke-miterlimit:4;stroke-dasharray:none"
id="path4136"
cx="20"
cy="1032.3622"
r="19.790106" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ff0029;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 20,1020.0647 0,24.595"
id="path4138"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4140"
d="m 32.297513,1032.3622 -24.5950211,0"
style="fill:none;fill-rule:evenodd;stroke:#ff0029;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

@ -0,0 +1,14 @@
$(function () {
let $area = $('#with-placeholder');
let placeholder = $area.prop("placeholder");
let changed = false;
$area.addClass("auto-hint");
$area.html(placeholder);
$area.on("click", function (e) {
// if (changed) return
console.log("click");
$(e.target).removeClass("auto-hit");
$(e.target).html("");
return true
})
});

@ -0,0 +1,411 @@
{% extends 'partials/base.html' %}
{% load i18n %}
{% block head_css %}
<style>
.-error, .errorlist {
color: red
}
</style>
{% endblock %}
{% block content %}
{% include 'partials/modals/project_work_type_suggestion.html' %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<div class="col-lg-12 allProjects">
<p class="titleScore">Новый заказ</p>
</div>
<form action="{% url 'projects:customer-project-create' %}" method="POST" enctype="multipart/form-data" novalidate
class="-spec-work-type-combo-container">
{% csrf_token %}
<input type="hidden" id="extraFields" name="extra_fields" value="">
<div class="chatBlock new-rass new-rass2 disTab">
<div class="col-lg-9">
<p class="new-pp new-pp3">Формирование заказа</p>
{% if form.non_field_errors %}
<div class="new-pp3" style="color: red; margin-top: 70px">{{ form.non_field_errors }}</div>
{% endif %}
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p class="titleResF1">Название заказа <span data-tooltip data-placement="{% tooltip_placement pk=4 %}"
title="{% tooltip pk=4 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.name.errors.as_text }}</span></p>
<input type="text" class="box-sizing" name="{{ form.name.html_name }}" value="{{ form.name.value }}">
</div>
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p class="titleResF1">Подробно опишите задание <span data-tooltip
data-placement="{% tooltip_placement pk=5 %}"
title="{% tooltip pk=5 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.text.errors.as_text }}</span></p>
<textarea name="{{ form.text.html_name }}" id="text-new"
style="margin-top:0;">{{ form.text.value }}</textarea>
</div>
</div>
<div class="col-lg-3 wrChat1">
<div class="messageBlock box-sizing disTab">
<p>Дополнительно</p>
</div>
<div id="fileUploadContainer" class="col-lg-12 documentsChat">
<div class="upload">
<p id="fileUploadAddBtn" style="margin: 0">+ добавить файл (до 100 файлов)</p>
</div>
<ul class="list-new-new">
<li class="file-upload-widget" style="display: none">
<input type="file" name="new_files" class="file-upload-input"
style="position: absolute; top: -1000px; left: -1000px">
<p class="file-upload-label"></p>
<div class="file-upload-remove-btn"></div>
</li>
</ul>
</div>
<p class="type-work">{% trans 'project_stage0' %} <span data-tooltip
data-placement="{% tooltip_placement pk=6 %}"
title="{% tooltip pk=6 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.work_type.errors.as_text }}</span></p>
<div class="mail-block type-work-inset -project-work-type-radios-container">
{% for id, text in form.work_type.field.choices %}
<div class="inset-mb">
<label>
<input
type="radio"
value="{{ id }}"
{% if form.work_type.value|int == id %}checked{% endif %}
name="{{ form.work_type.html_name }}">
{# <span></span>#}
</label>
<p>{{ text }}</p>
</div>
{% endfor %}
</div>
<div class="textAreaBlock2 box-sizing disTab">
<a href="#" onclick="return false" data-toggle="modal" data-target="#projectWorkTypeSuggestionModal"
class="new-link new-lw">+ Добавить раздел</a>
</div>
</div>
</div>
<div class="col-lg-12 new-filter">
<div class="filter clearfix">
<div class="polsF1 disTab">
<div class="col-lg-3 -single-spec-select">
<div class="-bold">{% trans 'project_stage1' %} <span data-tooltip
data-placement="{% tooltip_placement pk=7 %}"
data-placement="{% tooltip_placement pk=7 %}"
title="{% tooltip pk=7 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.specialization.errors.as_text }}</span></div>
<input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%">
</div>
<div class="col-lg-3 -single-spec-select">
<div class="-bold"><span class="-dynamic-label">{% trans 'project_stage2' %}</span></div>
<input type="hidden" class="-spec-select -spec-select-level-2" style="width: 100%">
</div>
<div class="col-lg-3 -single-spec-select">
<div class="-bold">{% trans 'project_stage3' %}</div>
<input type="hidden" class="-spec-select -spec-select-level-3" style="width: 100%">
</div>
<div class="col-lg-3 -single-spec-select">
<div class="-bold">{% trans 'project_stage4' %}</div>
<input type="hidden" class="-spec-select -spec-select-level-4" style="width: 100%">
</div>
<input type="hidden" name="{{ form.specialization.html_name }}" value="{{ form.specialization.value }}"
class="-chosen-spec-id">
</div>
<div class="titleF1 titleF2 disTab">
<div class="col-lg-12">Бюджет <span data-tooltip data-placement="{% tooltip_placement pk=8 %}"
title="{% tooltip pk=8 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.budget.errors.as_text }}</span></div>
<!--<div class="col-lg-8"></div>-->
</div>
<div class="searchF1 polsF1 polsFF">
<div class="col-lg-4">
<input type="text" class="box-sizing surr" name="{{ form.budget.html_name }}"
value="{{ form.budget.value }}">
{{ form.currency }}
</div>
<div class="col-lg-3">
{{ form.term_type }}
</div>
<div class="col-lg-5 dog-new">
<label>
<input
type="checkbox"
{% if form.budget_by_agreement.value %}checked{% endif %}
name="{{ form.budget_by_agreement.html_name }}">
<span></span>
</label>
<p>или по договоренности <span data-tooltip data-placement="{% tooltip_placement pk=9 %}"
title="{% tooltip pk=9 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span></p>
</div>
</div>
<div class="searchF1 polsF1 polsFF make-new">
<label>
<input
type="checkbox"
{% if form.price_and_term_required.value %}checked{% endif %}
name="{{ form.price_and_term_required.html_name }}">
<span></span>
</label>
<p>Сделать для исполнителей обязательным для заполнения поля цена и срок</p>
</div>
<div class="titleF1 titleF2 disTab">
<div class="col-lg-12">Способ оплаты <span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.deal_type.errors.as_text }}</span>
</div>
</div>
<div class="searchF1 polsF1 polsFF radio-afer">
<div class="col-lg-6">
<label>
<input
type="radio"
name="{{ form.deal_type.html_name }}"
{% if form.deal_type.value == 'secure_deal' %}checked{% endif %}
value="secure_deal">
{# <span></span>#}
</label>
<p class="text-afer">
Безопасная сделка (с резервированием бюджета)
</p>
<p class="des-afer">
{% tooltip pk=10 as tooltip10 %}{{ tooltip10|linebreaksbr }}
</p>
</div>
<div class="col-lg-6">
<label>
<input
type="radio"
name="{{ form.deal_type.html_name }}"
{% if form.deal_type.value == 'direct_payment' %}checked{% endif %}
value="direct_payment">
{# <span></span>#}
</label>
<p class="text-afer">
Прямая оплата Исполнителю на его кошелек/счет
</p>
<p class="des-afer">
{% tooltip pk=11 as tooltip11 %}{{ tooltip11|linebreaksbr }}
</p>
</div>
</div>
<div class="resSearchF1">
<div class="col-lg-3">
<p class="titleResF1">Расширенный поиск</p>
<button data-tooltip data-placement="{% tooltip_placement pk=12 %}" title="{% tooltip pk=12 %}"
class="resButtonF1">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</button>
</div>
<div class="col-lg-9">
<div class="borderS1"></div>
</div>
</div>
<div class="slideRes disTab activeSlide">
<div class="titleF1 disTab">
<div class="col-lg-3">Выбор объекта <span data-tooltip data-placement="{% tooltip_placement pk=13 %}"
title="{% tooltip pk=13 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span><br><span
id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.realty.errors.as_text }}</span></div>
<div class="col-lg-3">Наименование <span data-tooltip data-placement="{% tooltip_placement pk=14 %}"
title="{% tooltip pk=14 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span><br><span
id="{% random_ident %}" class="-validation-error"
style="color: red">{{ realty_form.name.errors.as_text }}</span></div>
<div class="col-lg-3">Классификация здания <span data-tooltip
data-placement="{% tooltip_placement pk=15 %}"
title="{% tooltip pk=15 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span><br><span
id="{% random_ident %}" class="-validation-error"
style="color: red">{{ realty_form.building_classification.errors.as_text }}</span></div>
<div class="col-lg-3">Вид строительства <span data-tooltip
data-placement="{% tooltip_placement pk=16 %}"
title="{% tooltip pk=16 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span><br><span
id="{% random_ident %}" class="-validation-error"
style="color: red">{{ realty_form.construction_type.errors.as_text }}</span></div>
</div>
<div class="polsF1 polsF2 disTab">
<div class="col-lg-3">
<select
class="selectpicker"
id="realtyId"
name="{{ form.realty.html_name }}">
<option value="" {% if not form.realty.value %}selected="selected"{% endif %}>Создать новый</option>
{% for r in form.realty.field.queryset %}
<option value="{{ r.pk }}"
{% if form.realty.value|int == r.pk %}selected="selected"{% endif %}>{{ r.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-3">
<input
type="text"
id="realtyName"
name="{{ realty_form.name.html_name }}"
class="box-sizing surr surr2"
value="{{ realty_form.name.value }}">
</div>
<div class="col-lg-3">
{{ realty_form.building_classification }}
{# <select#}
{# id="realtyBuildingClassificationId"#}
{# #}
{# name="{{ realty_form.building_classification.html_name }}">#}
{# {% for c in realty_form.building_classification.field.queryset %}#}
{# <option value="{{ c.pk }}" {% if realty_form.building_classification.value|int == c.pk %}selected="selected"{% endif %}>{{ c.name }}</option>#}
{# {% endfor %}#}
{# </select>#}
</div>
<div class="col-lg-3">
<select
id="realtyConstructionTypeId"
class="selectpicker"
name="{{ realty_form.construction_type.html_name }}">
{% for t in realty_form.construction_type.field.queryset %}
<option value="{{ t.pk }}"
{% if realty_form.construction_type.value|int == t.pk %}selected="selected"{% endif %}>{{ t.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="titleF1 disTab">
<div class="col-lg-12">Местоположение <span data-tooltip data-placement="{% tooltip_placement pk=18 %}"
title="{% tooltip pk=18 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ realty_form.location.errors.as_text }}</span></div>
</div>
<div class="polsF1 polsF2 disTab">
<div>
<div class="col-lg-3">
<input type="hidden" class="-location-select -location-select-country" style="width: 100%">
</div>
<div class="col-lg-3">
<input type="hidden" class="-location-select -location-select-region" style="width: 100%">
</div>
<div class="col-lg-3">
<input type="hidden" class="-location-select -location-select-city" style="width: 100%">
</div>
</div>
<input type="hidden" id="chosenLocationId" name="{{ realty_form.location.html_name }}"
value="{{ realty_form.location.value }}">
<div class="col-lg-3 make-new">
<label>{{ form.cro }}<span></span></label>
<p>Требуется допуск (СРО) <span data-tooltip data-placement="{% tooltip_placement pk=17 %}"
title="{% tooltip pk=17 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span></p>
</div>
</div>
</div>
<div class="searchF1 polsF1 polsFF links-filter">
<input class="btn-submit-link" type="submit" value="Разместить проект">
</div>
</div>
</div>
</form>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}
{% block js_block %}
<script>
// Project work type suggestion modal ---------------------------------
;
(function () {
var $modal = $('#projectWorkTypeSuggestionModal')
var $form = $modal.find('.-project-work-type-suggestion-form').first()
var workTypeSuggestionUrl = '/projects/suggest-work-type/'
$modal.find('.-action-button').first().on('click', function ($evt) {
$.post(workTypeSuggestionUrl, $form.serialize())
.then(function (res) {
if (res.status === 'success') {
$form.trigger('reset')
$('.-error').text('')
$modal.modal('hide')
$.jGrowl('Предложение успешно отправлено')
} else if (res.status === 'error') {
_.flow(
_.toPairs,
_.each(function (pair) {
var cssSelector = pair[0]
var errors = pair[1]
$(cssSelector).first().text(_.join(' ', errors))
})
)(res.form_errors)
}
})
})
}())
// Scroll to first form validation error ---------------------------
;
(function () {
var hash = $('.-validation-error').filter(function (i, el) {
return $(el).text()
}).first().attr('id')
if (hash)
window.location.hash = hash
}())
</script>
{% endblock %}

@ -1,410 +1,383 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% load i18n %} {% load i18n %}
{% load staticfiles %}
{% block head_css %} {% load sass_tags %}
<style> {% block old_css %}
.-error, .errorlist {
color: red
}
</style>
{% endblock %} {% endblock %}
{% block head_css %}
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
<link rel='stylesheet' href='{% sass_src "sass/main.sass" %}'>
<link rel='stylesheet' href='{% sass_src "sass/components/custom-components.sass" %}'>
<link rel='stylesheet' href='{% sass_src "lib/proekton-components/sass/components.sass" %}'>
{% endblock %}
{% block content %} {% block content %}
{% include 'partials/modals/project_work_type_suggestion.html' %} {% include 'partials/modals/project_work_type_suggestion.html' %}
{% include 'partials/header.html' %} {% include 'partials/header.html' %}
<div class="container main-scope">
<div class="container mainScore"> <div class="row title-scope">
<div class="row"> <div class="col-lg-12">
<div class="col-lg-12 allProjects"> {# <div class="title-scope">#}
<p class="titleScore">Новый заказ</p> <h1>Новый заказ</h1>
</div> {# </div>#}
<form action="{% url 'projects:customer-project-create' %}" method="POST" enctype="multipart/form-data" novalidate
class="-spec-work-type-combo-container">
{% csrf_token %}
<input type="hidden" id="extraFields" name="extra_fields" value="">
<div class="chatBlock new-rass new-rass2 disTab">
<div class="col-lg-9">
<p class="new-pp new-pp3">Формирование заказа</p>
{% if form.non_field_errors %}
<div class="new-pp3" style="color: red; margin-top: 70px">{{ form.non_field_errors }}</div>
{% endif %}
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p class="titleResF1">Название заказа <span data-tooltip data-placement="{% tooltip_placement pk=4 %}"
title="{% tooltip pk=4 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.name.errors.as_text }}</span></p>
<input type="text" class="box-sizing" name="{{ form.name.html_name }}" value="{{ form.name.value }}">
</div>
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p class="titleResF1">Подробно опишите задание <span data-tooltip
data-placement="{% tooltip_placement pk=5 %}"
title="{% tooltip pk=5 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.text.errors.as_text }}</span></p>
<textarea name="{{ form.text.html_name }}" id="text-new"
style="margin-top:0;">{{ form.text.value }}</textarea>
</div>
</div>
<div class="col-lg-3 wrChat1">
<div class="messageBlock box-sizing disTab">
<p>Дополнительно</p>
</div>
<div id="fileUploadContainer" class="col-lg-12 documentsChat">
<div class="upload">
<p id="fileUploadAddBtn" style="margin: 0">+ добавить файл (до 100 файлов)</p>
</div>
<ul class="list-new-new">
<li class="file-upload-widget" style="display: none">
<input type="file" name="new_files" class="file-upload-input"
style="position: absolute; top: -1000px; left: -1000px">
<p class="file-upload-label"></p>
<div class="file-upload-remove-btn"></div>
</li>
</ul>
</div>
<p class="type-work">{% trans 'project_stage0' %} <span data-tooltip
data-placement="{% tooltip_placement pk=6 %}"
title="{% tooltip pk=6 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span>
<span id="{% random_ident %}" class="-validation-error"
style="color: red">{{ form.work_type.errors.as_text }}</span></p>
<div class="mail-block type-work-inset -project-work-type-radios-container">
{% for id, text in form.work_type.field.choices %}
<div class="inset-mb">
<label>
<input
type="radio"
value="{{ id }}"
{% if form.work_type.value|int == id %}checked{% endif %}
name="{{ form.work_type.html_name }}">
{# <span></span>#}
</label>
<p>{{ text }}</p>
</div>
{% endfor %}
</div>
<div class="textAreaBlock2 box-sizing disTab">
<a href="#" onclick="return false" data-toggle="modal" data-target="#projectWorkTypeSuggestionModal"
class="new-link new-lw">+ Добавить раздел</a>
</div> </div>
</div>
</div> </div>
<div class="col-lg-12 new-filter"> <div class="row main-content">
<div class="filter clearfix"> <div class="col-lg-12">
<div class="polsF1 disTab"> <form action="{% url 'projects:customer-project-create' %}" method="POST"
<div class="col-lg-3 -single-spec-select"> enctype="multipart/form-data" novalidate>
<div class="-bold">{% trans 'project_stage1' %} <span data-tooltip {% csrf_token %}
data-placement="{% tooltip_placement pk=7 %}" <div class="row">
title="{% tooltip pk=7 %}" <div class="col-lg-9">
class="-green-glyphicon glyphicon glyphicon-question-sign"></span> <div class="simple-field">
<span id="{% random_ident %}" class="-validation-error" <div class="header">Название заказа</div>
style="color: red">{{ form.specialization.errors.as_text }}</span></div> <i class="fa fa-question-circle-o" aria-hidden="true"></i>
<input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%"> <span class="required">Обязательно</span>
</div> <input value="{{ form.name.value }}" name="{{ form.name.html_name }}"
class="simple-input italic"
<div class="col-lg-3 -single-spec-select"> placeholder="Пример: Дизайн квартиры, Армирование фундамента, Конструкции перекрытия и т.д."
<div class="-bold"><span class="-dynamic-label">{% trans 'project_stage2' %}</span></div> autocomplete="off"
<input type="hidden" class="-spec-select -spec-select-level-2" style="width: 100%"> required>
</div> </div>
</div>
<div class="col-lg-3 -single-spec-select"> <div class="col-lg-3">
<div class="-bold">{% trans 'project_stage3' %}</div> <div id="sb-realty-top"></div>
<input type="hidden" class="-spec-select -spec-select-level-3" style="width: 100%"> </div>
</div> </div>
<div class="row vertical-child mod-align-bottom">
<div class="col-lg-3 -single-spec-select"> <div class="col-lg-9">
<div class="-bold">{% trans 'project_stage4' %}</div> <div class="" id="select-box-1"></div>
<input type="hidden" class="-spec-select -spec-select-level-4" style="width: 100%"> </div>
</div> <div class="col-lg-3">
<div href="#" onclick="return false" data-toggle="modal"
<input type="hidden" name="{{ form.specialization.html_name }}" value="{{ form.specialization.value }}" data-target="#projectWorkTypeSuggestionModal"
class="-chosen-spec-id"> class="btn btn-simple btn-plus">Нет нужной специальности хочу добавить
</div> </div>
<div class="titleF1 titleF2 disTab"> </div>
<div class="col-lg-12">Бюджет <span data-tooltip data-placement="{% tooltip_placement pk=8 %}" </div>
title="{% tooltip pk=8 %}" <div class="row">
class="-green-glyphicon glyphicon glyphicon-question-sign"></span> <div class="col-lg-3">
<span id="{% random_ident %}" class="-validation-error" <div class="vertical-child" id="select-box-2">
style="color: red">{{ form.budget.errors.as_text }}</span></div> </div>
<!--<div class="col-lg-8"></div>--> </div>
</div> <div class="col-lg-3">
<div class="searchF1 polsF1 polsFF"> <div class="vertical-child" id="select-box-3">
<div class="col-lg-4"> </div>
<input type="text" class="box-sizing surr" name="{{ form.budget.html_name }}" </div>
value="{{ form.budget.value }}"> <div class="col-lg-3">
{{ form.currency }} <div class="vertical-child" id="select-box-4">
</div> </div>
<div class="col-lg-3"> </div>
{{ form.term_type }} <div class="col-lg-3">
</div> <div class="vertical-child" id="select-box-5">
<div class="col-lg-5 dog-new"> </div>
<label> </div>
<input </div>
type="checkbox" <div class="row" style="display: none">
{% if form.budget_by_agreement.value %}checked{% endif %} <div class="col-lg-12">
name="{{ form.budget_by_agreement.html_name }}"> <div class="selected-container horizontal" id="selected-spec">
<input type="hidden" name="{{ form.specialization.html_name }}"
<span></span> value="{{ form.specialization.value }}">
</label> </div>
</div>
<p>или по договоренности <span data-tooltip data-placement="{% tooltip_placement pk=9 %}" </div>
title="{% tooltip pk=9 %}" <div style="margin-top: 45px" class="row">
class="-green-glyphicon glyphicon glyphicon-question-sign"></span></p> <div class="col-lg-12">
</div> <div class="simple-field">
</div> <div class="header">Подобно опишите задание для /
<div class="searchF1 polsF1 polsFF make-new"> <span class="select-text" id="spec-value"></span>
<label> </div>
<input <i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
type="checkbox" <span class="required">Обязательно</span>
{% if form.price_and_term_required.value %}checked{% endif %} <textarea class="description" rows="6" placeholder=
name="{{ form.price_and_term_required.html_name }}"> " Пример №1
Разработать архиьектурные решения для жилого дома на основании эскизной проработки
<span></span>
</label>
Пример №2
<p>Сделать для исполнителей обязательным для заполнения поля цена и срок</p> Разработать проект по електроснабжению и освещению гаража"></textarea>
</div>
<div class="titleF1 titleF2 disTab"> </div>
<div class="col-lg-12">Способ оплаты <span id="{% random_ident %}" class="-validation-error" <div class="documentsChat mod" id="fileUploadContainer">
style="color: red">{{ form.deal_type.errors.as_text }}</span> <div style="display: inline-block;vertical-align: middle;">
</div> <div style="display: inline-block;vertical-align: inherit;"
</div> class="upload-new paper-clip">
<div class="searchF1 polsF1 polsFF radio-afer"> <p id="fileUploadAddBtn" style="margin: 0">прикрепить файл</p>
<div class="col-lg-6"> </div>
<label> <span style="display: inline-block;vertical-align: inherit;">ДО 100 ФАЙЛОВ</span>
<input </div>
type="radio"
name="{{ form.deal_type.html_name }}" <ul style="float: none" class="list-new-new">
{% if form.deal_type.value == 'secure_deal' %}checked{% endif %} <li class="file-upload-widget" style="display: none">
value="secure_deal"> <input type="file" name="new_files" class="file-upload-input"
style="position: absolute; top: -1000px; left: -1000px">
{# <span></span>#} <span class="file-upload-label"></span>
</label> <div class="file-upload-remove-btn"></div>
</li>
<p class="text-afer"> </ul>
Безопасная сделка (с резервированием бюджета) </div>
</p>
<p class="des-afer"> </div>
{% tooltip pk=10 as tooltip10 %}{{ tooltip10|linebreaksbr }} </div>
</p>
</div> <div class="row">
<div class="col-lg-12">
<div class="col-lg-6"> <div class="separator">
<label> <span class="header">Показать расширенные настройки</span>
<input <button class="resButton">
type="radio" <span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
name="{{ form.deal_type.html_name }}" </button>
{% if form.deal_type.value == 'direct_payment' %}checked{% endif %} <div class="border"></div>
value="direct_payment"> </div>
</div>
{# <span></span>#} </div>
</label>
<div class="slide">
<p class="text-afer"> <div style="padding-bottom: 15px" class="row">
Прямая оплата Исполнителю на его кошелек/счет <div class="col-lg-12">
</p> <div class="header">Способ оплаты</div>
</div>
<p class="des-afer"> </div>
{% tooltip pk=11 as tooltip11 %}{{ tooltip11|linebreaksbr }} <div class="row">
</p> <div class="col-lg-6">
</div> <label class="mod-align-center header">
</div> <input name="{{ form.deal_type.html_name }}" class="custom-radio" type="radio"
{% if form.deal_type.value == 'secure_deal' %}checked{% endif %}
value="secure_deal">&nbsp;
<div class="resSearchF1"> Безопасная сделка (с
<div class="col-lg-3"> резервированием бюджета)
<p class="titleResF1">Расширенный поиск</p> </label>
<button data-tooltip data-placement="{% tooltip_placement pk=12 %}" title="{% tooltip pk=12 %}"
class="resButtonF1"> <div class="description">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span> <span class="teaser">
</button> Безопасная сделка – это сервис, с помощью которого:<br/>
</div> -Заказчики - полностью избавляются от всех финансовых рисков при сотрудничестве с
<div class="col-lg-9"> Исполнителями;<br/>
<div class="borderS1"></div> -Исполнители - получают гарантию своевременной оплаты своей работы (выполненной по
</div> заданию
</div> точно в срок).
</span>
<div class="slideRes disTab activeSlide"> <span class="complete">
<div class="titleF1 disTab"> <p>
<div class="col-lg-3">Выбор объекта <span data-tooltip data-placement="{% tooltip_placement pk=13 %}" Это сервис и тип оплаты в заказах, в котором сумма оплаты резервируется
title="{% tooltip pk=13 %}" (перечисляется
class="-green-glyphicon glyphicon glyphicon-question-sign"></span><br><span на
id="{% random_ident %}" class="-validation-error" сайт) Заказчиком до начала работы и выплачивается Исполнителю только после
style="color: red">{{ form.realty.errors.as_text }}</span></div> успешного
<div class="col-lg-3">Наименование <span data-tooltip data-placement="{% tooltip_placement pk=14 %}" выполнения задания. А в случае некачественного и/или несвоевременного выполнения
title="{% tooltip pk=14 %}"
class="-green-glyphicon glyphicon glyphicon-question-sign"></span><br><span возвращается Заказчику.
id="{% random_ident %}" class="-validation-error" </p>
style="color: red">{{ realty_form.name.errors.as_text }}</span></div> <p>
<div class="col-lg-3">Классификация здания <span data-tooltip Сайт выступает в Безопасных сделках хранителем и гарантом сохранности средств. А
data-placement="{% tooltip_placement pk=15 %}" в
title="{% tooltip pk=15 %}" случае
class="-green-glyphicon glyphicon glyphicon-question-sign"></span><br><span возникновения конфликтов в заказе - Арбитром, независимой третьей Стороной,
id="{% random_ident %}" class="-validation-error" помогающей
style="color: red">{{ realty_form.building_classification.errors.as_text }}</span></div> решить проблемы при сотрудничестве и справедливо распорядиться зарезервированной
<div class="col-lg-3">Вид строительства <span data-tooltip суммой:<br>
data-placement="{% tooltip_placement pk=16 %}" -выплатить ее Исполнителю, если работа выполнена своевременно и в полном
title="{% tooltip pk=16 %}" соответствии с
class="-green-glyphicon glyphicon glyphicon-question-sign"></span><br><span заданием;<br>
id="{% random_ident %}" class="-validation-error" -вернуть Заказчику, если работа не выполнена или нарушены сроки выполнения;<br>
style="color: red">{{ realty_form.construction_type.errors.as_text }}</span></div> -разделить сумму между Заказчиком и Исполнителем, если работа выполнена частично
</div> и
без нарушения сроков.
<div class="polsF1 polsF2 disTab"> </p>
<div class="col-lg-3"> </span>
<select <span class="more"></span>
class="selectpicker" </div>
id="realtyId" </div>
name="{{ form.realty.html_name }}"> <div class="col-lg-6">
<option value="" {% if not form.realty.value %}selected="selected"{% endif %}>Создать новый</option> <label class="mod-align-center header">
<input name="{{ form.deal_type.html_name }}" class="custom-radio" type="radio"
{% for r in form.realty.field.queryset %} {% if form.deal_type.value == 'direct_payment' %}checked{% endif %}
<option value="{{ r.pk }}" value="direct_payment">&nbsp;
{% if form.realty.value|int == r.pk %}selected="selected"{% endif %}>{{ r.name }}</option> Прямая оплата Исполнителю на
{% endfor %} его
</select> кошелек/счет
</div> </label>
<div class="col-lg-3"> <div class="description">
<input <p>
type="text" Прямая оплата - это оплата без помощи сайта. Оплаты заказов происходят напрямую
id="realtyName" исполнителю
name="{{ realty_form.name.html_name }}" на его личный счет или кошелек.
class="box-sizing surr surr2" </p>
value="{{ realty_form.name.value }}"> <p>
</div> В данном случае сайт не выступает гарантом сохранности средств и не является
<div class="col-lg-3"> Арбитром
{{ realty_form.building_classification }} при
{# <select#} спорных вопросах.
{# id="realtyBuildingClassificationId"#} </p>
{# #} </div>
{# name="{{ realty_form.building_classification.html_name }}">#} </div>
{# {% for c in realty_form.building_classification.field.queryset %}#} </div>
{# <option value="{{ c.pk }}" {% if realty_form.building_classification.value|int == c.pk %}selected="selected"{% endif %}>{{ c.name }}</option>#} <div style="margin-top: 40px" class="row mod-align-bottom">
{# {% endfor %}#} <div class="col-lg-3">
{# </select>#} <div class="header ">Бюджет
</div> <i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
<div class="col-lg-3"> </div>
<select <input name="{{ form.budget.html_name }}" class="simple-input icon-rub js-number-format"
id="realtyConstructionTypeId" placeholder="Введите сумму"
class="selectpicker" value="{{ form.budget.value }}"
name="{{ realty_form.construction_type.html_name }}"> autocomplete="off">
{% for t in realty_form.construction_type.field.queryset %} </div>
<option value="{{ t.pk }}" <div class="col-lg-3">
{% if realty_form.construction_type.value|int == t.pk %}selected="selected"{% endif %}>{{ t.name }}</option> <div class="header">Срок
{% endfor %} <i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</select> </div>
</div> <input name="{{ form.term.html_name }}" class="simple-input icon-days js-number-format"
</div> placeholder="Введите срок"
<div class="titleF1 disTab"> value="{{ form.term.value }}"
<div class="col-lg-12">Местоположение <span data-tooltip data-placement="{% tooltip_placement pk=18 %}" autocomplete="off">
title="{% tooltip pk=18 %}" </div>
class="-green-glyphicon glyphicon glyphicon-question-sign"></span> <div class="col-lg-4">
<span id="{% random_ident %}" class="-validation-error" <div class="row">
style="color: red">{{ realty_form.location.errors.as_text }}</span></div> <div class="col-lg-1">
</div> <input name="{{ form.price_and_term_required.html_name }}" id="safe"
<div class="polsF1 polsF2 disTab"> class="custom-checkbox" type="checkbox"
<div> {% if form.price_and_term_required.value %}checked{% endif %}>
<div class="col-lg-3"> </div>
<input type="hidden" class="-location-select -location-select-country" style="width: 100%"> <div class="col-lg-11">
</div> <label for="safe" style="font-weight: normal" class="">
Сделать для исполнителей обязательным для заполнения поля цена и срок
<div class="col-lg-3"> </label>
<input type="hidden" class="-location-select -location-select-region" style="width: 100%"> </div>
</div> </div>
</div>
<div class="col-lg-3"> <div class="col-lg-2">
<input type="hidden" class="-location-select -location-select-city" style="width: 100%"> <div class="row">
</div> <div class="col-lg-2">
</div> <input name="{{ form.budget_by_agreement.html_name }}" id="by_agreement"
class="custom-checkbox" type="checkbox"
<input type="hidden" id="chosenLocationId" name="{{ realty_form.location.html_name }}" {% if form.budget_by_agreement.value %}checked{% endif %}>
value="{{ realty_form.location.value }}"> </div>
<div class="col-lg-10">
<div class="col-lg-3 make-new"> <label for="by_agreement" style="font-weight: normal" class="">
<label>{{ form.cro }}<span></span></label> Бюджет и срок по договоренности
<p>Требуется допуск (СРО) <span data-tooltip data-placement="{% tooltip_placement pk=17 %}" </label>
title="{% tooltip pk=17 %}" </div>
class="-green-glyphicon glyphicon glyphicon-question-sign"></span></p> </div>
</div> </div>
</div> </div>
</div> {# <div class="row">#}
{# <div class="col-lg-12">#}
{# <div class="separator">#}
<div class="searchF1 polsF1 polsFF links-filter"> {# <div class="border"></div>#}
<input class="btn-submit-link" type="submit" value="Разместить проект"> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
<!-- bottom block -->
<div class="row logical-block">
<div class="col-lg-12">
<div class="row">
<div class="col-lg-12">
<label class="header mod-align-center">
<input id="checkbox-sb-realty" class="custom-checkbox" type="checkbox">
&nbsp; Создать/выбрать объект, прикрепить заказ в объект &nbsp;
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</label>
</div>
</div>
<div class="row mod-align-bottom">
<div class="col-lg-6">
{# placeholder="Создайте/Выберите объект"#}
<div id="sb-realty"></div>
</div>
<div class="col-lg-6">
<div class="selected-container horizontal" id="selected-realty">
<input class="-id" type="hidden" name="{{ form.realty.html_name }}"
value="{{ form.realty.value }}">
<input class="-name" type="hidden" name="new_realty_name" value="">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="sb-building-classification">
</div>
<div class="vertical-child" id="sb-building-sub-classification">
</div>
<div class="selected-container" id="selected-building-classification">
<input type="hidden"
name="{{ realty_form.building_classification.html_name }}"
value="{{ realty_form.building_classification.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-construction-type">
</div>
<div class="selected-container" id="selected-construction-type">
<input type="hidden"
name="{{ realty_form.construction_type.html_name }}"
value="{{ realty_form.construction_type.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-location-1"></div>
<div class="vertical-child" id="sb-location-2"></div>
<div class="vertical-child" id="sb-location-3"></div>
<div class="selected-container" id="selected-location">
<input type="hidden"
name="{{ realty_form.location.html_name }}"
value="{{ realty_form.location.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="select-box-header vertical-child">
<span style="width: 180px" class="header">Требуется допуск (СРО)</span>
<i class="fa fa-question-circle-o" aria-hidden="true"
title="bla-bla-bla..."></i>
</div>
<div class="custom-check">
<div class="checked"></div>
<div style="display: none" class="not-checked"></div>
<input name="{{ form.cro.html_name }}" type="checkbox" hidden
{% if form.cro.value %} checked{% endif %}>
</div>
</div>
</div> <!-- //bottom block -->
</div>
</div>
<div class="row top-line">
<div class="col-lg-3" style="text-align: center">
<div class="header">&nbsp;</div>
<input style="width: 100%" type="submit" class="btn btn-simple"
value="РАЗМЕСТИТЬ ЗАКАЗ">
</div>
<div class="col-lg-3 col-lg-offset-6" style="text-align: center">
<div class="header">&nbsp;</div>
<input style="width: 100%" type="button" class="btn btn-simple"
value="ПРЕДВАРИТЕЛЬНЫЙ ПРОСМОТР">
</div>
</div>
</div> <!-- slide -->
</form>
</div> <!-- content -->
</div> </div>
</form> {% include 'partials/footer.html' %}
{% include 'partials/footer.html' %}
</div> </div>
</div>
{% endblock %}
{% block js_block %}
<script>
// Project work type suggestion modal ---------------------------------
;
(function () {
var $modal = $('#projectWorkTypeSuggestionModal')
var $form = $modal.find('.-project-work-type-suggestion-form').first()
var workTypeSuggestionUrl = '/projects/suggest-work-type/'
$modal.find('.-action-button').first().on('click', function ($evt) {
$.post(workTypeSuggestionUrl, $form.serialize())
.then(function (res) {
if (res.status === 'success') {
$form.trigger('reset')
$('.-error').text('')
$modal.modal('hide')
$.jGrowl('Предложение успешно отправлено')
} else if (res.status === 'error') {
_.flow(
_.toPairs,
_.each(function (pair) {
var cssSelector = pair[0]
var errors = pair[1]
$(cssSelector).first().text(_.join(' ', errors))
})
)(res.form_errors)
}
})
})
}())
// Scroll to first form validation error ---------------------------
;
(function () {
var hash = $('.-validation-error').filter(function (i, el) {
return $(el).text()
}).first().attr('id')
if (hash)
window.location.hash = hash
}())
</script>
{% endblock %} {% endblock %}
{% block old_js %}
<script src='{% static "lib/jquery.fileupload/js/vendor/jquery.ui.widget.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.iframe-transport.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.fileupload.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.fileupload-process.js" %}'></script>
<script src='{% static "my-libs.js" %}'></script>
{% endblock %}
{% block js_block %}
<script src='{% static "js/bootstrap.min.js" %}'></script>
<script src='{% static "js/build/init_customer_project_create.js" %}'></script>
<script src='{% static "js/build/create_project.js" %}'></script>
<script src='{% static "js/jquery.mask.min.js" %}'></script>
<script>
$(function () {
$('.js-number-format').mask('0000000000');
})
</script>
{% endblock %}

@ -1,10 +1,12 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% load staticfiles %} {% load staticfiles %}
{% load sass_tags %}
{% block head_css %} {% block head_css %}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/fonts.css" %}'> {# <link rel='stylesheet' href='{% static "lib/proekton-components/css/fonts.css" %}'>#}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/selected-container.css" %}'> {# <link rel='stylesheet' href='{% static "lib/proekton-components/css/selected-container.css" %}'>#}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/editable-container.css" %}'> {# <link rel='stylesheet' href='{% static "lib/proekton-components/css/editable-container.css" %}'>#}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/select-box.css" %}'> {# <link rel='stylesheet' href='{% static "lib/proekton-components/css/select-box.css" %}'>#}
<link rel='stylesheet' href='{% sass_src "lib/proekton-components/sass/components.sass" %}'>
<link rel='stylesheet' href='{% static "css/project_filter.css" %}'>{# other #} <link rel='stylesheet' href='{% static "css/project_filter.css" %}'>{# other #}
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'> <link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
{% endblock %} {% endblock %}

@ -32,7 +32,8 @@ app_name = 'projects'
urlpatterns = [ urlpatterns = [
urls.url(r'^$', ProjectFilterView.as_view(), name='project-filter'), urls.url(r'^$', ProjectFilterView.as_view(), name='project-filter'),
urls.url(r'^create/$', CustomerProjectCreateView.as_view(), name='customer-project-create'), # urls.url(r'^create/$', CustomerProjectCreateView.as_view(), name='customer-project-create'),
urls.url(r'^create$', CustomerProjectCreateView.as_view(), name='customer-project-create'),
urls.url(r'^(?P<pk>\d+)/$', ProjectDetailWithAnswerView.as_view(), name='detail'), urls.url(r'^(?P<pk>\d+)/$', ProjectDetailWithAnswerView.as_view(), name='detail'),
urls.url(r'^(?P<pk>\d+)/edit/$', CustomerProjectEditView.as_view(), name='customer-project-edit'), urls.url(r'^(?P<pk>\d+)/edit/$', CustomerProjectEditView.as_view(), name='customer-project-edit'),
urls.url(r'^(?P<pk>\d+)/trash/$', CustomerProjectTrashView.as_view(), name='customer-project-trash'), urls.url(r'^(?P<pk>\d+)/trash/$', CustomerProjectTrashView.as_view(), name='customer-project-trash'),

@ -39,12 +39,14 @@ from .models import (
Project, Project,
ProjectFile, ProjectFile,
TERM_TYPE_MORPHS, TERM_TYPE_MORPHS,
Realty
) )
from .forms import ( from .forms import (
ContractorPortfolioTrashForm, ContractorPortfolioTrashForm,
CustomerProjectDeleteForm, CustomerProjectDeleteForm,
CustomerProjectEditForm, CustomerProjectEditForm,
CustomerProjectEditFormNew,
CustomerProjectRestoreForm, CustomerProjectRestoreForm,
CustomerProjectTrashForm, CustomerProjectTrashForm,
PortfolioEditForm, PortfolioEditForm,
@ -55,6 +57,7 @@ from .forms import (
ProjectFilterRealtyForm, ProjectFilterRealtyForm,
ProjectWorkTypeSuggestionForm, ProjectWorkTypeSuggestionForm,
RealtyForm, RealtyForm,
RealtyFormNew
) )
from specializations.models import Specialization from specializations.models import Specialization
@ -399,9 +402,91 @@ class ProjectFilterView(BaseMixin, View):
return render(request, 'partials/inc-projects-results.html', self.get_context(request.POST)) return render(request, 'partials/inc-projects-results.html', self.get_context(request.POST))
# class CustomerProjectCreateView(BaseMixin, View):
# form_class = CustomerProjectEditForm
# realty_form = RealtyForm
# work_type_suggestion_form = ProjectWorkTypeSuggestionForm
# template_name = 'customer_project_create.html'
#
# def dispatch(self, request, *args, **kwargs):
# if request.user.is_authenticated() and request.user.is_customer():
# return super().dispatch(request, *args, **kwargs)
# else:
# raise PermissionDenied
#
# def get(self, request, *args, **kwargs):
# context = self.get_context_data(**_.merge({}, request.GET, kwargs))
#
# form = self.form_class(request=request)
# realty_form = self.realty_form(request=request, prefix='realty_form')
# work_type_suggestion_form = self.work_type_suggestion_form(request=request, prefix='work_type_suggestion')
#
# context.update({
# 'form': form,
# 'realty_form': realty_form,
# 'work_type_suggestion_form': work_type_suggestion_form,
# })
#
# return render(request, self.template_name, context)
#
# def post(self, request, *args, **kwargs):
# form = self.form_class(request.POST,
# request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
#
# form.is_valid()
# realty = form.cleaned_data.get('realty')
#
# if realty:
# realty_form = self.realty_form(request.POST, instance=realty, request=request, prefix='realty_form')
# else:
# realty_form = self.realty_form(request.POST, request=request, prefix='realty_form')
#
# if form.is_valid() and realty_form.is_valid():
# project = form.save(commit=False)
# project.customer = request.user
# project.save()
# form.save_m2m()
#
# Order.objects.create(project=project, secure=project.deal_type == 'secure_deal')
#
# for file in request.FILES.getlist('new_files'):
# ProjectFile.objects.create(file=file, project=project)
#
# if realty:
# realty_form.save()
# else:
# realty = realty_form.save(commit=False)
# realty.user = request.user
# realty.save()
# realty_form.save_m2m()
#
# project.realty = realty # Connect a realty with a project
# project.save()
#
# messages.info(request, 'Проект успешно создан')
# redirect_to = reverse('projects:detail', kwargs={'pk': project.pk})
# return redirect(redirect_to)
# else:
# if form.errors:
# messages.info(request, (
# '<p>Произошла ошибка (form)</p>'
# '<pre>{form}</pre>'
# ).format(form=pformat(form.errors)))
#
# if realty_form and realty_form.errors:
# messages.info(request, (
# '<p>Произошла ошибка (realty_form)</p>'
# '<pre>{realty_form}</pre>'
# ).format(realty_form=pformat(realty_form.errors)))
#
# context = self.get_context_data(**kwargs)
# context.update({'form': form, 'realty_form': realty_form})
# return render(request, self.template_name, context)
class CustomerProjectCreateView(BaseMixin, View): class CustomerProjectCreateView(BaseMixin, View):
form_class = CustomerProjectEditForm form_class = CustomerProjectEditFormNew
realty_form = RealtyForm realty_form = RealtyFormNew
work_type_suggestion_form = ProjectWorkTypeSuggestionForm work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'customer_project_create.html' template_name = 'customer_project_create.html'
@ -427,8 +512,7 @@ class CustomerProjectCreateView(BaseMixin, View):
return render(request, self.template_name, context) return render(request, self.template_name, context)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, form = self.form_class(request.POST, request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
form.is_valid() form.is_valid()
realty = form.cleaned_data.get('realty') realty = form.cleaned_data.get('realty')
@ -454,6 +538,9 @@ class CustomerProjectCreateView(BaseMixin, View):
else: else:
realty = realty_form.save(commit=False) realty = realty_form.save(commit=False)
realty.user = request.user realty.user = request.user
if not request.POST.get('new_realty_name'):
realty.is_virtual = True
realty.name = request.POST.get('new_realty_name')
realty.save() realty.save()
realty_form.save_m2m() realty_form.save_m2m()

@ -0,0 +1,84 @@
backports-abc==0.4
beautifulsoup4==4.5.1
decorator==4.0.10
defusedxml==0.4.1
diff-match-patch==20121119
Django==1.9.7
django-activeurl==0.1.9
django-appconf==1.0.2
django-classy-tags==0.7.2
django-compress==1.0.1
django-compressor==2.0
django-cors-headers==1.3.1
django-debug-toolbar==1.4
django-environ==0.4.0
django-extensions==1.6.7
django-filter==0.13.0
django-fluent-pages==1.0.1
django-fluent-utils==1.3
django-guardian==1.4.4
django-hitcount==1.2.2
django-import-export==0.4.5
django-mathfilters==0.4.0
django-modelcluster==2.0
django-mptt==0.8.4
django-parler==1.6.5
django-password-reset==0.9
django-polymorphic==0.9.2
django-polymorphic-tree==1.2.5
django-recaptcha==1.0.5
django-registration-redux==1.4
django-sass-processor==0.5.2
django-slug-preview==1.0.1
django-tag-parser==3.0
django-taggit==0.18.3
django-tinymce==2.3.0
django-treebeard==4.0.1
django-wysiwyg==0.8.0
djangorestframework==3.3.3
djangorestframework-filters==0.8.0
fake-factory==0.5.7
future==0.15.2
gunicorn==19.6.0
html5lib==0.999999
ipython==5.1.0
ipython-genutils==0.1.0
jsonschema==2.5.1
libsass==0.11.2
lxml==3.6.4
Momoko==2.2.3
natsort==5.0.1
oauthlib==1.1.2
pexpect==4.2.1
pickleshare==0.7.4
Pillow==3.4.2
pkg-resources==0.0.0
prompt-toolkit==1.0.8
psycopg2==2.6.1
ptyprocess==0.5.1
pydash==3.4.3
Pygments==2.1.3
PyJWT==1.4.0
python-dateutil==2.5.3
python-social-auth==0.2.19
python3-openid==3.0.10
pytz==2016.6.1
rcssmin==1.0.6
redis==2.10.5
requests==2.10.0
requests-oauthlib==0.6.1
rest-framework-generic-relations==1.1.0
rjsmin==1.0.12
simplegeneric==0.8.1
six==1.10.0
sorl-thumbnail==12.3
sqlparse==0.1.19
tablib==0.11.2
tornado==4.3
tqdm==4.8.4
traitlets==4.3.1
Unidecode==0.4.19
wagtail==1.6
wcwidth==0.1.7
Werkzeug==0.11.10
Willow==0.3.1

@ -0,0 +1,24 @@
{% extends 'partials/base.html' %}
{% block old_css %}
{% endblock %}
{% block content %}
<section class="mainContainer">
{% include 'partials/header.html' %}
<div class="container-fluid">
<div class="row">
<p class="welcomeMain">{{ main_settings.heading }}</p>
</div>
</div>
<div class="container-fluid">
Main page text will be here...
</div>
</section>
{% endblock %}
{% block js_block %}
<script src='{% static "js/bootstrap.min.js" %}'></script>
{% endblock %}
{% block old_js %}
{% endblock %}

@ -2,143 +2,156 @@
{#{% load compress %}#} {#{% load compress %}#}
<html lang="ru"> <html lang="ru">
<head> <head>
<meta charset='utf-8'> <meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge, chrome=1'> <meta http-equiv='X-UA-Compatible' content='IE=edge, chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1'> <meta name='viewport' content='width=device-width, initial-scale=1'>
<!--<meta name='viewport' content='initial-scale=1.0, user-scalable=no, maximum-scale=1'>--> <!--<meta name='viewport' content='initial-scale=1.0, user-scalable=no, maximum-scale=1'>-->
{% block head %}{% endblock %} {% block head %}{% endblock %}
<title>PROEKTON</title> <title>PROEKTON</title>
{# {% compress css %}#} {# {% compress css %}#}
<link rel='stylesheet' href='{% static "css/reset.css" %}'> {% block old_css %}
<link rel='stylesheet' href='{% static "lib/jquery-ui/jquery-ui.css" %}'> <link rel='stylesheet' href='{% static "css/reset.css" %}'>
<link rel='stylesheet' href='{% static "css/bootstrap.css" %}'> <link rel='stylesheet' href='{% static "lib/jquery-ui/jquery-ui.css" %}'>
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'> <link rel='stylesheet' href='{% static "css/bootstrap.css" %}'>
<link rel='stylesheet' href='{% static "lib/bootstrap-select/css/bootstrap-select.css" %}'> <link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
<link rel='stylesheet' href='{% static "lib/select2/select2.css" %}'> <!-- Tmp --> <link rel='stylesheet' href='{% static "lib/bootstrap-select/css/bootstrap-select.css" %}'>
<link rel='stylesheet' href='{% static "css/swiper.min.css" %}'> <link rel='stylesheet' href='{% static "lib/select2/select2.css" %}'> <!-- Tmp -->
<link rel='stylesheet' href='{% static "lib/jquery.fileupload/css/jquery.fileupload.css" %}'> <link rel='stylesheet' href='{% static "css/swiper.min.css" %}'>
<link rel='stylesheet' href='{% static "js/magnific-popup.css" %}'> <link rel='stylesheet' href='{% static "lib/jquery.fileupload/css/jquery.fileupload.css" %}'>
<link rel="stylesheet" href='{% static "lib/jquery-jgrowl/jquery.jgrowl.min.css" %}'> <link rel='stylesheet' href='{% static "js/magnific-popup.css" %}'>
<link rel='stylesheet' href='{% static "css/main.css" %}'> <link rel="stylesheet" href='{% static "lib/jquery-jgrowl/jquery.jgrowl.min.css" %}'>
<link rel='stylesheet' href='{% static "css/extra.css" %}'> <!-- Our additional CSS --> <link rel='stylesheet' href='{% static "css/main.css" %}'>
<link rel='stylesheet' href='{% static "css/extra.css" %}'> <!-- Our additional CSS -->
{% endblock %}
{% block common_css %}
<link rel='stylesheet' href='{% static "css/bootstrap.css" %}'>
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
{% endblock %}
{% block head_css %} {% block head_css %}
{% endblock %} {% endblock %}
{% if TEMPLATE_DEBUG %} {% if TEMPLATE_DEBUG %}
<link rel='stylesheet' href='{% static "css/dev-colors.css" %}'> <!-- Dev-time only, temporary!!! --> <link rel='stylesheet' href='{% static "css/dev-colors.css" %}'> <!-- Dev-time only, temporary!!! -->
{% endif %} {% endif %}
<link rel="icon" href="{% static 'img/favicon.jpg' %}" type="image/x-icon"> <link rel="icon" href="{% static 'img/favicon.jpg' %}" type="image/x-icon">
<link rel="shortcut icon" href="{% static 'img/favicon50.jpg' %}" type="image/x-icon"> <link rel="shortcut icon" href="{% static 'img/favicon50.jpg' %}" type="image/x-icon">
<link rel="apple-touch-icon" href="{% static 'img/favicon128.jpg' %}" sizes="128x128"> <link rel="apple-touch-icon" href="{% static 'img/favicon128.jpg' %}" sizes="128x128">
<link rel="icon" type="image/png" href="{% static 'img/favicon50.jpg' %}" sizes="32x32"> <link rel="icon" type="image/png" href="{% static 'img/favicon50.jpg' %}" sizes="32x32">
<link rel="icon" type="image/png" href="{% static 'img/favicon18.jpg' %}" sizes="16x16"> <link rel="icon" type="image/png" href="{% static 'img/favicon18.jpg' %}" sizes="16x16">
{# {% endcompress %}#} {# {% endcompress %}#}
<meta name="keywords" content=""> <meta name="keywords" content="">
<meta name="description" content="_TEXT_"> <meta name="description" content="_TEXT_">
<meta name="yandex-verification" content="58d23691715ef942"> <meta name="yandex-verification" content="58d23691715ef942">
<link rel="canonical" href="_URL_"> <link rel="canonical" href="_URL_">
</head> </head>
<body> <body>
{% if messages %} {% if messages %}
{% for message in messages %} {% for message in messages %}
<div class="c" <div class="c"
style="position: relative; padding: 10px; margin-bottom: 6px; z-index: 100">{{ message|safe }}</div> style="position: relative; padding: 10px; margin-bottom: 6px; z-index: 100">{{ message|safe }}</div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if TEMPLATE_DEBUG %} {% if TEMPLATE_DEBUG %}
<div ondblclick="$(this).css('display', 'none')" <div ondblclick="$(this).css('display', 'none')"
style="position: absolute; left: 0; bottom: 0; padding: 6px; color: black; background-color: {% if request.user.is_contractor %}#BADA55{% else %}#C0FFEE{% endif %}; z-index: 50"> style="position: absolute; left: 0; bottom: 0; padding: 6px; color: black; background-color: {% if request.user.is_contractor %}#BADA55{% else %}#C0FFEE{% endif %}; z-index: 50">
{{ request.user }}<br> {{ request.user }}<br>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<b>PK:</b> {{ request.user.pk }}<br> <b>PK:</b> {{ request.user.pk }}<br>
<b>Groups:</b> {{ request.user.groups.all }} <b>Groups:</b> {{ request.user.groups.all }}
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
{% block content %}{% endblock %} {% block content %}{% endblock %}
{% block common_js %}
<script src='{% static "js/jquery-2.2.3.min.js" %}'></script>
{# <script src='{% static "js/bootstrap.min.js" %}'></script>#}
{% endblock %}
{#{% compress js %}#} {#{% compress js %}#}
{% block old_js %}
<script src='{% static "lib/lodash/lodash.js" %}'></script> <script src='{% static "lib/lodash/lodash.js" %}'></script>
<script src='{% static "lib/lodash/lodash.fp.js" %}'></script> <script src='{% static "lib/lodash/lodash.fp.js" %}'></script>
<script src='{% static "js/jquery-2.2.3.min.js" %}'></script> <script src='{% static "js/jquery-2.2.3.min.js" %}'></script>
<script src='{% static "lib/jquery-ui/jquery-ui.js" %}'></script> <script src='{% static "lib/jquery-ui/jquery-ui.js" %}'></script>
<script src='{% static "lib/jquery-ui/i18n/datepicker-ru.js" %}'></script> <!-- jQueryUI Datepicker i18n --> <script src='{% static "lib/jquery-ui/i18n/datepicker-ru.js" %}'></script> <!-- jQueryUI Datepicker i18n -->
<script src='{% static "js/bootstrap.min.js" %}'></script> <script src='{% static "js/bootstrap.min.js" %}'></script>
<script src='{% static "lib/bootstrap-select/js/bootstrap-select.js" %}'></script> <script src='{% static "lib/bootstrap-select/js/bootstrap-select.js" %}'></script>
<script src='{% static "lib/select2/select2.js" %}'></script> <script src='{% static "lib/select2/select2.js" %}'></script>
<script src='{% static "lib/urijs/URI.min.js" %}'></script> <script src='{% static "lib/urijs/URI.min.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/vendor/jquery.ui.widget.js" %}'></script> <script src='{% static "lib/jquery.fileupload/js/vendor/jquery.ui.widget.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.iframe-transport.js" %}'></script> <script src='{% static "lib/jquery.fileupload/js/jquery.iframe-transport.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.fileupload.js" %}'></script> <script src='{% static "lib/jquery.fileupload/js/jquery.fileupload.js" %}'></script>
<script src='{% static "lib/jquery.fileupload/js/jquery.fileupload-process.js" %}'></script> <script src='{% static "lib/jquery.fileupload/js/jquery.fileupload-process.js" %}'></script>
<script src='{% static "js/jquery.magnific-popup.min.js" %}'></script> <script src='{% static "js/jquery.magnific-popup.min.js" %}'></script>
<script src='{% static "lib/jquery.cookie/jquery.cookie.min.js" %}'></script> <script src='{% static "lib/jquery.cookie/jquery.cookie.min.js" %}'></script>
<script src='{% static "lib/jquery-jgrowl/jquery.jgrowl.min.js" %}'></script> <script src='{% static "lib/jquery-jgrowl/jquery.jgrowl.min.js" %}'></script>
<script src='{% static "my-libs.js" %}'></script> <script src='{% static "my-libs.js" %}'></script>
<script src='{% static "js/main.js" %}'></script> <!-- Файл верстальщика --> <script src='{% static "js/main.js" %}'></script> <!-- Файл верстальщика -->
<script src='{% static "index.js" %}'></script> <!-- Файл программистов --> <script src='{% static "index.js" %}'></script> <!-- Файл программистов -->
<script> <script>
var SocketHandlerMain = function (userId) { var SocketHandlerMain = function (userId) {
var domain = '{{ request.META.HTTP_HOST }}'; var domain = '{{ request.META.HTTP_HOST }}';
var port = '{{ request.META.SERVER_PORT }}'; var port = '{{ request.META.SERVER_PORT }}';
var queryString = '{{ request.get_full_path }}'; var queryString = '{{ request.get_full_path }}';
if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/work-projects') != 0)) { if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/work-projects') != 0)) {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
if (window.location.protocol == 'https:') { if (window.location.protocol == 'https:') {
var ws = "wss://"; var ws = "wss://";
} else { } else {
var ws = "ws://"; var ws = "ws://";
} }
var url = ws + domain + '/chat/' + userId + '/'; var url = ws + domain + '/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {
intervalId = setInterval(function () { intervalId = setInterval(function () {
sock.send('{"dummy": 1}'); sock.send('{"dummy": 1}');
}, 15000); }, 15000);
}; };
sock.onmessage = function (event) { sock.onmessage = function (event) {
var notificationData = JSON.parse(event.data); var notificationData = JSON.parse(event.data);
var outMessage = ""; var outMessage = "";
if (notificationData.answer_type == 'add_message_contact') { if (notificationData.answer_type == 'add_message_contact') {
outMessage += "<a href='/chat/?user_id=" + notificationData.sender_id + "'>" + notificationData.msg + "<a>"; outMessage += "<a href='/chat/?user_id=" + notificationData.sender_id + "'>" + notificationData.msg + "<a>";
} else if ((notificationData.answer_type == 'approve_stages') || (notificationData.answer_type == 'add_message_order')) { } else if ((notificationData.answer_type == 'approve_stages') || (notificationData.answer_type == 'add_message_order')) {
outMessage += "<a href='/chat/#order" + notificationData.order_id + "'>" + notificationData.msg + "<a>"; outMessage += "<a href='/chat/#order" + notificationData.order_id + "'>" + notificationData.msg + "<a>";
}
$.jGrowl("Вам пришло новое сообщение!<br />" + outMessage, {life: 15000});
};
this.add_message = function (messageData) {
sock.send(JSON.stringify(messageData));
};
}
};
var userId = '{{ request.user.pk }}';
if (userId) {
var socketMain = new SocketHandlerMain(userId);
} }
$.jGrowl("Вам пришло новое сообщение!<br />" + outMessage, {life: 15000}); </script>
}; {% endblock %}
this.add_message = function (messageData) {
sock.send(JSON.stringify(messageData)); {% block js_block %}
};
} {% endblock %}
};
var userId = '{{ request.user.pk }}';
if (userId) {
var socketMain = new SocketHandlerMain(userId);
}
</script>
{% block js_block %}{% endblock %}
{#{% endcompress %}#} {#{% endcompress %}#}
</body> </body>

@ -1,7 +1,9 @@
{% load staticfiles %} {% load staticfiles %}
{% load sass_tags %}
<link rel='stylesheet' href='{% sass_src "partials/sass/footer.sass" %}'>
<footer class="disTab"> <footer class="row">
<div class="col-lg-4"> <div class="col-lg-4">
<div class="logoF" onclick="window.location='/'"></div> <div class="logoF" onclick="window.location='/'"></div>

@ -2,6 +2,7 @@
{% load thumbnail %} {% load thumbnail %}
{% load user_tags %} {% load user_tags %}
{% load activeurl %} {% load activeurl %}
{% load sass_tags %}
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
{% url 'users:contractor-profile' pk=request.user.pk as profile_url %} {% url 'users:contractor-profile' pk=request.user.pk as profile_url %}
@ -9,6 +10,8 @@
{% url 'users:customer-profile-open-projects' pk=request.user.pk as profile_url %} {% url 'users:customer-profile-open-projects' pk=request.user.pk as profile_url %}
{% endif %} {% endif %}
<link rel='stylesheet' href='{% sass_src "partials/sass/header.sass" %}'>
<div class="wrTop {% if request.user.is_authenticated %} disTab {% endif %}"> <div class="wrTop {% if request.user.is_authenticated %} disTab {% endif %}">
<div class="container-fluid topMain"> <div class="container-fluid topMain">
<div class="row"> <div class="row">
@ -22,7 +25,7 @@
<ul class="mainMenu"> <ul class="mainMenu">
<li class="icon_tm1"> <li class="icon_tm1">
<a href="{% url 'projects:project-filter' %}">Поиск заказов</a> <a href="{% url 'projects:project-filter' %}">Поиск заказов</a>
<span></span> <span></span>
</li> </li>
{% if request.user.is_contractor %} {% if request.user.is_contractor %}

@ -0,0 +1,91 @@
$static: '/static'
footer
background-color: #F7F7F7
&:before
content: ''
width: 300px
height: 3px
background-color: black
.logoF
width: 183px
height: 36px
background: url('#{$static}/img/logoF.png') no-repeat center
background-size: cover
float: left
margin: 41px 0 0 27px
cursor: pointer
.linksSoc
width: 100%
float: left
margin: 32px 0 0 0
padding: 0 0 0 23px
>
a
width: 46px
height: 46px
opacity: 0.2
display: block
float: left
margin-right: 10px
-webkit-transition: opacity 0.4s ease-out
-moz-transition: opacity 0.4s ease-out
transition: opacity 0.4s ease-out
&:link, &:visited
width: 46px
height: 46px
opacity: 0.2
display: block
float: left
margin-right: 10px
-webkit-transition: opacity 0.4s ease-out
-moz-transition: opacity 0.4s ease-out
transition: opacity 0.4s ease-out
.icon_ls1
background: url('#{$static}/img/socSprite.png') no-repeat 0 0
.icon_ls2
background: url('#{$static}/img/socSprite.png') no-repeat -46px 0
.icon_ls3
background: url('#{$static}/img/socSprite.png') no-repeat -92px 0
.icon_ls4
background: url('#{$static}/img/socSprite.png') no-repeat -138px 0
.icon_ls5
background: url('#{$static}/img/socSprite.png') no-repeat -184px 0
margin-right: 0
a:hover
opacity: 1
.copy-rights
float: left
font-size: 16px
font-family: 'pfdintextcomppro-regular', sans-serif
text-transform: uppercase
letter-spacing: 2px
margin: 34px 0 42px 31px
color: #aaa
.listF1
p
font-family: Arial, Verdana, Helvetica, sans-serif
font-size: 16px
text-transform: uppercase
color: #2c2c2c
font-weight: bold
margin: 46px 0 20px 0
ul li
margin-bottom: 6px
list-style: none
color: red
&:last-child
margin-bottom: 0
a
font-family: 'Arial-MT-Regular', sans-serif
color: #6c6c6c
font-size: 15px
&:link, &:visited
font-family: 'Arial-MT-Regular', sans-serif
color: #6c6c6c
font-size: 15px

@ -0,0 +1,334 @@
$static: '/static'
.wrTop
width: 100%
background-color: black
.topMain
width: 1200px
margin: 0 auto
.col-lg-7
width: 55%
.col-lg-2
width: 19%
.mainMenu li
padding-right: 25px
a
font-size: 15px
.welcomeMain
width: 100%
float: left
font-size: 48px
text-align: center
padding: 54px 0 39px 0
font-family: 'pfbeausanspro-thin', sans-serif
.welcomeMain
line-height: 48px
font-family: 'pfdintextcomppro-regular', sans-serif
font-size: 43px
.logo
width: 183px
height: 36px
background: url('#{$static}/img/logo.png') no-repeat center
background-size: cover
float: left
margin: 18px 0 21px 10px
cursor: pointer
.mainMenu
float: left
margin: 26px 0 0 0
li
float: left
position: relative
padding-right: 30px
list-style: none
a
text-decoration: none
border-bottom: 3px solid transparent
-webkit-transition: all 0.4s ease-out
-moz-transition: all 0.4s ease-out
transition: all 0.4s ease-out
&:hover a
border-color: #ff0029
span
content: ''
position: absolute
height: 23px
left: 0
top: -1px
.icon_tm1 span
width: 26px
//background: url('../img/listMain.png') no-repeat left
background-size: cover
background: url('#{$static}/img/listMain.png') no-repeat 0 0
.icon_tm2 span
width: 22px
background-size: cover
background: url('#{$static}/img/listMain.png') no-repeat -26px 0
.icon_tm3 span
width: 24px
background-size: cover
background: url('#{$static}/img/listMain.png') no-repeat -48px 0
.icon_tm1:hover span
width: 26px
background: url('#{$static}/img/listMain2.png') no-repeat left !important
background-size: cover
background-position: 0 0 !important
.icon_tm2:hover span
width: 22px
background: url('#{$static}/img/listMain2.png') no-repeat left !important
background-size: cover
background-position: -26px 0 !important
.icon_tm3:hover span
width: 26px !important
background: url('#{$static}/img/listMain2.png') no-repeat left !important
background-size: cover
background-position: -49px 0 !important
.mainMenu li
&:last-child
padding-right: 0
a
color: white
font-size: 18px
padding: 30px 0 27px 40px
font-family: 'pfbeausanspro-reg', sans-serif
&.active > a
border-color: #ff0029
&.icon_tm1.active span
background: url('#{$static}/img/listMain2.png') no-repeat !important
&.officeList.active span
background: url('#{$static}/img/list4tml.png') no-repeat center !important
&.icon_tm2.active span
background: url('#{$static}/img/listMain2.png') no-repeat center !important
&.icon_tm3.active span
background: url('#{$static}/img/listMain2.png') no-repeat right !important
.changeBlock
width: 485px
overflow: hidden
padding: 113px 0 0 0
position: relative
&a
border: none
cursor: pointer
height: 40px
border-radius: 40px
font-size: 20px
text-transform: uppercase
font-family: 'pfdintextcomppro-regular', sans-serif
letter-spacing: 4px
position: relative
top: -60px
display: table
margin: auto
.changeBlock1
float: left
margin-left: -15px
background-color: rgba(255, 0, 6, 0.7)
&a
&:link,
&:visited
background: url('#{$static}/img/button1.png') no-repeat 25px, black
color: white
padding: 24px 26px 20px 72px
.changeBlock2
float: right
margin-right: -15px
background-color: rgba(0, 0, 0, 0.7)
&a
&:link,
&:visited
background: url('#{$static}/img/button2.png') no-repeat 27px, white
color: black
padding: 24px 26px 20px 72px
.changeBlock
p
font-family: 'Arial-MT-Regular', sans-serif
.changeBlock1
p
color: white
.changeBlock2
p
color: black
.changeBlock
min-height: 500px
display: table
padding: 143px 20px 120px 20px
&:after
content: ''
position: absolute
width: 66px
height: 1px
left: 50%
margin-left: -30px
background-color: white
bottom: 60px
.changeBlock2
float: right
margin-right: -15px
background-color: rgba(0, 0, 0, 0.7)
.square
width: 46px
height: 46px
position: absolute
right: -23px
top: 100px
z-index: 9
-webkit-transform: rotate(135deg)
-moz-transform: rotate(135deg)
transform: rotate(135deg)
background-color: #DCDCDD
.insetSquare
width: 100%
height: 100%
position: relative
-webkit-transform: rotate(-135deg)
-moz-transform: rotate(-135deg)
transform: rotate(-135deg)
background: url('#{$static}/img/arrow.png') no-repeat center
.imgProfile
width: 75px
height: 75px
float: right
margin: 0 0 0 -60px
img
display: block
width: 100%
height: 100%
.infoProfile
float: right
.btn-group
.btn
width: 75px
height: 75px
float: left
border-radius: 0 !important
background-color: black
border: none
span
color: white
font-size: 26px
.dropdown-toggle
&:hover, &:active, &:focus
-webkit-box-shadow: inset 0 3px 5px rgba(255, 0, 39, 0.99)
-moz-box-shadow: inset 0 3px 5px rgba(255, 0, 39, 0.99)
box-shadow: inset 0 3px 5px rgba(255, 0, 39, 0.99)
background-color: rgb(255, 0, 39)
.dropdown-menu
border-radius: 0
background-color: black
left: -174px
margin: -1px 100% 0 0
float: left
width: 250px
height: auto
padding: 30px 20px 15px 40px
border-top: 3px solid #ff2c2c
li
margin-bottom: 10px
&:last-child
margin-bottom: 0
a
color: white
font-size: 17px
font-family: 'pfbeausanspro-reg', sans-serif
position: relative
&:link, &:visited
color: white
font-size: 17px
font-family: 'pfbeausanspro-reg', sans-serif
position: relative
&:hover, &:active
background-color: black !important
color: #ff2c2c
span
content: ''
position: absolute
width: 20px
left: -18px
top: 4px
.icon_mm1 a span
height: 20px
background-size: cover
background: url('#{$static}/img/menu.png') no-repeat 0 0
.icon_mm2 a span
height: 22px
background-size: cover
background: url('#{$static}/img/menu.png') no-repeat 0 -20px
.icon_mm3 a span
height: 13px
background-size: cover
background: url('#{$static}/img/menu.png') no-repeat 0 -42px
top: 6px
.icon_mm4 a span
height: 20px
background-size: cover
background: url('#{$static}/img/menu.png') no-repeat 0 -55px
.icon_mm5 a span
height: 20px
background-size: cover
background: url('#{$static}/img/menu.png') no-repeat 0 -75px
.icon_mm6 a span
height: 20px
background-size: cover
background: url('#{$static}/img/menu.png') no-repeat 0 -95px
.icon_mm7 a span
height: 20px
background-size: cover
background: url('#{$static}/img/menu.png') no-repeat 0 0
.icon_mm8 a span
height: 20px
background-size: contain
background: url('#{$static}/img/user-5.png') no-repeat 0 0
.icon_mm1 a:hover span
height: 20px
background: url('#{$static}/img/menu2.png') no-repeat center !important
background-size: cover !important
background-position: 0 0 !important
.icon_mm2 a:hover span
height: 22px
background-size: cover
background: url('#{$static}/img/menu2.png') no-repeat 0 -20px
.icon_mm3 a:hover span
height: 13px
background-size: cover
background: url('#{$static}/img/menu2.png') no-repeat 0 -42px
.icon_mm4 a:hover span
height: 20px
background-size: cover
background: url('#{$static}/img/menu2.png') no-repeat 0 -55px
.icon_mm5 a:hover span
height: 20px
background-size: cover
background: url('#{$static}/img/menu2.png') no-repeat 0 -75px
.icon_mm6 a:hover span
height: 20px
background-size: cover
background: url('#{$static}/img/menu2.png') no-repeat 0 -95px
.icon_mm7 a:hover span
height: 20px
background-size: cover
background: url('#{$static}/img/menu2.png') no-repeat 0 0
.icon_mm8 a:hover span
height: 20px
background-size: contain
background: url('#{$static}/img/user-4.png') no-repeat 0 0

@ -1,11 +1,13 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% load staticfiles %} {% load staticfiles %}
{% load thumbnail %} {% load thumbnail %}
{% load sass_tags %}
{% block head_css %} {% block head_css %}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/fonts.css" %}'> {# <link rel='stylesheet' href='{% static "lib/proekton-components/css/fonts.css" %}'>#}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/selected-container.css" %}'> {# <link rel='stylesheet' href='{% static "lib/proekton-components/css/selected-container.css" %}'>#}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/editable-container.css" %}'> {# <link rel='stylesheet' href='{% static "lib/proekton-components/css/editable-container.css" %}'>#}
<link rel='stylesheet' href='{% static "lib/proekton-components/css/select-box.css" %}'> {# <link rel='stylesheet' href='{% static "lib/proekton-components/css/select-box.css" %}'>#}
<link rel='stylesheet' href='{% sass_src "lib/proekton-components/sass/components.sass" %}'>
<link rel='stylesheet' href='{% static "css/project_filter.css" %}'>{# other #} <link rel='stylesheet' href='{% static "css/project_filter.css" %}'>{# other #}
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'> <link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
<link rel='stylesheet' href='{% static "css/user_profile_edit.css" %}'> <link rel='stylesheet' href='{% static "css/user_profile_edit.css" %}'>

@ -6,7 +6,7 @@ from .models import InvoiceHistory, WithDraw, Transaction, Wallet, PayFromScore
class InvoiceHistoryAdmin(admin.ModelAdmin): class InvoiceHistoryAdmin(admin.ModelAdmin):
list_display = ('comment', 'sum', 'user', 'balance',) list_display = ('comment', 'sum', 'user', 'balance',)
readonly_fields = InvoiceHistory._meta.get_all_field_names() readonly_fields = list(map(lambda obj: obj.name, InvoiceHistory._meta.get_fields()))
class WithDrawAdmin(ImportExportModelAdmin): class WithDrawAdmin(ImportExportModelAdmin):
@ -16,17 +16,18 @@ class WithDrawAdmin(ImportExportModelAdmin):
class WalletAdmin(admin.ModelAdmin): class WalletAdmin(admin.ModelAdmin):
list_display = ('customer', 'balance', ) list_display = ('customer', 'balance', )
readonly_fields = Wallet._meta.get_all_field_names() # readonly_fields = Wallet._meta.get_all_field_names()
readonly_fields = list(map(lambda obj: obj.name, Wallet._meta.get_fields()))
class TransactionAdmin(admin.ModelAdmin): class TransactionAdmin(admin.ModelAdmin):
list_display = ('customer', 'complete',) list_display = ('customer', 'complete',)
readonly_fields = Transaction._meta.get_all_field_names() readonly_fields = list(map(lambda obj: obj.name, Transaction._meta.get_fields()))
class PayFromScoreAdmin(admin.ModelAdmin): class PayFromScoreAdmin(admin.ModelAdmin):
list_display = ('customer', 'sum', 'created_at') list_display = ('customer', 'sum', 'created_at')
readonly_fields = PayFromScore._meta.get_all_field_names() readonly_fields = list(map(lambda obj: obj.name, PayFromScore._meta.get_fields()))
admin.site.register(InvoiceHistory, InvoiceHistoryAdmin) admin.site.register(InvoiceHistory, InvoiceHistoryAdmin)

@ -0,0 +1,63 @@
const NODE_ENV = process.env.NODE_ENV || 'dev';
const webpack = require('webpack');
const path = require('path');
module.exports = {
// context: __dirname + "/assets/js/src",
context: __dirname,
// context: path.join(__dirname, "static", "js"),
entry: {
// user: "./user",
create_project: "./assets/js/src/customer_project_create.js",
init_customer_project_create: './assets/js/src/init_customer_project_create.js'
},
output: {
path: path.resolve(__dirname, "assets/js/build"),
filename: "[name].js",
// ,library: "[name]" // import to global variables
},
watch: NODE_ENV == 'dev',
devtools: "eval",
plugins: [
new webpack.DefinePlugin(
{NODE_ENV: JSON.stringify(NODE_ENV)})
// new webpack.EnvironmentPlugin('NODE_ENV')
],
resolve: {
alias: {
components: path.resolve(__dirname, "assets/lib/proekton-components/js/src")
}
,
// moduleDirectories: [__dirname + '/assets/js/src'],
extensions: ['', '.js']
},
resolveLoader: {
moduleDirectories: ['node_modules'],
// moduleTemplate: ['*-loader', '*'],
// extentions: ['', '.js']
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
query: {
cacheDirectory: true,
plugins: ['transform-decorators-legacy'],
presets: ['es2015']
}
},
]
}
};

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-12-01 17:03
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('work_sell', '0018_merge'),
]
operations = [
migrations.AlterField(
model_name='worksell',
name='work_type',
field=models.IntegerField(choices=[(403, 'Проектирование777'), (87, 'Техническое сопровождение666')], default=1),
),
]
Loading…
Cancel
Save