PR-41 Формирование заказа Заказчиком

Серьезно изменена структура проекта: sass, webpack
Закончено формирование заказа
remotes/origin/PR-41
booblegum 9 years ago
parent 1d92ce283c
commit 974437d40d
  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. 249
      assets/js/build/create_project.js
  11. 1912
      assets/js/build/init_customer_project_create.js
  12. 223
      assets/js/build/user.js
  13. 25
      assets/js/src/customer_project_create.js
  14. 122
      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. 16
      assets/js/src/seeds/read_more.js
  20. 5
      assets/js/src/seeds/test_seeds.js
  21. 56
      assets/js/src/user.js
  22. 8
      assets/lib/proekton-components/bash/browserify.sh
  23. 4
      assets/lib/proekton-components/js/src/NoTreeSelect.js
  24. 133
      assets/lib/proekton-components/js/src/SelectOrCreate.js
  25. 25
      assets/lib/proekton-components/js/src/SelectedContainer.js
  26. 28
      assets/lib/proekton-components/js/src/SelectedContainerCreate.js
  27. 4
      assets/lib/proekton-components/js/src/SingleTreeSelect.js
  28. 5
      assets/lib/proekton-components/js/src/TreeSelect.js
  29. 46
      assets/lib/proekton-components/js/src/base/AbsBaseSelect.js
  30. 5
      assets/lib/proekton-components/js/src/decorators.js
  31. 0
      assets/lib/proekton-components/js/src/examples/init.js
  32. 0
      assets/lib/proekton-components/js/src/examples/init_example.js
  33. 0
      assets/lib/proekton-components/js/src/examples/init_user_profile.js
  34. 66
      assets/lib/proekton-components/js/src/init_customer_project_create.js
  35. 4
      assets/lib/proekton-components/sass/components.sass
  36. 11
      assets/lib/proekton-components/sass/parts/_editable-container.sass
  37. 18
      assets/lib/proekton-components/sass/parts/_fonts.sass
  38. 165
      assets/lib/proekton-components/sass/parts/_select-box.sass
  39. 44
      assets/lib/proekton-components/sass/parts/_selected-container.sass
  40. 6
      assets/sass/base/_colors.sass
  41. 29
      assets/sass/base/_fonts.sass
  42. 1
      assets/sass/base/_variavles.sass
  43. 20
      assets/sass/common/_parts.sass
  44. 213
      assets/sass/components/custom-components.sass
  45. 65
      assets/sass/main.sass
  46. 6
      assets/sass/modules/_mods.sass
  47. 10
      assets/sass/utils/_functions.sass
  48. 7
      package.json
  49. 79
      projects/forms.py
  50. 47
      projects/migrations/0048_auto_20161201_2003.py
  51. 25
      projects/migrations/0049_auto_20161201_2157.py
  52. 10
      projects/models.py
  53. 11
      projects/static/css/project_filter.css
  54. 411
      projects/templates/_trash/customer_project_create.html
  55. 769
      projects/templates/customer_project_create.html
  56. 276
      projects/templates/customer_project_create_new.html
  57. 5
      projects/urls.py
  58. 177
      projects/views.py
  59. 24
      templates/home_modular.html
  60. 255
      templates/partials/base.html
  61. 4
      templates/partials/footer.html
  62. 3
      templates/partials/header.html
  63. 91
      templates/partials/sass/footer.sass
  64. 334
      templates/partials/sass/header.sass
  65. 63
      webpack.config.js
  66. 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):

@ -267,19 +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 = [ SASS_PROCESSOR_INCLUDE_DIRS = [
# os.path.join(ROOT_DIR, 'extra-styles/scss'), os.path.join(ROOT_DIR, 'assets/sass'),
# os.path.join(ROOT_DIR, 'node_modules'), ]
# ] # print("SASS = ", SASS_PROCESSOR_INCLUDE_DIRS)
# SASS_PROCESSOR_AUTO_INCLUDE = False # SASS_PROCESSOR_AUTO_INCLUDE = False
SASS_PROCESSOR_INCLUDE_FILE_PATTERN = r'^.+\.scss$' # SASS_PROCESSOR_INCLUDE_FILE_PATTERN = r'^.+\.sass$'
SASS_PROCESSOR_ENABLED = DEBUG SASS_PROCESSOR_ENABLED = DEBUG
# SASS_PRECISION = 8 # SASS_PRECISION = 8
SASS_PROCESSOR_ROOT = os.path.join(ROOT_DIR, 'assets') # 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,249 @@
/******/ (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 _test_seeds = __webpack_require__(5);
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)();
});
/***/ },
/* 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 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,25 @@
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 {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();
});

@ -0,0 +1,122 @@
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();
console.log("hide");
}
}
)
}
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,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,8 +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
browserify ./js/src/init_customer_project_create.js -o ./js/build/init_customer_project_create.js -t babelify
#watchify ./js/src/init.js -t babelify -o ./js/build/init.js

@ -2,9 +2,9 @@ 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) {

@ -0,0 +1,133 @@
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);
}
_onButtonAddOptions(e) {
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));
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;

@ -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
}) })
} }
@ -280,9 +286,6 @@ export default class AbsBaseSelect {
this.$buttonAddOptions.hide(); this.$buttonAddOptions.hide();
// TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select // TODO: сделать проверку на наличие всех нужных элементов и их корректый jq select
// REDEFINE IN CHILD
// this.dataTree = data;
// this._bindEvents();
} }
_fillOptionsData() { _fillOptionsData() {
@ -392,6 +395,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 +416,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,13 +4,16 @@ 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);
}else {
console.log("arg = ", arg);
} }
} }
method.apply(this, args); method.apply(this, args);

@ -1,66 +0,0 @@
import SelectedContainer from './SelectedContainer';
import NoTreeSelect from './NoTreeSelect';
import TreeSelect from './TreeSelect';
import SingleTreeSelect from './SingleTreeSelect'
$(function () {
function createFilterSpecs(url) {
// SPECIALIZATIONS FILTER
let sb_main = new TreeSelect($('#select-box-1'), {url, visible: true});
sb_main.setHeader("Специальность");
let select_container = new SelectedContainer($('#selected-spec'), {obj: sb_main});
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});
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 createFilterBuildingClass(url) {
// BUILDING-CLASSIFICATION FILTER
let 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});
sb_build_main.connectSelectedContainer(select_build_container);
sb_build_main.setNearbySelectBox(sb_build_1);
sb_build_1.setNearbySelectBox("", sb_build_main);
}
function createFilterConstructionType(url) {
let 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});
sb_constr_main.connectSelectedContainer(select_constr_type);
}
function createFilerLocations(url) {
let sb_loc_main = new SingleTreeSelect($('#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 SingleTreeSelect($('#sb-location-2'), {obj: sb_loc_main});
let sb_loc_2 = new SingleTreeSelect($('#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);
}
createFilterSpecs('/api/specializations_flat');
createFilterBuildingClass('/api/building_classifications');
createFilterConstructionType('/api/construction_type');
createFilerLocations('/api/locations_flat');
});

@ -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,165 @@
@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
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,20 @@
@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
&:hover
cursor: pointer
.required
font:
size: 10pt
color: #9f9f9f

@ -0,0 +1,213 @@
@import "common/parts"
@import "base/colors"
@import "base/variavles"
.simple-field
.header
@extend %header
max-width: 100%
.simple-input
height: 51px
width: 100%
border: 1px solid #cccccc
outline: none
padding: 5px 40px 5px 20px
background-color: white
margin-bottom: -1px
&.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
.simple-select
height: 51px
width: 100%
border: 1px solid #cccccc
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
.upload-new
width: 50%
height: 30px
overflow: hidden
cursor: pointer
border-radius: 40px
border: 1px solid #FF0029
&: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)
.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
//.btn-simple
.upload-new, .btn-simple
transition: all 0.3s
cursor: pointer
.upload-new
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
font-size: 12px
text-align: center
font-family: Myriad, sans-serif
.upload-new.paper-clip
padding-left: 40px
padding-right: 15px
background: url("#{$static}/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
.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,65 @@
@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 #CFCFCF
border-left: 1px solid #CFCFCF
.main-content
padding: 43px 25px 40px 25px
.title-scope
line-height: 36px
padding: 0 100px
text-align: center
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 #CFCFCF
border-bottom: 1px solid #CFCFCF
.select-text
color: #{map_get($component_colors, select)}

@ -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):
@ -111,7 +113,7 @@ class Project(models.Model, HitCountMixin):
price_and_term_required = models.BooleanField(default=False) price_and_term_required = models.BooleanField(default=False)
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')
realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects') realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects')

@ -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,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,411 +1,382 @@
{% 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 "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/editable-container.css" %}'>#}
{# <link rel='stylesheet' href='{% static "lib/proekton-components/css/select-box.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/fonts.sass" %}'>#}
<link rel='stylesheet' href='{% sass_src "lib/proekton-components/sass/components.sass" %}'>
<link rel='stylesheet' href='{% sass_src "sass/components/custom-components.sass" %}'>
{# <link rel='stylesheet' href='{% static "css/project_filter.css" %}'>#}
{# <link rel='stylesheet' href='{% static "css/user_profile_edit.css" %}'>#}
{# <link rel='stylesheet' href='{% static "css/custom-checkboxes.css" %}'>#}
{# <link rel='stylesheet' href='{% static "css/customer_project_create.css" %}'>#}
{% 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 main-content">
<div class="row"> <div class="col-lg-12">
<div class="col-lg-12 allProjects"> <div class="row">
<p class="titleScore">Новый заказ</p> <div class="col-lg-12">
</div> <div class="title-scope">
<h1>Новый заказ</h1>
<form action="{% url 'projects:customer-project-create' %}" method="POST" enctype="multipart/form-data" novalidate </div>
class="-spec-work-type-combo-container"> </div>
{% 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> <form action="{% url 'projects:customer-project-create' %}" method="POST"
<div class="titleF1 disTab"> enctype="multipart/form-data" novalidate>
<div class="col-lg-12">Местоположение <span data-tooltip data-placement="{% tooltip_placement pk=18 %}" {% csrf_token %}
title="{% tooltip pk=18 %}" <div class="row">
class="-green-glyphicon glyphicon glyphicon-question-sign"></span> <div class="col-lg-9">
<span id="{% random_ident %}" class="-validation-error" <div class="simple-field">
style="color: red">{{ realty_form.location.errors.as_text }}</span></div> <div class="header">Название заказа</div>
</div> <i class="fa fa-question-circle-o" aria-hidden="true"></i>
<div class="polsF1 polsF2 disTab"> <span class="required">Обязательно</span>
<div> <input value="{{ form.name.value }}" name="{{ form.name.html_name }}"
<div class="col-lg-3"> class="simple-input"
<input type="hidden" class="-location-select -location-select-country" style="width: 100%"> placeholder="Пример: Дизайн квартиры, Армирование фундамента, Конструкции перекрытия и т.д."
</div> required>
</div>
<div class="col-lg-3"> </div>
<input type="hidden" class="-location-select -location-select-region" style="width: 100%"> <div class="col-lg-3">
</div>
</div>
<div class="col-lg-3"> </div>
<input type="hidden" class="-location-select -location-select-city" style="width: 100%"> <div class="row vertical-child mod-align-bottom">
</div> <div class="col-lg-9">
</div> <div class="" id="select-box-1"></div>
</div>
<input type="hidden" id="chosenLocationId" name="{{ realty_form.location.html_name }}" <div class="col-lg-3">
value="{{ realty_form.location.value }}"> <div href="#" onclick="return false" data-toggle="modal"
data-target="#projectWorkTypeSuggestionModal"
<div class="col-lg-3 make-new"> class="btn btn-simple btn-plus">Нет нужной специальности хочу добавить
<label>{{ form.cro }}<span></span></label> </div>
<p>Требуется допуск (СРО) <span data-tooltip data-placement="{% tooltip_placement pk=17 %}" </div>
title="{% tooltip pk=17 %}" </div>
class="-green-glyphicon glyphicon glyphicon-question-sign"></span></p> <div class="row">
</div> <div class="col-lg-3">
</div> <div class="vertical-child" id="select-box-2">
</div> </div>
</div>
<div class="col-lg-3">
<div class="searchF1 polsF1 polsFF links-filter"> <div class="vertical-child" id="select-box-3">
<input class="btn-submit-link" type="submit" value="Разместить проект"> </div>
</div> </div>
</div> <div class="col-lg-3">
<div class="vertical-child" id="select-box-4">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-5">
</div>
</div>
</div>
<div class="row" style="display: none">
<div class="col-lg-12">
<div class="selected-container horizontal" id="selected-spec">
<input type="hidden" name="{{ form.specialization.html_name }}"
value="{{ form.specialization.value }}">
</div>
</div>
</div>
<div style="margin-top: 45px" class="row">
<div class="col-lg-12">
<div class="simple-field">
<div class="header">Подобно опишите задание для /
<span class="select-text" id="spec-value"></span>
</div>
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
<span class="required">Обязательно</span>
<textarea style="width: 100%" rows="6" placeholder=
" Пример №1
Разработать архиьектурные решения для жилого дома на основании эскизной проработки
Пример №2
Разработать проект по електроснабжению и освещению гаража"></textarea>
</div>
<div class="documentsChat mod" id="fileUploadContainer">
<div style="display: inline-block;vertical-align: middle;">
<div style="display: inline-block;vertical-align: inherit;"
class="upload-new paper-clip">
<p id="fileUploadAddBtn" style="margin: 0">прикрепить файл</p>
</div>
<span style="display: inline-block;vertical-align: inherit;">до 100 файлов</span>
</div>
<ul style="float: none" 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">
<span class="file-upload-label"></span>
<div class="file-upload-remove-btn"></div>
</li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="separator">
<span class="header">Показать расширенные настройки</span>
<button class="resButton">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</button>
<div class="border"></div>
</div>
</div>
</div>
<div class="slide active">
<div style="padding-bottom: 15px" class="row">
<div class="col-lg-12">
<div class="header">Способ оплаты</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label class="mod-align-center">
<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;
Безопасная сделка (с
резервированием бюджета)
</label>
<div class="description">
<span class="teaser">
Безопасная сделка – это сервис, с помощью которого:<br/>
-Заказчики - полностью избавляются от всех финансовых рисков при сотрудничестве с
Исполнителями;<br/>
-Исполнители - получают гарантию своевременной оплаты своей работы (выполненной по
заданию
точно в срок).
</span>
<span class="complete">
<p>
Это сервис и тип оплаты в заказах, в котором сумма оплаты резервируется
(перечисляется
на
сайт) Заказчиком до начала работы и выплачивается Исполнителю только после
успешного
выполнения задания. А в случае некачественного и/или несвоевременного выполнения
возвращается Заказчику.
</p>
<p>
Сайт выступает в Безопасных сделках хранителем и гарантом сохранности средств. А
в
случае
возникновения конфликтов в заказе - Арбитром, независимой третьей Стороной,
помогающей
решить проблемы при сотрудничестве и справедливо распорядиться зарезервированной
суммой:<br>
-выплатить ее Исполнителю, если работа выполнена своевременно и в полном
соответствии с
заданием;<br>
-вернуть Заказчику, если работа не выполнена или нарушены сроки выполнения;<br>
-разделить сумму между Заказчиком и Исполнителем, если работа выполнена частично
и
без нарушения сроков.
</p>
</span>
<span class="more"></span>
</div>
</div>
<div class="col-lg-6">
<label class="mod-align-center">
<input name="{{ form.deal_type.html_name }}" class="custom-radio" type="radio"
{% if form.deal_type.value == 'direct_payment' %}checked{% endif %}
value="direct_payment">&nbsp;
Прямая оплата Исполнителю на
его
кошелек/счет
</label>
<div class="description">
<p>
Прямая оплата - это оплата без помощи сайта. Оплаты заказов происходят напрямую
исполнителю
на его личный счет или кошелек.
</p>
<p>
В данном случае сайт не выступает гарантом сохранности средств и не является
Арбитром
при
спорных вопросах.
</p>
</div>
</div>
</div>
<div style="margin-top: 40px" class="row mod-align-bottom">
<div class="col-lg-3">
<div class="header ">Бюджет
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input name="{{ form.budget.html_name }}" class="simple-input icon-rub" placeholder="Введите сумму"
value="{{ form.budget.value }}">
</div>
<div class="col-lg-3">
<div class="header">Срок
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input name="{{ form.term.html_name }}" class="simple-input icon-days" placeholder="Введите срок"
value="{{ form.term.value }}">
</div>
<div class="col-lg-4">
<div class="row">
<div class="col-lg-1">
<input name="{{ form.price_and_term_required.html_name }}" id="safe" class="custom-checkbox" type="checkbox"
{% if form.price_and_term_required.value %}checked{% endif %}>
</div>
<div class="col-lg-11">
<label for="safe" style="font-weight: normal" class="">
Сделать для исполнителей обязательным для заполнения поля цена и срок
</label>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="row">
<div class="col-lg-2">
<input name="{{ form.budget_by_agreement.html_name }}" id="by_agreement"
class="custom-checkbox" type="checkbox"
{% if form.budget_by_agreement.value %}checked{% endif %}>
</div>
<div class="col-lg-10">
<label for="by_agreement" style="font-weight: normal" class="">
Бюджет и срок по договоренности
</label>
</div>
</div>
</div>
</div>
{# <div class="row">#}
{# <div class="col-lg-12">#}
{# <div class="separator">#}
{# <div class="border"></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="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 %}
{% 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 %} {% block js_block %}
<script> <script src='{% static "js/bootstrap.min.js" %}'></script>
// Project work type suggestion modal --------------------------------- <script src='{% static "js/build/init_customer_project_create.js" %}'></script>
<script src='{% static "js/build/create_project.js" %}'></script>
;
(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 %}

@ -1,276 +0,0 @@
{% extends 'partials/base.html' %}
{% load i18n %}
{% load staticfiles %}
{% block head_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/editable-container.css" %}'>
<link rel='stylesheet' href='{% static "lib/proekton-components/css/select-box.css" %}'>
<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/user_profile_edit.css" %}'>
<link rel='stylesheet' href='{% static "css/custom-checkboxes.css" %}'>
<link rel='stylesheet' href='{% static "css/customer_project_create.css" %}'>
{% endblock %}
{% block content %}
{% include 'partials/modals/project_work_type_suggestion.html' %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row mainContent">
<div class="row">
<div class="col-lg-12 allProjects">
<p class="titleScore">Новый заказ</p>
</div>
</div>
<div class="row">
<div class="col-lg-9">
<div class="header">Название заказа
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input value="" name="" class="simple-input"
placeholder="Пример: Дизайн квартиры, Армирование фундамента, Конструкции перекрытия и т.д.">
</div>
<div class="col-lg-3">
</div>
</div>
<div class="row vertical-child">
<div class="col-lg-9">
<div class="" id="select-box-1"></div>
</div>
<div class="col-lg-3">
<div href="#" onclick="return false" data-toggle="modal"
data-target="#projectWorkTypeSuggestionModal"
class="btn btn-simple btn-plus">Нет нужной специальности хочу добавить
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-2">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-3">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-4">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-5">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="selected-container horizontal" id="selected-spec">
<input type="hidden" name="{{ form.contractor_specializations.html_name }}"
value="{{ form.contractor_specializations.value }}">
</div>
</div>
</div>
<div style="margin-top: 45px" class="row">
<div class="col-lg-12">
<div class="header">
Подобно опишите задание для / ...
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i> Обязательно
</div>
<textarea style="width: 100%" rows="6" placeholder=
" Пример №1
Разработать архиьектурные решения для жилого дома на основании эскизной проработки
Пример №2
Разработать проект по електроснабжению и освещению гаража"></textarea>
{# <div id="fileUploadContainer" class="upload-new paper-clip">#}
{# <p id="fileUploadAddBtn" style="margin: 0">прикрепить файл</p> до 100 файлов#}
{# </div>#}
<div class="documentsChat mod" id="fileUploadContainer">
<div style="display: inline-block;vertical-align: middle;">
<div style="display: inline-block;vertical-align: inherit;" class="upload-new paper-clip">
<p id="fileUploadAddBtn" style="margin: 0">прикрепить файл</p>
</div>
<span style="display: inline-block;vertical-align: inherit;">(до 100 файлов)</span>
</div>
<ul style="float: none" 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>
</div>
</div>
<div class="row separator">
<div class="col-lg-12">
<div class="flex">
<span class="header">Показать расширенные настройки</span>
<button class="resButton">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</button>
<div class="border"></div>
</div>
</div>
</div>
<div class="slide active">
<div class="row">
<div class="col-lg-12">
<div class="header">Способ оплаты</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label>
<input type="checkbox"> Безопасная сделка (с резервированием бюджета)
</label>
<div class="description">
Безопасная сделка – это сервис, с помощью которого:
-Заказчики - полностью избавляются от всех финансовых рисков при сотрудничестве с
Исполнителями;
-Исполнители - получают гарантию своевременной оплаты своей работы (выполненной по заданию
точно в срок).
Это сервис и тип оплаты в заказах, в котором сумма оплаты резервируется (перечисляется на
сайт) Заказчиком до начала работы и выплачивается Исполнителю только после успешного
выполнения задания. А в случае некачественного и/или несвоевременного выполнения –
возвращается Заказчику.
Сайт выступает в Безопасных сделках хранителем и гарантом сохранности средств. А в случае
возникновения конфликтов в заказе - Арбитром, независимой третьей Стороной, помогающей
решить проблемы при сотрудничестве и справедливо распорядиться зарезервированной суммой:
-выплатить ее Исполнителю, если работа выполнена своевременно и в полном соответствии с
заданием;
-вернуть Заказчику, если работа не выполнена или нарушены сроки выполнения;
-разделить сумму между Заказчиком и Исполнителем, если работа выполнена частично и без
нарушения сроков.
</div>
</div>
<div class="col-lg-6">
<label>
<input type="checkbox"> Прямая оплата Исполнителю на его кошелек/счет
</label>
<div class="description">
Прямая оплата - это оплата без помощи сайта. Оплаты заказов происходят напрямую исполнителю
на его личный счет или кошелек.
В данном случае сайт не выступает гарантом сохранности средств и не является Арбитром при
спорных вопросах.
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="header ">Бюджет
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input name="..." class="simple-input" placeholder="Введите сумму" value="">
</div>
<div class="col-lg-3">
<div class="header">Срок
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
<input name="..." class="simple-input" placeholder="Введите срок" value="">
</div>
<div class="col-lg-3">
<label>
<input type="checkbox"> Сделать для исполнителей обязательным для заполнения поля цена и
срок
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</label>
</div>
<div class="col-lg-3">
<label>
<input type="checkbox"> Бюджет и срок по договоренности
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</label>
</div>
</div>
<div class="row separator">
<div class="col-lg-12">
<div class="flex">
<div class="border"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<input type="checkbox"> Создать/выбрать объект, прикрепить объект к заказу
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<input name="..." class="simple-input" placeholder="Создайте/Выберите объект" value="">
</div>
<div class="col-lg-6">
<div class="selected-container horizontal" id="selected-obj">
<input type="hidden" name="obj" value="">
</div>
</div>
</div>
<!-- bottom block -->
<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="{{ form.contractor_building_classifications.html_name }}"
value="{{ form.contractor_building_classifications.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="{{ form.contractor_construction_types.html_name }}"
value="{{ form.contractor_construction_types.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 class="row top-line">
<div class="col-lg-3 vertical-child" style="text-align: center">
<div class="header">&nbsp;</div>
<input type="submit" class="btn btn-simple" value="РАЗМЕСТИТЬ ЗАКАЗ">
</div>
<div class="col-lg-3 col-lg-offset-6 vertical-child" style="text-align: center">
<div class="header">&nbsp;</div>
<input type="submit" class="btn btn-simple" value="ПРЕДВАРИТЕЛЬНЫЙ ПРОСМОТР">
</div>
</div>
</div> <!-- slide -->
</div> <!-- content -->
</div>
{% endblock %}
{% block js_block %}
<script src='{% static "lib/proekton-components/js/build/init_customer_project_create.js" %}'></script>
{% endblock %}

@ -12,7 +12,6 @@ from .views import (
ContractorPortfolioUpdateView, ContractorPortfolioUpdateView,
CustomerOfferOrderView, CustomerOfferOrderView,
CustomerProjectCreateView, CustomerProjectCreateView,
CustomerProjectCreateViewNew,
CustomerProjectDeleteView, CustomerProjectDeleteView,
CustomerProjectEditView, CustomerProjectEditView,
CustomerProjectRestoreView, CustomerProjectRestoreView,
@ -33,8 +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_new/$', CustomerProjectCreateViewNew.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,93 +402,93 @@ 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): # class CustomerProjectCreateView(BaseMixin, View):
form_class = CustomerProjectEditForm # form_class = CustomerProjectEditForm
realty_form = RealtyForm # realty_form = RealtyForm
work_type_suggestion_form = ProjectWorkTypeSuggestionForm # work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'customer_project_create.html' # template_name = 'customer_project_create.html'
#
def dispatch(self, request, *args, **kwargs): # def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer(): # if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs) # return super().dispatch(request, *args, **kwargs)
else: # else:
raise PermissionDenied # raise PermissionDenied
#
def get(self, request, *args, **kwargs): # def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs)) # context = self.get_context_data(**_.merge({}, request.GET, kwargs))
#
form = self.form_class(request=request) # form = self.form_class(request=request)
realty_form = self.realty_form(request=request, prefix='realty_form') # 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') # work_type_suggestion_form = self.work_type_suggestion_form(request=request, prefix='work_type_suggestion')
#
context.update({ # context.update({
'form': form, # 'form': form,
'realty_form': realty_form, # 'realty_form': realty_form,
'work_type_suggestion_form': work_type_suggestion_form, # 'work_type_suggestion_form': work_type_suggestion_form,
}) # })
#
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')
#
if realty: # if realty:
realty_form = self.realty_form(request.POST, instance=realty, request=request, prefix='realty_form') # realty_form = self.realty_form(request.POST, instance=realty, request=request, prefix='realty_form')
else: # else:
realty_form = self.realty_form(request.POST, request=request, prefix='realty_form') # realty_form = self.realty_form(request.POST, request=request, prefix='realty_form')
#
if form.is_valid() and realty_form.is_valid(): # if form.is_valid() and realty_form.is_valid():
project = form.save(commit=False) # project = form.save(commit=False)
project.customer = request.user # project.customer = request.user
project.save() # project.save()
form.save_m2m() # form.save_m2m()
#
Order.objects.create(project=project, secure=project.deal_type == 'secure_deal') # 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)
for file in request.FILES.getlist('new_files'):
ProjectFile.objects.create(file=file, project=project)
if realty: class CustomerProjectCreateView(BaseMixin, View):
realty_form.save() form_class = CustomerProjectEditFormNew
else: realty_form = RealtyFormNew
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 CustomerProjectCreateViewNew(BaseMixin, View):
form_class = CustomerProjectEditForm
realty_form = RealtyForm
work_type_suggestion_form = ProjectWorkTypeSuggestionForm work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'customer_project_create_new.html' template_name = 'customer_project_create.html'
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer(): if request.user.is_authenticated() and request.user.is_customer():
@ -509,8 +512,7 @@ class CustomerProjectCreateViewNew(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')
@ -536,6 +538,9 @@ class CustomerProjectCreateViewNew(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,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">

@ -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

@ -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