Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
course-discovery
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
course-discovery
Commits
0dca3588
Commit
0dca3588
authored
Oct 07, 2016
by
Awais Qureshi
Committed by
GitHub
Oct 07, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #362 from edx/awais786/ECOM-5496
Awais786/ecom 5496
parents
057bca2d
5b361188
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
384 additions
and
17 deletions
+384
-17
course_discovery/apps/publisher/forms.py
+63
-1
course_discovery/apps/publisher/migrations/0010_auto_20161006_1151.py
+64
-0
course_discovery/apps/publisher/models.py
+19
-7
course_discovery/apps/publisher/tests/factories.py
+3
-0
course_discovery/apps/publisher/tests/test_views.py
+0
-0
course_discovery/apps/publisher/urls.py
+1
-0
course_discovery/apps/publisher/views.py
+80
-8
course_discovery/static/js/publisher/publisher.js
+12
-0
course_discovery/static/sass/publisher/course_detail.scss
+88
-1
course_discovery/templates/publisher/add_course_form.html
+0
-0
course_discovery/templates/publisher/view_course_form.html
+54
-0
No files found.
course_discovery/apps/publisher/forms.py
View file @
0dca3588
"""
"""
Course publisher forms.
Course publisher forms.
"""
"""
from
django.contrib.auth.models
import
Group
from
django
import
forms
from
django
import
forms
from
django.utils.translation
import
ugettext_lazy
as
_
from
course_discovery.apps.publisher.models
import
Course
,
CourseRun
,
Seat
from
course_discovery.apps.course_metadata.models
import
Person
from
course_discovery.apps.publisher.models
import
Course
,
CourseRun
,
Seat
,
User
class
BaseCourseForm
(
forms
.
ModelForm
):
class
BaseCourseForm
(
forms
.
ModelForm
):
...
@@ -40,6 +43,24 @@ class CourseForm(BaseCourseForm):
...
@@ -40,6 +43,24 @@ class CourseForm(BaseCourseForm):
exclude
=
(
'changed_by'
,)
exclude
=
(
'changed_by'
,)
class
CustomCourseForm
(
CourseForm
):
""" Course Form. """
institution
=
forms
.
ModelChoiceField
(
queryset
=
Group
.
objects
.
all
(),
required
=
True
)
title
=
forms
.
CharField
(
label
=
'Course Title'
,
required
=
True
,
max_length
=
255
)
number
=
forms
.
CharField
(
label
=
'Course Number'
,
required
=
True
,
max_length
=
255
)
team_admin
=
forms
.
ModelChoiceField
(
queryset
=
User
.
objects
.
filter
(
is_staff
=
True
),
required
=
True
)
class
Meta
(
CourseForm
.
Meta
):
model
=
Course
fields
=
(
'title'
,
'number'
,
'short_description'
,
'full_description'
,
'expected_learnings'
,
'level_type'
,
'primary_subject'
,
'secondary_subject'
,
'tertiary_subject'
,
'prerequisites'
,
'level_type'
,
'image'
,
'team_admin'
,
'level_type'
,
'institution'
,
)
class
CourseRunForm
(
BaseCourseForm
):
class
CourseRunForm
(
BaseCourseForm
):
""" Course Run Form. """
""" Course Run Form. """
...
@@ -49,6 +70,30 @@ class CourseRunForm(BaseCourseForm):
...
@@ -49,6 +70,30 @@ class CourseRunForm(BaseCourseForm):
exclude
=
(
'state'
,
'changed_by'
,)
exclude
=
(
'state'
,
'changed_by'
,)
class
CustomCourseRunForm
(
CourseRunForm
):
""" Course Run Form. """
contacted_partner_manager
=
forms
.
BooleanField
(
widget
=
forms
.
RadioSelect
(
choices
=
((
1
,
_
(
"Yes"
)),
(
0
,
_
(
"No"
)))),
initial
=
0
,
required
=
False
)
start
=
forms
.
DateTimeField
(
required
=
True
)
staff
=
forms
.
ModelMultipleChoiceField
(
queryset
=
Person
.
objects
.
all
(),
widget
=
forms
.
SelectMultiple
,
required
=
False
)
target_content
=
forms
.
BooleanField
(
widget
=
forms
.
RadioSelect
(
choices
=
((
1
,
_
(
"Yes"
)),
(
0
,
_
(
"No"
)))),
initial
=
0
,
required
=
False
)
class
Meta
(
CourseRunForm
.
Meta
):
fields
=
(
'keywords'
,
'start'
,
'end'
,
'length'
,
'transcript_languages'
,
'language'
,
'min_effort'
,
'max_effort'
,
'keywords'
,
'contacted_partner_manager'
,
'target_content'
,
'pacing_type'
,
'is_seo_review'
,
'video_language'
,
'staff'
,
)
class
SeatForm
(
BaseCourseForm
):
class
SeatForm
(
BaseCourseForm
):
""" Course Seat Form. """
""" Course Seat Form. """
...
@@ -76,3 +121,20 @@ class SeatForm(BaseCourseForm):
...
@@ -76,3 +121,20 @@ class SeatForm(BaseCourseForm):
seat
.
save
()
seat
.
save
()
return
seat
return
seat
def
clean
(
self
):
price
=
self
.
cleaned_data
.
get
(
'price'
)
seat_type
=
self
.
cleaned_data
.
get
(
'type'
)
if
seat_type
in
[
Seat
.
PROFESSIONAL
,
Seat
.
NO_ID_PROFESSIONAL
,
Seat
.
VERIFIED
,
Seat
.
CREDIT
]
\
and
not
price
:
self
.
add_error
(
'price'
,
_
(
'Only honor/audit seats can be without price.'
))
return
self
.
cleaned_data
class
CustomSeatForm
(
SeatForm
):
""" Course Seat Form. """
class
Meta
(
SeatForm
.
Meta
):
fields
=
(
'price'
,
'type'
)
course_discovery/apps/publisher/migrations/0010_auto_20161006_1151.py
0 → 100644
View file @
0dca3588
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'publisher'
,
'0009_auto_20160929_1927'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'course'
,
name
=
'expected_learnings'
,
field
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
'Expected Learnings'
),
),
migrations
.
AlterField
(
model_name
=
'course'
,
name
=
'full_description'
,
field
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
'Full Description'
),
),
migrations
.
AlterField
(
model_name
=
'course'
,
name
=
'level_type'
,
field
=
models
.
ForeignKey
(
related_name
=
'publisher_courses'
,
default
=
None
,
to
=
'course_metadata.LevelType'
,
blank
=
True
,
verbose_name
=
'Level Type'
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'course'
,
name
=
'prerequisites'
,
field
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
'Prerequisites'
),
),
migrations
.
AlterField
(
model_name
=
'course'
,
name
=
'short_description'
,
field
=
models
.
CharField
(
default
=
None
,
max_length
=
255
,
null
=
True
,
blank
=
True
,
verbose_name
=
'Brief Description'
),
),
migrations
.
AlterField
(
model_name
=
'courserun'
,
name
=
'language'
,
field
=
models
.
ForeignKey
(
related_name
=
'publisher_course_runs'
,
to
=
'ietf_language_tags.LanguageTag'
,
verbose_name
=
'Content Language'
,
blank
=
True
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'historicalcourse'
,
name
=
'expected_learnings'
,
field
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
'Expected Learnings'
),
),
migrations
.
AlterField
(
model_name
=
'historicalcourse'
,
name
=
'full_description'
,
field
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
'Full Description'
),
),
migrations
.
AlterField
(
model_name
=
'historicalcourse'
,
name
=
'prerequisites'
,
field
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
'Prerequisites'
),
),
migrations
.
AlterField
(
model_name
=
'historicalcourse'
,
name
=
'short_description'
,
field
=
models
.
CharField
(
default
=
None
,
max_length
=
255
,
null
=
True
,
blank
=
True
,
verbose_name
=
'Brief Description'
),
),
]
course_discovery/apps/publisher/models.py
View file @
0dca3588
...
@@ -7,7 +7,7 @@ from django.dispatch import receiver
...
@@ -7,7 +7,7 @@ from django.dispatch import receiver
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django_extensions.db.models
import
TimeStampedModel
from
django_extensions.db.models
import
TimeStampedModel
from
django_fsm
import
FSMField
,
transition
from
django_fsm
import
FSMField
,
transition
from
guardian.shortcuts
import
assign_perm
from
guardian.shortcuts
import
assign_perm
,
get_groups_with_perms
from
simple_history.models
import
HistoricalRecords
from
simple_history.models
import
HistoricalRecords
from
sortedm2m.fields
import
SortedManyToManyField
from
sortedm2m.fields
import
SortedManyToManyField
from
stdimage.models
import
StdImageField
from
stdimage.models
import
StdImageField
...
@@ -84,18 +84,18 @@ class Course(TimeStampedModel, ChangedByMixin):
...
@@ -84,18 +84,18 @@ class Course(TimeStampedModel, ChangedByMixin):
title
=
models
.
CharField
(
max_length
=
255
,
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Course title'
))
title
=
models
.
CharField
(
max_length
=
255
,
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Course title'
))
number
=
models
.
CharField
(
max_length
=
50
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Course number'
))
number
=
models
.
CharField
(
max_length
=
50
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Course number'
))
short_description
=
models
.
CharField
(
short_description
=
models
.
CharField
(
max_length
=
255
,
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'
Course subtitle
'
)
max_length
=
255
,
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'
Brief Description
'
)
)
)
full_description
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'
About this course
'
))
full_description
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'
Full Description
'
))
organizations
=
models
.
ManyToManyField
(
organizations
=
models
.
ManyToManyField
(
Organization
,
blank
=
True
,
related_name
=
'publisher_courses'
,
verbose_name
=
_
(
'Partner Name'
)
Organization
,
blank
=
True
,
related_name
=
'publisher_courses'
,
verbose_name
=
_
(
'Partner Name'
)
)
)
level_type
=
models
.
ForeignKey
(
level_type
=
models
.
ForeignKey
(
LevelType
,
default
=
None
,
null
=
True
,
blank
=
True
,
related_name
=
'publisher_courses'
,
verbose_name
=
_
(
'
Course level
'
)
LevelType
,
default
=
None
,
null
=
True
,
blank
=
True
,
related_name
=
'publisher_courses'
,
verbose_name
=
_
(
'
Level Type
'
)
)
)
expected_learnings
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
"
What you'll learn
"
))
expected_learnings
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
"
Expected Learnings
"
))
syllabus
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
)
syllabus
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
)
prerequisites
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
)
prerequisites
=
models
.
TextField
(
default
=
None
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Prerequisites'
)
)
learner_testimonial
=
models
.
CharField
(
max_length
=
50
,
null
=
True
,
blank
=
True
)
learner_testimonial
=
models
.
CharField
(
max_length
=
50
,
null
=
True
,
blank
=
True
)
verification_deadline
=
models
.
DateTimeField
(
verification_deadline
=
models
.
DateTimeField
(
null
=
True
,
null
=
True
,
...
@@ -147,6 +147,15 @@ class Course(TimeStampedModel, ChangedByMixin):
...
@@ -147,6 +147,15 @@ class Course(TimeStampedModel, ChangedByMixin):
for
group
in
user
.
groups
.
all
():
for
group
in
user
.
groups
.
all
():
assign_perm
(
self
.
VIEW_PERMISSION
,
group
,
self
)
assign_perm
(
self
.
VIEW_PERMISSION
,
group
,
self
)
def
assign_permission_by_group
(
self
,
institution
):
assign_perm
(
self
.
VIEW_PERMISSION
,
institution
,
self
)
@property
def
get_group_institution
(
self
):
""" Returns the Group object with for the given course object. """
available_groups
=
get_groups_with_perms
(
self
)
return
available_groups
[
0
]
if
available_groups
else
None
class
CourseRun
(
TimeStampedModel
,
ChangedByMixin
):
class
CourseRun
(
TimeStampedModel
,
ChangedByMixin
):
""" Publisher CourseRun model. It contains fields related to the course run intake form."""
""" Publisher CourseRun model. It contains fields related to the course run intake form."""
...
@@ -185,7 +194,10 @@ class CourseRun(TimeStampedModel, ChangedByMixin):
...
@@ -185,7 +194,10 @@ class CourseRun(TimeStampedModel, ChangedByMixin):
max_effort
=
models
.
PositiveSmallIntegerField
(
max_effort
=
models
.
PositiveSmallIntegerField
(
null
=
True
,
blank
=
True
,
null
=
True
,
blank
=
True
,
help_text
=
_
(
'Estimated maximum number of hours per week needed to complete a course run.'
))
help_text
=
_
(
'Estimated maximum number of hours per week needed to complete a course run.'
))
language
=
models
.
ForeignKey
(
LanguageTag
,
null
=
True
,
blank
=
True
,
related_name
=
'publisher_course_runs'
)
language
=
models
.
ForeignKey
(
LanguageTag
,
null
=
True
,
blank
=
True
,
related_name
=
'publisher_course_runs'
,
verbose_name
=
_
(
'Content Language'
)
)
transcript_languages
=
models
.
ManyToManyField
(
transcript_languages
=
models
.
ManyToManyField
(
LanguageTag
,
blank
=
True
,
related_name
=
'publisher_transcript_course_runs'
LanguageTag
,
blank
=
True
,
related_name
=
'publisher_transcript_course_runs'
)
)
...
...
course_discovery/apps/publisher/tests/factories.py
View file @
0dca3588
...
@@ -7,6 +7,7 @@ from factory.fuzzy import FuzzyText, FuzzyChoice, FuzzyDecimal, FuzzyDateTime, F
...
@@ -7,6 +7,7 @@ from factory.fuzzy import FuzzyText, FuzzyChoice, FuzzyDecimal, FuzzyDateTime, F
from
pytz
import
UTC
from
pytz
import
UTC
from
course_discovery.apps.core.models
import
Currency
from
course_discovery.apps.core.models
import
Currency
from
course_discovery.apps.core.tests.factories
import
UserFactory
from
course_discovery.apps.course_metadata.choices
import
CourseRunPacing
from
course_discovery.apps.course_metadata.choices
import
CourseRunPacing
from
course_discovery.apps.course_metadata.tests
import
factories
from
course_discovery.apps.course_metadata.tests
import
factories
from
course_discovery.apps.ietf_language_tags.models
import
LanguageTag
from
course_discovery.apps.ietf_language_tags.models
import
LanguageTag
...
@@ -34,6 +35,8 @@ class CourseFactory(factory.DjangoModelFactory):
...
@@ -34,6 +35,8 @@ class CourseFactory(factory.DjangoModelFactory):
secondary_subject
=
factory
.
SubFactory
(
factories
.
SubjectFactory
)
secondary_subject
=
factory
.
SubFactory
(
factories
.
SubjectFactory
)
tertiary_subject
=
factory
.
SubFactory
(
factories
.
SubjectFactory
)
tertiary_subject
=
factory
.
SubFactory
(
factories
.
SubjectFactory
)
team_admin
=
factory
.
SubFactory
(
UserFactory
)
class
Meta
:
class
Meta
:
model
=
Course
model
=
Course
...
...
course_discovery/apps/publisher/tests/test_views.py
View file @
0dca3588
This diff is collapsed.
Click to expand it.
course_discovery/apps/publisher/urls.py
View file @
0dca3588
...
@@ -7,6 +7,7 @@ from course_discovery.apps.publisher import views
...
@@ -7,6 +7,7 @@ from course_discovery.apps.publisher import views
urlpatterns
=
[
urlpatterns
=
[
url
(
r'^courses/new$'
,
views
.
CreateCourseView
.
as_view
(),
name
=
'publisher_courses_new'
),
url
(
r'^courses/new$'
,
views
.
CreateCourseView
.
as_view
(),
name
=
'publisher_courses_new'
),
url
(
r'^courses/(?P<pk>\d+)/view/$'
,
views
.
ReadOnlyView
.
as_view
(),
name
=
'publisher_courses_readonly'
),
url
(
r'^courses/(?P<pk>\d+)/edit/$'
,
views
.
UpdateCourseView
.
as_view
(),
name
=
'publisher_courses_edit'
),
url
(
r'^courses/(?P<pk>\d+)/edit/$'
,
views
.
UpdateCourseView
.
as_view
(),
name
=
'publisher_courses_edit'
),
url
(
r'^course_runs/(?P<pk>\d+)/$'
,
views
.
CourseRunDetailView
.
as_view
(),
name
=
'publisher_course_run_detail'
),
url
(
r'^course_runs/(?P<pk>\d+)/$'
,
views
.
CourseRunDetailView
.
as_view
(),
name
=
'publisher_course_run_detail'
),
url
(
r'^course_runs/$'
,
views
.
CourseRunListView
.
as_view
(),
name
=
'publisher_course_runs'
),
url
(
r'^course_runs/$'
,
views
.
CourseRunListView
.
as_view
(),
name
=
'publisher_course_runs'
),
...
...
course_discovery/apps/publisher/views.py
View file @
0dca3588
...
@@ -2,8 +2,11 @@
...
@@ -2,8 +2,11 @@
Course publisher views.
Course publisher views.
"""
"""
from
django.contrib
import
messages
from
django.contrib
import
messages
from
django.contrib.auth.models
import
Group
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.db
import
transaction
from
django.http
import
HttpResponseRedirect
,
HttpResponseForbidden
from
django.http
import
HttpResponseRedirect
,
HttpResponseForbidden
from
django.shortcuts
import
render
,
get_object_or_404
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.views.generic
import
View
from
django.views.generic
import
View
from
django.views.generic.detail
import
DetailView
from
django.views.generic.detail
import
DetailView
...
@@ -12,7 +15,9 @@ from django.views.generic.list import ListView
...
@@ -12,7 +15,9 @@ from django.views.generic.list import ListView
from
django_fsm
import
TransitionNotAllowed
from
django_fsm
import
TransitionNotAllowed
from
guardian.shortcuts
import
get_objects_for_user
from
guardian.shortcuts
import
get_objects_for_user
from
course_discovery.apps.publisher.forms
import
CourseForm
,
CourseRunForm
,
SeatForm
from
course_discovery.apps.publisher.forms
import
(
CourseForm
,
CourseRunForm
,
SeatForm
,
CustomCourseForm
,
CustomCourseRunForm
,
CustomSeatForm
)
from
course_discovery.apps.publisher
import
mixins
from
course_discovery.apps.publisher
import
mixins
from
course_discovery.apps.publisher.models
import
Course
,
CourseRun
,
Seat
,
State
from
course_discovery.apps.publisher.models
import
Course
,
CourseRun
,
Seat
,
State
from
course_discovery.apps.publisher.wrappers
import
CourseRunWrapper
from
course_discovery.apps.publisher.wrappers
import
CourseRunWrapper
...
@@ -59,16 +64,72 @@ class CourseRunDetailView(mixins.LoginRequiredMixin, mixins.ViewPermissionMixin,
...
@@ -59,16 +64,72 @@ class CourseRunDetailView(mixins.LoginRequiredMixin, mixins.ViewPermissionMixin,
# pylint: disable=attribute-defined-outside-init
# pylint: disable=attribute-defined-outside-init
class
CreateCourseView
(
mixins
.
LoginRequiredMixin
,
mixins
.
FormValidMixin
,
CreateView
):
class
CreateCourseView
(
mixins
.
LoginRequiredMixin
,
CreateView
):
""" Create Course View."""
""" Create Course View."""
model
=
Course
model
=
Course
form_class
=
CourseForm
course_form
=
CustomCourseForm
template_name
=
'publisher/course_form.html'
run_form
=
CustomCourseRunForm
success_url
=
'publisher:publisher_courses_edit'
seat_form
=
CustomSeatForm
assign_user_groups
=
True
template_name
=
'publisher/add_course_form.html'
success_url
=
'publisher:publisher_courses_readonly'
def
get_success_url
(
self
,
course_id
):
# pylint: disable=arguments-differ
return
reverse
(
self
.
success_url
,
kwargs
=
{
'pk'
:
course_id
})
def
get_context_data
(
self
):
return
{
'course_form'
:
self
.
course_form
,
'run_form'
:
self
.
run_form
,
'seat_form'
:
self
.
seat_form
}
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
return
render
(
request
,
self
.
template_name
,
self
.
get_context_data
())
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
ctx
=
self
.
get_context_data
()
course_form
=
self
.
course_form
(
request
.
POST
,
request
.
FILES
)
run_form
=
self
.
run_form
(
request
.
POST
)
seat_form
=
self
.
seat_form
(
request
.
POST
)
if
course_form
.
is_valid
()
and
run_form
.
is_valid
()
and
seat_form
.
is_valid
():
try
:
with
transaction
.
atomic
():
seat
=
seat_form
.
save
(
commit
=
False
)
run_course
=
run_form
.
save
(
commit
=
False
)
course
=
course_form
.
save
(
commit
=
False
)
course
.
changed_by
=
self
.
request
.
user
course
.
save
()
run_course
.
course
=
course
run_course
.
changed_by
=
self
.
request
.
user
run_course
.
save
()
# commit false does not save m2m object.
run_form
.
save_m2m
()
seat
.
course_run
=
run_course
seat
.
changed_by
=
self
.
request
.
user
seat
.
save
()
institution
=
get_object_or_404
(
Group
,
pk
=
course_form
.
data
[
'institution'
])
# assign guardian permission.
course
.
assign_permission_by_group
(
institution
)
def
get_success_url
(
self
):
messages
.
success
(
return
reverse
(
self
.
success_url
,
kwargs
=
{
'pk'
:
self
.
object
.
id
})
request
,
_
(
'Course created successfully.'
)
)
return
HttpResponseRedirect
(
self
.
get_success_url
(
course
.
id
))
except
Exception
as
e
:
# pylint: disable=broad-except
messages
.
error
(
request
,
str
(
e
))
messages
.
error
(
request
,
_
(
'Please fill all required field.'
))
ctx
.
update
(
{
'course_form'
:
course_form
,
'run_form'
:
run_form
,
'seat_form'
:
seat_form
}
)
return
render
(
request
,
self
.
template_name
,
ctx
,
status
=
400
)
class
UpdateCourseView
(
mixins
.
LoginRequiredMixin
,
mixins
.
ViewPermissionMixin
,
mixins
.
FormValidMixin
,
UpdateView
):
class
UpdateCourseView
(
mixins
.
LoginRequiredMixin
,
mixins
.
ViewPermissionMixin
,
mixins
.
FormValidMixin
,
UpdateView
):
...
@@ -88,6 +149,17 @@ class UpdateCourseView(mixins.LoginRequiredMixin, mixins.ViewPermissionMixin, mi
...
@@ -88,6 +149,17 @@ class UpdateCourseView(mixins.LoginRequiredMixin, mixins.ViewPermissionMixin, mi
return
context
return
context
class
ReadOnlyView
(
mixins
.
LoginRequiredMixin
,
mixins
.
ViewPermissionMixin
,
DetailView
):
""" Course Run Detail View."""
model
=
Course
template_name
=
'publisher/view_course_form.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
ReadOnlyView
,
self
)
.
get_context_data
(
**
kwargs
)
context
[
'comment_object'
]
=
self
return
context
class
CreateCourseRunView
(
mixins
.
LoginRequiredMixin
,
mixins
.
FormValidMixin
,
CreateView
):
class
CreateCourseRunView
(
mixins
.
LoginRequiredMixin
,
mixins
.
FormValidMixin
,
CreateView
):
""" Create Course Run View."""
""" Create Course Run View."""
model
=
CourseRun
model
=
CourseRun
...
...
course_discovery/static/js/publisher/publisher.js
View file @
0dca3588
...
@@ -7,6 +7,18 @@ $(".administration-nav .tab-container > button").click(function(event) {
...
@@ -7,6 +7,18 @@ $(".administration-nav .tab-container > button").click(function(event) {
$
(
tab
).
fadeIn
();
$
(
tab
).
fadeIn
();
});
});
$
(
document
).
ready
(
function
(){
$
(
'ul.tabs .course-tabs'
).
click
(
function
(){
var
tab_id
=
$
(
this
).
attr
(
'data-tab'
);
$
(
'ul.tabs .course-tabs'
).
removeClass
(
'active'
);
$
(
'.content'
).
removeClass
(
'active'
);
$
(
this
).
addClass
(
'active'
);
$
(
"#"
+
tab_id
).
addClass
(
'active'
);
})
});
function
alertTimeout
(
wait
)
{
function
alertTimeout
(
wait
)
{
setTimeout
(
function
(){
setTimeout
(
function
(){
$
(
'.alert-messages'
).
html
(
''
);
$
(
'.alert-messages'
).
html
(
''
);
...
...
course_discovery/static/sass/publisher/course_detail.scss
View file @
0dca3588
...
@@ -321,10 +321,97 @@ $light-gray: rgba(204, 204, 204, 1);
...
@@ -321,10 +321,97 @@ $light-gray: rgba(204, 204, 204, 1);
margin-bottom
:
20px
;
margin-bottom
:
20px
;
}
}
.publisher-layout
{
background
:
rgb
(
242
,
242
,
242
);
padding
:
15px
;
margin-bottom
:
20px
;
.layout-title
{
font-size
:
24px
;
font-weight
:
bold
;
}
.course-form
{
margin
:
0
;
box-shadow
:
none
;
}
}
input
,
select
{
max-width
:
100%
;
}
.required
{
color
:
red
;
font-size
:
12px
;
}
.checkbox-inline
{
ul
{
list-style
:
none
;
margin-left
:
0
;
margin-bottom
:
15px
;
li
{
display
:
inline-block
;
@include
margin-right
(
10px
);
&
:last-child
{
margin-right
:
0
;
}
}
}
}
.course-information
{
.course-information
{
margin-bottom
:
30px
;
margin-bottom
:
30px
;
input
,
select
{
margin-bottom
:
15px
;
}
.hd-4
{
margin-bottom
:
25px
;
padding-bottom
:
10px
;
border-bottom
:
1px
solid
rgb
(
51
,
51
,
51
);
}
.field-title
{
border-bottom
:
1px
solid
rgb
(
51
,
51
,
51
);
padding-bottom
:
10px
;
margin-bottom
:
20px
;
font-weight
:
bold
;
}
.course-tabs
{
list-style
:
none
;
@include
float
(
left
);
@include
float
(
left
);
width
:
50%
;
@include
margin-right
(
10px
);
padding
:
10px
;
border-bottom
:
2px
solid
#ccc
;
color
:
#ccc
;
text-align
:
center
;
&
:hover
{
color
:
#337ab7
;
border-bottom
:
2px
solid
#337ab7
;
}
}
.course-tabs.active
{
border-bottom
:
2px
solid
#337ab7
;
color
:
#337ab7
;
}
.content
{
display
:
none
;
p
{
margin
:
0
;
}
p
:first-of-type
{
margin-bottom
:
20px
;
}
}
.content.active
{
display
:
inline-block
;
}
.info-item
{
.info-item
{
margin-bottom
:
15px
;
margin-bottom
:
15px
;
...
...
course_discovery/templates/publisher/add_course_form.html
0 → 100644
View file @
0dca3588
This diff is collapsed.
Click to expand it.
course_discovery/templates/publisher/view_course_form.html
0 → 100644
View file @
0dca3588
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Course Form" %}
{% endblock title %}
{% block content %}
<div
class=
"alert-messages"
>
{% if messages %}
{% for message in messages %}
<div
class=
"alert alert-{{ message.tags }}"
role=
"alert"
aria-labelledby=
"alert-title-{{ message.tags }}"
tabindex=
"-1"
>
<div
class=
"alert-message-with-action"
>
<p
class=
"alert-copy"
>
{{ message }}
</p>
</div>
</div>
{% endfor %}
{% endif %}
</div>
<div
class=
"layout-full publisher-layout layout"
>
<h2
class=
"layout-title"
>
{% trans "Base information" %}
</h2>
<div
class=
"card course-form"
>
<div
class=
"course-information"
>
<h4
class=
"hd-4"
>
{% trans "Course Form" %}
</h4>
<fieldset
class=
"form-group grid-container grid-manual"
>
<div
class=
"field-title"
>
{% trans "INSTITUTION INFORMATION" %}
</div>
<div
class=
"row"
>
<div
class=
"col col-6"
>
{{ object.get_group_institution }}
</div>
</div>
</fieldset>
</div>
</div>
</div>
<div
class=
"layout-full layout"
>
<h2
class=
"layout-title"
>
{% trans "Course information" %}
</h2>
<div
class=
"card course-form"
>
<div
class=
"course-information"
>
<fieldset
class=
"form-group"
>
<div
class=
"field-row"
>
<div
class=
"field-col"
>
<label
class=
"field-label "
for=
"title"
>
{{ course_form.title.label }}
</label>
{{ object.title }}
</div>
</div>
</fieldset>
</div>
</div>
</div>
{% endblock content %}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment