~xibo-maintainers/xibo/tempel

« back to all changes in this revision

Viewing changes to views/layout-designer-page.twig

  • Committer: Dan Garner
  • Date: 2016-02-16 14:21:08 UTC
  • mto: This revision was merged to the branch mainline in revision 484.
  • Revision ID: git-v1:63232095626c7ce5aee618d037440309aa4f8e42
UI/Model/Structure for dynamic display groups.
xibosignage/xibo#724

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
    {% if layout.backgroundImageId == 0 %}
27
27
        {% set backgroundCss = layout.backgroundColor %}
28
28
    {% else %}
29
 
        {% set backgroundCss %}url('{{ urlFor("layout.download.background", {id: layout.layoutId}) }}?preview=1&width={{ width }}&height={{ height }}&proportional=0&layoutBackgroundId={{ layout.backgroundImageId }}') top center no-repeat; background-color: {{ layout.backgroundColor }}{% endset %}
 
29
        {% set backgroundCss %}url('{{ urlFor("library.download", {id: layout.backgroundImageId}) }}?preview=1&width={{ width }}&height={{ height }}') top center no-repeat; background-color: {{ layout.backgroundColor }}{% endset %}
30
30
    {% endif %}
31
31
 
32
 
 
33
 
    <div class="layout-toolbox row">
34
 
        <div class="col-md-12">
35
 
            <div class="panel bttm-fix with-nav-tabs panel-primary">
36
 
                <div class="panel-heading">
37
 
                    <ul class="nav nav-tabs">
38
 
                        <li class="active tab-design">
39
 
                            <a class="text-center" id="designer-tab" href="#tab1primary" data-toggle="tab"><i class="fa fa-pencil-square-o" aria-hidden="true"></i>  {% trans "Designer" %}</a>
40
 
                        </li>
41
 
                        <li class="tab-design">
42
 
                            <a class="text-center" id="action-tab" href="#tab2primary" data-toggle="tab"><i class="fa fa-bell" aria-hidden="true"></i>   {% trans "Actions" %}</a>
43
 
                        </li>
44
 
                        <div class="pull-right">
45
 
                            <span class="text-center" data-toggle="tooltip" data-placement="bottom" data-title="{% trans "Layout Duration: Duration may change depending on the exact number of items in ticker/twitter media items." %}">
46
 
                                <i class="fa fa-clock-o" aria-hidden="true"></i>
47
 
                                <span id="layout-duration" class="label label-success big-duration"></span></span>
48
 
                            <span>| <b>Currently Editing</b></span>
49
 
                            <select id="layoutJumpList" data-live-search="true" data-width="auto">
50
 
                                {% for item in layouts %}
51
 
                                    <option value="{{ urlFor("layout.designer", {id: item.layoutId}) }}"{% if item.layoutId == layout.layoutId %} selected{% endif %}>{{ item.layout }}</option>
52
 
                                {% endfor %}
53
 
                            </select>
54
 
                        </div>
55
 
                    </ul>
56
 
                </div>
57
 
                <div class="panel-body">
58
 
                    <div class="tab-content">
59
 
                        <div class="tab-pane no-pad fade in active" id="tab1primary">
60
 
                            <div class="col-md-3 text-center">
61
 
 
62
 
                                <div class="btn-group btn-group-justified" role="group" aria-label="...">
63
 
                                    <div class="btn-group" role="group">
64
 
                                        <a class="XiboFormButton btn btn-default btn-sm" role="button" href="{{ urlFor("layout.edit.form", {id: layout.layoutId}) }}" title="{% trans "Edit the Layout Properties" %}"><span><i class="fa fa-picture-o" aria-hidden="true"></i> {% trans "Background" %}</span></a>
65
 
                                    </div>
66
 
                                    <div class="btn-group" role="group">
67
 
                                        <a class="btn btn-info btn-sm" id="regionAddButton" role="button" href="{{ urlFor("region.add", {id: layout.layoutId}) }}"><span><i class="fa fa-plus" aria-hidden="true"></i> {% trans "Region" %}</span></a>
68
 
                                    </div>
69
 
                                </div>
70
 
                            </div>
71
 
 
72
 
                            <div class="col-md-2 text-center">
73
 
                                {% if currentUser.routeViewable("/user") %}
74
 
                                <div class="designer-control-panel-checkbox override-layout">
75
 
                                    <input type="checkbox" class="switch-check-box" name="lockPosition"  data-size="small" data-off-color="danger" data-on-color="success" data-label-width="100" data-label-text="{% trans "Lock Positions" %}" {% if currentUser.getOptionValue("lockPosition", "false") == "true" %}checked="checked"{% endif %}
76
 
                                           data-on-text="{% trans "On" %}" data-off-text="{% trans "Off" %}"/>
77
 
                                </div>
78
 
                                {% endif %}
79
 
                            </div>
80
 
                            <div class="col-md-2 text-center">
81
 
                                {% if currentUser.routeViewable("/user") %}
82
 
                                <div class="designer-control-panel-checkbox override-layout">
83
 
                                    <input type="checkbox"  data-size="small" data-off-color="danger" data-on-color="success" class="switch-check-box" data-label-text="{% trans "Hide Controls" %}" data-label-width="100" name="hideControls" {% if currentUser.getOptionValue("hideControls", "false") == "true" %}checked="checked"{% endif %}
84
 
                                           data-on-text="{% trans "On" %}" data-off-text="{% trans "Off" %}"/>
85
 
                                </div>
86
 
                                {% endif %}
87
 
                            </div>
88
 
                            <div class="col-md-2 text-center">
89
 
                                <div class="btn-group btn-group-justified" role="group" aria-label="...">
90
 
                                    <div class="btn-group" role="group">
91
 
 
92
 
                                        <a class="btn btn-default btn-sm" data-toggle="tooltip" data-placement="bottom" title="{% trans "Decrease the canvas size" %}" role="button" href="{{ urlFor("layout.designer", {id: layout.layoutId}) }}?zoom={{ zoom - 0.3 }}" ><span><i class="fa fa-search-minus"  aria-hidden="true"></i></span> </a>
93
 
                                    </div>
94
 
                                    <div class="btn-group" role="group">
95
 
 
96
 
                                        <a class="btn btn-default btn-sm" data-toggle="tooltip" data-placement="bottom" title="{% trans "Increase the canvas size" %}" role="button" href="{{ urlFor("layout.designer", {id: layout.layoutId}) }}?zoom={{ zoom + 0.3 }}"><span><i class="fa fa-search-plus" aria-hidden="true"></i></span></a>
97
 
                                    </div>
98
 
                                    <div class="btn-group" role="group">
99
 
                                        <button id="saveDesignerSize" data-toggle="tooltip" data-placement="bottom" title="{% trans "Save canvas size as default" %}" class="btn btn-success btn-sm " role="button" data-designer-size="{{ zoom }}">
100
 
                                            <i class="fa fa-floppy-o" aria-hidden="true"></i></button>
101
 
                                    </div>
102
 
                                </div>
103
 
                            </div>
104
 
 
105
 
                            <div class="col-md-3 text-center">
106
 
                                <div class="btn-group" role="group" aria-label="...">
107
 
                                <div class="btn-group" role="group">
108
 
                                    <button id="layout-revert" class="btn btn-warning btn-sm disabled btn-block">
109
 
                                        <i class="fa fa-undo" aria-hidden="true"></i> {% trans "Undo" %}</button>
110
 
                                </div>
111
 
                                <div class="btn-group" role="group">
112
 
                                    <button id="layout-save-all" class="btn btn-success btn-sm disabled btn-block">
113
 
                                        <i class="fa fa-floppy-o" aria-hidden="true"></i> {% trans "Save Region Positions" %}
114
 
                                    </button>
115
 
                                </div>
116
 
                            </div>
117
 
                        </div>
118
 
 
119
 
                    </div>
120
 
                    <div class="tab-pane no-pad fade" id="tab2primary">
121
 
                        <div class="col-md-6">
122
 
                            <div class="btn-group btn-group-justified" role="group" aria-label="...">
123
 
                                <div class="btn-group" role="group">
124
 
                                    <a class="btn btn-success btn-sm" role="button" href="{{ urlFor("layout.preview", {id: layout.layoutId}) }}" target="_blank"><span><i class="fa fa-eye" aria-hidden="true"></i> {% trans "Preview Layout" %}</span></a>
125
 
                                </div>
126
 
                                <div class="btn-group" role="group">
127
 
                                    <a class="XiboFormButton btn btn-info btn-sm" id="schedule-btn" role="button" href="{{ urlFor("schedule.now.form", {id: layout.campaignId, from: "Campaign"}) }}"><span><i class="fa fa-clock-o" aria-hidden="true"></i> {% trans "Schedule Now" %}</span></a>
128
 
                                </div>
129
 
                                <div class="btn-group" role="group">
130
 
                                    <a class="XiboFormButton btn btn-warning btn-sm" role="button" href="{{ urlFor("template.from.layout.form", {id: layout.layoutId}) }}"><span><i class="fa fa-floppy-o" aria-hidden="true"></i> {% trans "Save Template" %}</span></a>
131
 
                                </div>
132
 
                                {% if layout.schemaVersion < 2 %}
133
 
                                    <div class="btn-group" role="group">
134
 
                                        <a class="XiboFormButton btn btn-warning btn-sm" role="button" href="{{ urlFor("layout.upgrade.form", {id: layout.layoutId}) }}"><span><i class="fa fa-floppy-o" aria-hidden="true"></i> {% trans "Upgrade Layout" %}</span></a>
135
 
                                    </div>
136
 
                                {% endif %}
137
 
                            </div>
138
 
                        </div>
139
 
                        <div class="col-md-6">
140
 
                            {% if isTemplate %}
141
 
                                <div class="alert no-pad alert-info text-right">{% trans "Editing a Template will only affect future Layouts." %}</div>
142
 
                            {% else %}
143
 
                                <div id="layout-status" class="alert no-pad text-center" style="margin-bottom: 0px;"></div>
144
 
                            {% endif %}
145
 
                        </div>
146
 
 
147
 
                    </div>
148
 
                </div>
149
 
            </div>
150
 
        </div>
 
32
    <div class="row">
 
33
        <div class="col-sm-12 text-center">
 
34
            <h4>{% trans "Layout Design" %} - {{ layout.layout }}</h4>
151
35
        </div>
152
36
    </div>
153
 
 
154
37
    <div class="row">
155
 
        <div class="col-md-12">
156
 
            <div id="layout" zoom="{{ zoom }}" tip_scale="1" designer_scale="{{ designerScale }}" class="layout center-block" layoutid="{{ layout.layoutId }}" data-background-color="{{ layout.backgroundColor }}" data-status-url="{{ urlFor("layout.status", {id: layout.layoutId}) }}" data-position-all-url="{{ urlFor("region.position.all", {id: layout.layoutId}) }}" style="position:relative; width:{{ width }}px; height:{{ height }}px; background:{{ backgroundCss }};">
 
38
        <div class="col-sm-2">
 
39
            <div class="row">
 
40
                <div class="col-sm-12">
 
41
                    <div id="layout-status" class="alert"></div>
 
42
                </div>
 
43
            </div>
 
44
            <div class="row">
 
45
                <div class="col-sm-12">
 
46
                    <p data-toggle="tooltip" data-title="{% trans "Duration may change depending on the exact number of items in ticker/twitter media items." %}">{% trans "Layout Duration" %} <span id="layout-duration"></span></p>
 
47
                </div>
 
48
            </div>
 
49
            <div class="row">
 
50
                <div class="col-sm-12 layoutJumpListContainer">
 
51
                    <select id="layoutJumpList" data-live-search="true">
 
52
                        {% for item in layouts %}
 
53
                            <option value="{{ urlFor("layout.designer", {id: item.layoutId}) }}"{% if item.layoutId == layout.layoutId %} selected{% endif %}>{{ item.layout }}</option>
 
54
                        {% endfor %}
 
55
                    </select>
 
56
                </div>
 
57
            </div>
 
58
            <div class="row">
 
59
                <div class="col-sm-12 designer-control-panel">
 
60
                    <a class="XiboFormButton btn btn-default btn-block" href="{{ urlFor("layout.edit.form", {id: layout.layoutId}) }}" title="{% trans "Edit the Layout Properties" %}"><span>{% trans "Background / Properties" %}</span></a>
 
61
                    <a class="btn btn-default btn-block" href="{{ urlFor("layout.preview", {id: layout.layoutId}) }}" target="_blank"><span>{% trans "Preview Layout" %}</span></a>
 
62
                    <a class="XiboFormButton btn btn-default btn-block" href="{{ urlFor("schedule.now.form", {id: layout.campaignId, from: "Campaign"}) }}"><span>{% trans "Schedule Now" %}</span></a>
 
63
                    <a class="XiboFormButton btn btn-default btn-block" href="{{ urlFor("template.from.layout.form", {id: layout.layoutId}) }}"><span>{% trans "Save Template" %}</span></a>
 
64
                    {% if layout.schemaVersion < 2 %}
 
65
                    <a class="XiboFormButton btn btn-default btn-block" href="{{ urlFor("layout.upgrade.form", {id: layout.layoutId}) }}"><span>{% trans "Upgrade Layout" %}</span></a>
 
66
                    {% endif %}
 
67
                </div>
 
68
            </div>
 
69
 
 
70
            <div class="row">
 
71
                <div class="col-sm-12">
 
72
                    <h4>{% trans "Regions" %}</h4>
 
73
                </div>
 
74
            </div>
 
75
            <div class="row">
 
76
                <div class="col-sm-12 designer-control-panel">
 
77
                    <a class="btn btn-default btn-block" id="regionAddButton" href="{{ urlFor("region.add", {id: layout.layoutId}) }}"><span>{% trans "Add Region" %}</span></a>
 
78
                    <button id="layout-save-all" class="btn btn-default btn-block disabled">{% trans "Save Positions" %}</button>
 
79
                    <button id="layout-revert" class="btn btn-default btn-block disabled">{% trans "Undo" %}</button>
 
80
                    <div class="designer-control-panel-checkbox"><input type="checkbox" class="switch-check-box" name="lockPosition" {% if currentUser.getOptionValue("lockPosition", "false") == "true" %}checked="checked"{% endif %} data-on-text="{% trans "On" %}" data-off-text="{% trans "Off" %}" /> {% trans "Lock Positions" %}</div>
 
81
                    <div class="designer-control-panel-checkbox"><input type="checkbox" class="switch-check-box" name="hideControls" {% if currentUser.getOptionValue("hideControls", "false") == "true" %}checked="checked"{% endif %} data-on-text="{% trans "On" %}" data-off-text="{% trans "Off" %}" /> {% trans "Hide Controls" %}</div>
 
82
                </div>
 
83
            </div>
 
84
            <div class="row">
 
85
                <div class="col-sm-12">
 
86
                    <h4>{% trans "Designer Size" %}</h4>
 
87
                </div>
 
88
            </div>
 
89
            <div class="row">
 
90
                <div class="col-sm-6 designer-control-panel">
 
91
                    <a class="btn btn-default btn-block" href="{{ urlFor("layout.designer", {id: layout.layoutId}) }}?zoom={{ zoom + 0.3 }}"><span>{% trans "+" %}</span></a>
 
92
                </div>
 
93
                <div class="col-sm-6 designer-control-panel">
 
94
                    <a class="btn btn-default btn-block" href="{{ urlFor("layout.designer", {id: layout.layoutId}) }}?zoom={{ zoom - 0.3 }}"><span>{% trans "-" %}</span></a>
 
95
                </div>
 
96
            </div>
 
97
            <div class="row">
 
98
                <div class="col-sm-12 designer-control-panel">
 
99
                    <button id="saveDesignerSize" class="btn btn-default btn-block" data-designer-size="{{ zoom }}">{% trans "Save as Default Size" %}</button>
 
100
                </div>
 
101
            </div>
 
102
        </div>
 
103
        <div class="col-sm-10">
 
104
            <div id="layout"
 
105
                 zoom="{{ zoom }}"
 
106
                 tip_scale="1"
 
107
                 designer_scale="{{ designerScale }}"
 
108
                 class="layout"
 
109
                 layoutid="{{ layout.layoutId }}"
 
110
                 data-background-color="{{ layout.backgroundColor }}"
 
111
                 data-status-url="{{ urlFor("layout.status", {id: layout.layoutId}) }}"
 
112
                 data-position-all-url="{{ urlFor("region.position.all", {id: layout.layoutId}) }}"
 
113
                 style="position:relative; width:{{ width }}px; height:{{ height }}px; background:{{ backgroundCss }};">
157
114
 
158
115
                {% for region in layout.regions %}
159
116
                    {% set regionWidth = region.width * designerScale %}
176
133
                        {% set previewCss = "" %}
177
134
                    {% endif %}
178
135
 
179
 
                    <div id="region_{{ region.regionId }}" regionEnabled="{{ currentUser.checkEditable(region) }}" regionid="{{ region.regionId }}" layoutid="{{ layout.layoutId }}" zindex="{{ region.zIndex }}" tip_scale="1" designer_scale="{{ designerScale }}" width="{{ region.width }}" height="{{ region.height }}" href="{{ urlFor("region.timeline.form", {id: region.regionId}) }}" {% if currentUser.checkEditable(region) %}ondblclick="XiboFormRender($(this))"{% endif %} class="{{ disabledCss }} {{ previewCss }}" data-preview-url="{{ urlFor("region.preview", {id: region.regionId}) }}" style="position:absolute; width:{{ regionWidth }}px; height:{{ regionHeight }}px; top: {{ regionTop }}px; left:{{ regionLeft }}px; z-index: {{ region.zIndex }};">
 
136
                    <div id="region_{{ region.regionId }}"
 
137
                         regionEnabled="{{ currentUser.checkEditable(region) }}"
 
138
                         regionid="{{ region.regionId }}"
 
139
                         layoutid="{{ layout.layoutId }}"
 
140
                         zindex="{{ region.zIndex }}"
 
141
                         tip_scale="1"
 
142
                         designer_scale="{{ designerScale }}"
 
143
                         width="{{ region.width }}"
 
144
                         height="{{ region.height }}"
 
145
                         href="{{ urlFor("region.timeline.form", {id: region.regionId}) }}"
 
146
                         {% if currentUser.checkEditable(region) %}ondblclick="XiboFormRender($(this).attr('href'))"{% endif %}
 
147
                         class="{{ disabledCss }} {{ previewCss }}"
 
148
                         data-preview-url="{{ urlFor("region.preview", {id: region.regionId}) }}"
 
149
                         style="position:absolute; width:{{ regionWidth }}px; height:{{ regionHeight }}px; top: {{ regionTop }}px; left:{{ regionLeft }}px; z-index: {{ region.zIndex }};">
180
150
                        <div class="regionTransparency {{ transparencyCss }}" style="width:100%; height:100%;"></div>
181
151
 
182
152
                        {% if currentUser.checkEditable(region) %}
183
153
                            <div class="btn-group regionInfo pull-right">
184
154
                                <button class="btn dropdown-toggle" data-toggle="dropdown">
185
 
                                    <span class="region-tip">{{ region.width|round }} x {{ region.height|round }} ({{ region.left|round }} ,{{ region.top|round }})</span> <span class="caret"></span>
 
155
                                    <span class="region-tip">{{ region.width|round }} x {{ region.height|round }} ({{ region.left|round }},{{ region.top|round }})</span>
 
156
                                    <span class="caret"></span>
186
157
                                </button>
187
158
                                <ul class="dropdown-menu">
188
 
                                    <li>
189
 
                                        <a class="XiboFormButton" href="{{ urlFor("region.timeline.form", {id: region.regionId}) }}">{% trans "Edit Timeline" %}</a>
190
 
                                    </li>
191
 
                                    <li>
192
 
                                        <a class="RegionOptionsMenuItem" href="{{ urlFor("region.edit.form", {id: region.regionId}) }}">{% trans "Options" %}</a>
193
 
                                    </li>
194
 
                                    <li>
195
 
                                        <a class="XiboFormButton" href="{{ urlFor("region.delete.form", {id: region.regionId}) }}">{% trans "Delete" %}</a>
196
 
                                    </li>
197
 
                                    <li>
198
 
                                        <a class="XiboFormButton" href="{{ urlFor("user.permissions.form", {entity: "Region", id: region.regionId}) }}">{% trans "Permissions" %}</a>
199
 
                                    </li>
 
159
                                    <li><a class="XiboFormButton" href="{{ urlFor("region.timeline.form", {id: region.regionId}) }}">{% trans "Edit Timeline" %}</a></li>
 
160
                                    <li><a class="RegionOptionsMenuItem" href="{{ urlFor("region.edit.form", {id: region.regionId}) }}">{% trans "Options" %}</a></li>
 
161
                                    <li><a class="XiboFormButton" href="{{ urlFor("region.delete.form", {id: region.regionId}) }}">{% trans "Delete" %}</a></li>
 
162
                                    <li><a class="XiboFormButton" href="{{ urlFor("user.permissions.form", {entity: "Region", id: region.regionId}) }}">{% trans "Permissions" %}</a></li>
200
163
                                </ul>
201
164
                            </div>
202
165
                        {% elseif layout.schemaVersion >= 2 and currentUser.checkViewable(region) %}
203
166
                            <div class="regionInfo">
204
 
                                <span class="region-tip">{{ region.width|round }} x {{ region.height|round }}
205
 
                                    ({{ region.left|round }}
206
 
                                    ,{{ region.top|round }})</span>
 
167
                                <span class="region-tip">{{ region.width|round }} x {{ region.height|round }} ({{ region.left|round }},{{ region.top|round }})</span>
207
168
                            </div>
208
169
                        {% endif %}
209
170
                        <div class="preview">
216
177
                {% endfor %}
217
178
            </div>
218
179
        </div>
219
 
 
220
180
    </div>
221
181
    {% if layout.schemaVersion < 2 %}
222
 
        <div class="row">
223
 
            <div class="col-sm-12">
224
 
                <p class="alert alert-danger">{% trans "This is an old format layout, please consider upgrading using Actions tab" %}</p>
225
 
            </div>
 
182
    <div class="row">
 
183
        <div class="col-sm-offset-1 col-sm-5">
 
184
            <p class="alert alert-danger">{% trans "This is an old format layout, please consider upgrading using the options menu" %}</p>
226
185
        </div>
 
186
    </div>
227
187
    {% endif %}
228
188
    {% if designerScale < 0.41 %}
229
189
        <div class="row">
230
 
            <div class="col-sm-12">
231
 
                <p class="alert alert-danger">{% trans "This Layout is very large, so we have disabled region drag and drop. You could enlarge the designer from the options menu or use Region Options to Manually Position your regions." %}</p>
232
 
            </div>
 
190
        <div class="col-sm-offset-1 col-sm-5">
 
191
            <p class="alert alert-danger">{% trans "This Layout is very large, so we have disabled region drag and drop. You could enlarge the designer from the options menu or use Region Options to Manually Position your regions." %}</p>
233
192
        </div>
 
193
    </div>
234
194
    {% endif %}
235
195
{% endblock %}
236
196
 
237
 
    {% block javaScript %}
238
 
        <script src="{{ theme.uri("js/xibo-layout-designer.js") }}?{{ version }}"></script>
239
 
        <script type="text/javascript">
240
 
            var translation = {
241
 
                savePositionsFirst: "{% autoescape "js" %}{{ "Please save the pending position changes first by clicking Save Positions or cancel by clicking Undo."|trans }}{% endautoescape %}"
242
 
            };
243
 
 
244
 
            // Callback for the media form
245
 
            function mediaFormCallBack(dialog) {
246
 
                
247
 
                $(dialog).closest(".modal").addClass("modal-big");
248
 
                
249
 
                // prevent filter form submit
250
 
                $("#libraryAssignFilterOptions").find("form").on("submit", function(e) {
251
 
                    e.preventDefault();
252
 
                    return false;
253
 
                });
254
 
 
255
 
                var mediaTable = $("#mediaAssignments").DataTable({
256
 
                    "language": dataTablesLanguage,
257
 
                    serverSide: true, stateSave: true, stateDuration: 0,
258
 
                    searchDelay: 3000,
259
 
                    "order": [[1, "asc"]],
260
 
                    "filter": false,
261
 
                    ajax: {
262
 
                        url: "{{ urlFor("library.search") }}",
263
 
                        "data": function (d) {
264
 
                            $.extend(d, $("#libraryAssignFilterOptions").find("form").serializeObject());
265
 
                        }
266
 
                    },
267
 
                    "columns": [
268
 
                        {"data": "mediaId"},
269
 
                        {"data": "name"},
270
 
                        {"data": "mediaType"},
271
 
                        {
272
 
                            "name": "mediaId",
273
 
                            "data": null,
274
 
                            "render": function (data, type, row, meta) {
275
 
                                if (type === "display") {
276
 
                                    // Return only the image part of the data
277
 
                                    if (data.thumbnailUrl === '')
278
 
                                        return '';
279
 
                                    else
280
 
                                        return '<img src="' + data.thumbnailUrl + '"/>';
281
 
                                    return data;
282
 
                                } else {
283
 
                                    return row.mediaId;
284
 
                                }
285
 
                            }
286
 
                        },
287
 
                        {
288
 
                            "sortable": false,
289
 
                            "data": function (data, type, row, meta) {
290
 
                                if (type !== "display")
291
 
                                    return "";
292
 
 
293
 
                                // Create a click-able span
294
 
                                return "<a href=\"#\" class=\"assignItem\"><span class=\"glyphicon glyphicon-plus-sign\"></a>";
295
 
                            }
296
 
                        }
297
 
                    ]
298
 
                });
299
 
 
300
 
                mediaTable.on('draw', function (e, settings) {
301
 
                    dataTableDraw(e, settings);
302
 
 
303
 
                    // Clicky on the +spans
304
 
                    $(".assignItem", "#mediaAssignments").click(function () {
305
 
                        // Get the row that this is in.
306
 
                        var data = mediaTable.row($(this).closest("tr")).data();
307
 
 
308
 
                        // Construct a new list item for the lower list and append it.
309
 
                        var newItem = $("<li/>", {
310
 
                            "text": " " + data.name,
311
 
                            "data-media-id": data.mediaId,
312
 
                            "class": "li-sortable",
313
 
                            "dblclick": function () {
314
 
                                $(this).remove();
315
 
                            }
316
 
                        });
317
 
 
318
 
                        newItem.appendTo("#LibraryAssignSortable");
319
 
 
320
 
                        // Add a span to that new item
321
 
                        $("<span/>", {
322
 
                            "class": "glyphicon glyphicon-minus-sign",
323
 
                            click: function () {
324
 
                                $(this).parent().remove();
325
 
                            }
326
 
                        }).prependTo(newItem);
 
197
{% block javaScript %}
 
198
    <script src="{{ theme.uri("js/xibo-layout-designer.js") }}"></script>
 
199
    <script type="text/javascript">
 
200
        var translation = {
 
201
            savePositionsFirst: "{% trans "Please save the pending position changes first by clicking Save Positions or cancel by clicking Undo." %}"
 
202
        };
 
203
 
 
204
        // Callback for the media form
 
205
        function mediaFormCallBack() {
 
206
            var mediaTable = $("#mediaAssignments").DataTable({ "language": dataTablesLanguage,
 
207
                serverSide: true, stateSave: true,
 
208
                searchDelay: 3000,
 
209
                "order": [[ 0, "asc"]],
 
210
                "filter": false,
 
211
                ajax: {
 
212
                    url: "{{ urlFor("library.search") }}",
 
213
                    "data": function(d) {
 
214
                        $.extend(d, $("#libraryAssignFilterOptions").find("form").serializeObject());
 
215
                    }
 
216
                },
 
217
                "columns": [
 
218
                    { "data": "name" },
 
219
                    { "data": "mediaType" },
 
220
                    {
 
221
                        "sortable": false,
 
222
                        "data": function(data, type, row, meta) {
 
223
                            if (type != "display")
 
224
                                return "";
 
225
 
 
226
                            // Create a click-able span
 
227
                            return "<a href=\"#\" class=\"assignItem\"><span class=\"glyphicon glyphicon-plus-sign\"></a>";
 
228
                        }
 
229
                    }
 
230
                ]
 
231
            });
 
232
 
 
233
            mediaTable.on('draw', function(e, settings) {
 
234
                dataTableDraw(e, settings);
 
235
 
 
236
                // Clicky on the +spans
 
237
                $(".assignItem", "#mediaAssignments").click(function() {
 
238
                    // Get the row that this is in.
 
239
                    var data = mediaTable.row($(this).closest("tr")).data();
 
240
 
 
241
                    // Construct a new list item for the lower list and append it.
 
242
                    var newItem = $("<li/>", {
 
243
                        "text": data.name,
 
244
                        "data-media-id": data.mediaId,
 
245
                        "class": "li-sortable",
 
246
                        "dblclick": function(){
 
247
                            $(this).remove();
 
248
                        }
327
249
                    });
328
 
                });
329
 
                mediaTable.on('processing.dt', dataTableProcessing);
330
 
 
331
 
                // Make our little list sortable
332
 
                $("#LibraryAssignSortable").sortable();
333
 
 
334
 
                // Bind the filter form
335
 
                $("#libraryAssignFilterOptions").find("input, select").change(function () {
336
 
                    mediaTable.ajax.reload();
337
 
                });
338
 
            }
339
 
 
340
 
            /**
341
 
             * Open Upload Form
342
 
             */
343
 
            function openUploadForm(templateOptions, buttons) {
344
 
 
345
 
                // Close the current dialog
346
 
                XiboDialogClose();
347
 
 
348
 
                var template = Handlebars.compile($("#template-file-upload").html());
349
 
 
350
 
                // Handle bars and open a dialog
351
 
                bootbox.dialog({
352
 
                    message: template(templateOptions),
353
 
                    title: "{% trans "Upload media" %}",
354
 
                    buttons: buttons,
355
 
                    animate: false,
356
 
                    updateInAllChecked: {% if settings.LIBRARY_MEDIA_UPDATEINALL_CHECKB == "Checked" %}true{% else %}false{% endif %},
357
 
                    deleteOldRevisionsChecked: {% if settings.LIBRARY_MEDIA_DELETEOLDVER_CHECKB == "Checked" %}true{% else %}false{% endif %}
358
 
                });
359
 
 
360
 
                openUploadFormModelShown($(".modal-body").find("form"));
361
 
            }
362
 
 
363
 
            /**
364
 
             * Modal shown
365
 
             */
366
 
            function openUploadFormModelShown(form) {
 
250
 
 
251
                    newItem.appendTo("#LibraryAssignSortable");
 
252
 
 
253
                    // Add a span to that new item
 
254
                    $("<span/>", {
 
255
                        "class": "glyphicon glyphicon-minus-sign",
 
256
                        click: function(){
 
257
                            $(this).parent().remove();
 
258
                        }
 
259
                    }).appendTo(newItem);
 
260
                });
 
261
            });
 
262
            mediaTable.on('processing.dt', dataTableProcessing);
 
263
 
 
264
            // Make our little list sortable
 
265
            $("#LibraryAssignSortable").sortable();
 
266
 
 
267
            // Bind the filter form
 
268
            $("#libraryAssignFilterOptions").find("input, select").change(function() {
 
269
                mediaTable.ajax.reload();
 
270
            });
 
271
        }
 
272
 
 
273
        /**
 
274
         * Open Upload Form
 
275
         */
 
276
        function openUploadForm(templateOptions, buttons) {
 
277
 
 
278
            // Close the current dialog
 
279
            XiboDialogClose();
 
280
 
 
281
            var template = Handlebars.compile($("#template-file-upload").html());
 
282
 
 
283
            // Handle bars and open a dialog
 
284
            bootbox.dialog({
 
285
                message: template(templateOptions),
 
286
                title: "{% trans "Upload media" %}",
 
287
                buttons: buttons,
 
288
                updateInAllChecked: {% if settings.LIBRARY_MEDIA_UPDATEINALL_CHECKB == "Checked" %}true{% else %}false{% endif %},
 
289
                deleteOldRevisionsChecked: {% if settings.LIBRARY_MEDIA_DELETEOLDVER_CHECKB == "Checked" %}true{% else %}false{% endif %}
 
290
            }).on('shown.bs.modal', function() {
367
291
                // Configure the upload form
368
292
                var url = "{{ urlFor("library.add") }}";
 
293
                var form = $(this).find("form");
369
294
 
370
295
                // Initialize the jQuery File Upload widget:
371
296
                form.fileupload({
372
297
                    url: url,
373
 
                    disableImageResize: true
 
298
                    disableImageResize: false
374
299
                });
375
300
 
376
301
                // Upload server status check for browsers with CORS support:
380
305
                        type: 'HEAD'
381
306
                    }).fail(function () {
382
307
                        $('<span class="alert alert-error"/>')
383
 
                            .text('Upload server currently unavailable - ' + new Date())
384
 
                            .appendTo(form);
 
308
                                .text('Upload server currently unavailable - ' + new Date())
 
309
                                .appendTo(form);
385
310
                    });
386
311
                }
387
312
 
388
313
                // Enable iframe cross-domain access via redirect option:
389
314
                form.fileupload(
390
 
                    'option',
391
 
                    'redirect',
392
 
                    window.location.href.replace(
393
 
                        /\/[^\/]*$/,
394
 
                        '/cors/result.html?%s'
395
 
                    )
 
315
                        'option',
 
316
                        'redirect',
 
317
                        window.location.href.replace(
 
318
                                /\/[^\/]*$/,
 
319
                                '/cors/result.html?%s'
 
320
                        )
396
321
                );
397
322
 
398
323
                form.bind('fileuploadsubmit', function (e, data) {
404
329
 
405
330
                    inputs.filter("input").prop("disabled", true);
406
331
                });
407
 
            }
408
 
 
409
 
            // Click Handler for Library Upload Buttons (image, video, powerpoint, flash)
410
 
            function libraryUploadClick(e) {
 
332
            });
 
333
        }
 
334
 
 
335
        // Click Handler for Library Upload Buttons (image, video, powerpoint, flash)
 
336
        function libraryUploadClick(e) {
 
337
            e.preventDefault();
 
338
 
 
339
            var validExt = $(this).data().validExt.replace(/,/g, "|");
 
340
            var playlistId = $(this).data().playlistId;
 
341
 
 
342
            openUploadForm({
 
343
                trans: {
 
344
                    addFiles: "{% trans "Add files" %}",
 
345
                    startUpload: "{% trans "Start upload" %}",
 
346
                    cancelUpload: "{% trans "Cancel upload" %}"
 
347
                },
 
348
                upload: {
 
349
                    maxSize: {{ libraryUpload.maxSize }},
 
350
                    maxSizeMessage: "{{ libraryUpload.maxSizeMessage  }}",
 
351
                    validExt: validExt
 
352
                },
 
353
                playlistId: playlistId
 
354
            },{
 
355
                library: {
 
356
                    label: "{% trans "View Library" %}",
 
357
                            callback: function() {
 
358
                        XiboFormRender("{{ urlFor("playlist.library.assign.form") }}".replace(":id", playlistId));
 
359
                    }
 
360
                },
 
361
                main: {
 
362
                    label: "{% trans "Done" %}",
 
363
                            className: "btn-primary",
 
364
                            callback: function() {
 
365
                        XiboFormRender(timelineForm.url, timelineForm.value);
 
366
                    }
 
367
                }
 
368
            });
 
369
        }
 
370
 
 
371
        /**
 
372
         * Media Edit form
 
373
         */
 
374
        function mediaEditFormOpen(dialog) {
 
375
 
 
376
            if (dialog.find("form").data().mediaEditable != 1)
 
377
                return;
 
378
 
 
379
            // Create a new button
 
380
            var footer = dialog.find(".modal-footer");
 
381
            var mediaId = dialog.find("form").data().mediaId;
 
382
            var widgetId = dialog.find("form").data().widgetId;
 
383
            var validExtensions = dialog.find("form").data().validExtensions;
 
384
 
 
385
            // Append
 
386
            var replaceButton = $('<button class="btn btn-warning">').html("{% trans "Replace" %}");
 
387
            replaceButton.click(function(e) {
411
388
                e.preventDefault();
412
389
 
413
 
                var validExt = $(this).data().validExt.replace(/,/g, "|");
414
 
                var playlistId = $(this).data().playlistId;
415
 
 
 
390
                // Open the upload dialog with our options.
416
391
                openUploadForm({
 
392
                    oldMediaId: mediaId,
 
393
                    widgetId: widgetId,
 
394
                    {% if config.LIBRARY_MEDIA_UPDATEINALL_CHECKB == "Checked" %}
 
395
                    updateInAllChecked: true,
 
396
                    {% else %}
 
397
                    updateInAllChecked: false,
 
398
                    {% endif %}
417
399
                    trans: {
418
 
                        addFiles: "{% trans "Add files" %}",
419
 
                        startUpload: "{% trans "Start upload" %}",
420
 
                        cancelUpload: "{% trans "Cancel upload" %}"
 
400
                        addFiles: "{% trans "Add Replacement" %}",
 
401
                        startUpload: "{% trans "Start Replace" %}",
 
402
                        cancelUpload: "{% trans "Cancel Replace" %}",
 
403
                        updateInLayouts: {
 
404
                            title: "{% trans "Update this media in all layouts it is assigned to?" %}",
 
405
                            helpText: "{% trans "Note: It will only be updated in layouts you have permission to edit." %}"
 
406
                        },
 
407
                        deleteOldRevisions: {
 
408
                            title: "{% trans "Delete the old version?" %}",
 
409
                            helpText: "{% trans "Completely remove the old version of this media item if a new file is being uploaded." %}"
 
410
                        }
421
411
                    },
422
412
                    upload: {
423
413
                        maxSize: {{ libraryUpload.maxSize }},
424
 
                        maxSizeMessage: "{{ libraryUpload.maxSizeMessage }}",
425
 
                        validExt: validExt
426
 
                    },
427
 
                    playlistId: playlistId
 
414
                        maxSizeMessage: "{{ libraryUpload.maxSizeMessage  }}",
 
415
                        validExt: validExtensions
 
416
                    }
428
417
                }, {
429
 
                    library: {
430
 
                        label: "{% trans "View Library" %}",
431
 
                        callback: function () {
432
 
                            XiboFormRender("{{ urlFor("playlist.library.assign.form") }}".replace(":id", playlistId));
433
 
                        }
434
 
                    },
435
418
                    main: {
436
419
                        label: "{% trans "Done" %}",
437
420
                        className: "btn-primary",
438
 
                        callback: function () {
 
421
                        callback: function() {
439
422
                            XiboFormRender(timelineForm.url, timelineForm.value);
440
423
                        }
441
424
                    }
442
425
                });
443
 
            }
444
 
 
445
 
            /**
446
 
             * Media Edit form
447
 
             */
448
 
            function mediaEditFormOpen(dialog) {
449
 
 
450
 
                if (dialog.find("form").data().mediaEditable != 1)
451
 
                    return;
452
 
 
453
 
                // Create a new button
454
 
                var footer = dialog.find(".modal-footer");
455
 
                var mediaId = dialog.find("form").data().mediaId;
456
 
                var widgetId = dialog.find("form").data().widgetId;
457
 
                var validExtensions = dialog.find("form").data().validExtensions;
458
 
 
459
 
                // Append
460
 
                var replaceButton = $('<button class="btn btn-warning">').html("{% trans "Replace" %}");
461
 
                replaceButton.click(function (e) {
462
 
                    e.preventDefault();
463
 
 
464
 
                    // Open the upload dialog with our options.
465
 
                    openUploadForm({
466
 
                        oldMediaId: mediaId,
467
 
                        widgetId: widgetId,
468
 
                        {% if config.LIBRARY_MEDIA_UPDATEINALL_CHECKB == "Checked" %}
469
 
                        updateInAllChecked: true,
470
 
                        {% else %}
471
 
                        updateInAllChecked: false,
472
 
                        {% endif %}
473
 
                        trans: {
474
 
                            addFiles: "{% trans "Add Replacement" %}",
475
 
                            startUpload: "{% trans "Start Replace" %}",
476
 
                            cancelUpload: "{% trans "Cancel Replace" %}",
477
 
                            updateInLayouts: {
478
 
                                title: "{% trans "Update this media in all layouts it is assigned to?" %}",
479
 
                                helpText: "{% trans "Note: It will only be updated in layouts you have permission to edit." %}"
480
 
                            },
481
 
                            deleteOldRevisions: {
482
 
                                title: "{% trans "Delete the old version?" %}",
483
 
                                helpText: "{% trans "Completely remove the old version of this media item if a new file is being uploaded." %}"
484
 
                            }
485
 
                        },
486
 
                        upload: {
487
 
                            maxSize: {{ libraryUpload.maxSize }},
488
 
                            maxSizeMessage: "{{ libraryUpload.maxSizeMessage }}",
489
 
                            validExt: validExtensions
490
 
                        }
491
 
                    }, {
492
 
                        main: {
493
 
                            label: "{% trans "Done" %}",
494
 
                            className: "btn-primary",
495
 
                            callback: function () {
496
 
                                XiboFormRender(timelineForm.url, timelineForm.value);
497
 
                            }
498
 
                        }
499
 
                    });
500
 
                });
501
 
 
502
 
                footer.find(".btn-primary").before(replaceButton);
503
 
            }
504
 
 
505
 
            function timelineGridCallback(dialog) {
506
 
 
507
 
                dialog.addClass("modal-big");
508
 
 
509
 
                var timelineWidgetTabel = $("#timelineWidgets").DataTable({
510
 
                    "language": dataTablesLanguage,
511
 
                    serverSide: true, stateSave: true, stateDuration: 0,
512
 
                    filter: false,
513
 
                    searchDelay: 3000,
514
 
                    "order": [[0, "asc"]],
515
 
                    ajax: {
516
 
                        url: "{{ urlFor("playlist.widget.search") }}",
517
 
                        "data": function (d) {
518
 
                            $.extend(d, $("#timelineWidgets").closest(".XiboGrid").find(".FilterDiv form").serializeObject());
519
 
                        }
520
 
                    },
521
 
                    "columns": [
522
 
                        {"data": "displayOrder"},
523
 
                        {"data": "name", "orderable": false},
524
 
                        {"data": "type"},
525
 
                        {
526
 
                            "data": "calculatedDuration",
527
 
                            "render": function(data) {
528
 
                                return (data == 0) ? 'N/A' : data;
529
 
                            }
530
 
                        },
531
 
                        {"data": "transition"},
532
 
                        {
533
 
                            "orderable": false,
534
 
                            "data": dataTableButtonsColumn
535
 
                        }
536
 
                    ]
537
 
                });
538
 
 
539
 
                timelineWidgetTabel.on('draw', dataTableDraw);
540
 
                timelineWidgetTabel.on('processing.dt', dataTableProcessing);
541
 
 
542
 
                // Hook up the library Upload Buttons
543
 
                $(".libraryUploadForm").click(libraryUploadClick);
544
 
            }
545
 
 
546
 
            function DeleteRegion(form, regionId) {
 
426
            });
 
427
 
 
428
            footer.find(".btn-primary").before(replaceButton);
 
429
        }
 
430
 
 
431
        function timelineGridCallback(dialog) {
 
432
 
 
433
            dialog.addClass("modal-big");
 
434
 
 
435
            var timelineWidgetTabel = $("#timelineWidgets").DataTable({ "language": dataTablesLanguage,
 
436
                serverSide: true, stateSave: true,
 
437
                filter: false,
 
438
                searchDelay: 3000,
 
439
                "order": [[ 0, "asc"]],
 
440
                ajax: {
 
441
                    url: "{{ urlFor("playlist.widget.search") }}",
 
442
                    "data": function(d) {
 
443
                        $.extend(d, $("#timelineWidgets").closest(".XiboGrid").find(".FilterDiv form").serializeObject());
 
444
                    }
 
445
                },
 
446
                "columns": [
 
447
                    { "data": "displayOrder" },
 
448
                    { "data": "name", "orderable": false },
 
449
                    { "data": "type" },
 
450
                    { "data": "duration" },
 
451
                    { "data": "transition" },
 
452
                    {
 
453
                        "orderable": false,
 
454
                        "data": dataTableButtonsColumn
 
455
                    }
 
456
                ]
 
457
            });
 
458
 
 
459
            timelineWidgetTabel.on('draw', dataTableDraw);
 
460
            timelineWidgetTabel.on('processing.dt', dataTableProcessing);
 
461
        }
 
462
 
 
463
        function DeleteRegion(form, regionId) {
 
464
            $.ajax({
 
465
                type: form.attr("method"),
 
466
                url: form.attr("action"),
 
467
                cache: false,
 
468
                dataType: "json",
 
469
                data: form.serialize(),
 
470
                success: function(xhr, textStatus, error) {
 
471
 
 
472
                    XiboSubmitResponse(xhr, form);
 
473
 
 
474
                    if (xhr.success)
 
475
                        $("#region_" + regionId).remove();
 
476
                },
 
477
                error: function(xhr, textStatus, errorThrown) {
 
478
                    SystemMessage(xhr.responseText, false);
 
479
                }
 
480
            });
 
481
        }
 
482
 
 
483
        // Bind to the add button when we load
 
484
        $(document).ready(function() {
 
485
 
 
486
            // Add region button
 
487
            $("#regionAddButton").click(function(e) {
 
488
                e.preventDefault();
547
489
                $.ajax({
548
 
                    type: form.attr("method"),
549
 
                    url: form.attr("action"),
550
 
                    cache: false,
551
 
                    dataType: "json",
552
 
                    data: form.serialize(),
553
 
                    success: function (xhr, textStatus, error) {
554
 
 
555
 
                        XiboSubmitResponse(xhr, form);
556
 
 
557
 
                        if (xhr.success)
558
 
                            $("#region_" + regionId).remove();
559
 
                    },
560
 
                    error: function (xhr, textStatus, errorThrown) {
561
 
                        SystemMessage(xhr.responseText, false);
 
490
                    type: "post",
 
491
                    url: $(this).attr("href"),
 
492
                    cache:false,
 
493
                    dataType:"json",
 
494
                    success: function(xhr, textStatus, error) {
 
495
 
 
496
                        XiboSubmitResponse(xhr);
 
497
 
 
498
                        if (xhr.success) {
 
499
                            // Reload the designer
 
500
                            window.location.reload();
 
501
                        }
562
502
                    }
563
503
                });
564
 
            }
565
 
 
566
 
            // Bind to the add button when we load
567
 
            $(document).ready(function () {
568
 
 
569
 
                // Add region button
570
 
                $("#regionAddButton").click(function (e) {
571
 
                    e.preventDefault();
572
 
                    $.ajax({
573
 
                        type: "post",
574
 
                        url: $(this).attr("href"),
575
 
                        cache: false,
576
 
                        dataType: "json",
577
 
                        success: function (xhr, textStatus, error) {
578
 
 
579
 
                            XiboSubmitResponse(xhr);
580
 
 
581
 
                            if (xhr.success) {
582
 
                                // Reload the designer
583
 
                                window.location.reload();
584
 
                            }
585
 
                        }
586
 
                    });
587
 
                });
588
504
            });
589
 
 
590
 
            $("[name='my-checkbox']").bootstrapSwitch();
591
 
 
592
 
 
593
 
 
594
 
        </script>
595
 
 
596
 
 
597
 
        {% for module in modules %}
598
 
            {% if module.layoutDesignerJavaScript() != "" %}
599
 
                {% include module.layoutDesignerJavaScript() ~ ".twig" %}
600
 
            {% endif %}
601
 
        {% endfor %}
602
 
 
603
 
    {% endblock %}
 
505
        });
 
506
    </script>
 
507
 
 
508
    {% for module in modules  %}
 
509
        {% if module.layoutDesignerJavaScript() != "" %}
 
510
            {% include module.layoutDesignerJavaScript() ~ ".twig" %}
 
511
        {% endif %}
 
512
    {% endfor %}
 
513
 
 
514
{% endblock %}