Browse Source

Merge "Replaces multi select combos with transfer tables"

Zuul 1 year ago
parent
commit
84cac65360

+ 3
- 0
gbpui/_1550_gbp_project_add_panel_group.py View File

@@ -14,3 +14,6 @@ ADD_INSTALLED_APPS = ['gbpui', ]
14 14
 PANEL_GROUP = 'GroupPolicyPanels'
15 15
 PANEL_GROUP_NAME = 'Policy'
16 16
 PANEL_GROUP_DASHBOARD = 'project'
17
+
18
+AUTO_DISCOVER_STATIC_FILES = True
19
+ADD_ANGULAR_MODULES = ['gbpui', ]

+ 80
- 0
gbpui/fields.py View File

@@ -16,6 +16,11 @@ from django.forms import TextInput
16 16
 from django.forms import widgets
17 17
 from django.utils.safestring import mark_safe
18 18
 
19
+from django.forms.utils import flatatt
20
+from django.utils.html import format_html
21
+
22
+from django.utils.translation import ugettext_lazy as _
23
+
19 24
 
20 25
 class DynamicMultiSelectWidget(widgets.SelectMultiple):
21 26
 
@@ -84,3 +89,78 @@ class DropdownEditWidget(TextInput):
84 89
             data_list += '<option value="%s">' % item
85 90
         data_list += '</datalist>'
86 91
         return mark_safe(text_html + data_list)
92
+
93
+
94
+class TransferTableWidget(widgets.SelectMultiple):
95
+    actions_list = []
96
+    add_item_link = None
97
+    max_items = None
98
+    allocated_filter = False
99
+
100
+    allocated_help_text = None
101
+    available_help_text = None
102
+    no_allocated_text = None
103
+    no_available_text = None
104
+
105
+    def render(self, name, value, attrs=None, choices=()):
106
+        # css class currently breaks the layout for some reason,
107
+        self.attrs.pop('class', None)
108
+
109
+        final_attrs = self.build_attrs(attrs, name=name)
110
+
111
+        selected = [] if value is None else value
112
+
113
+        options = self.render_options(choices, selected)
114
+
115
+        if self.add_item_link is not None:
116
+            final_attrs['add_item_link'] = urlresolvers.reverse(
117
+                self.add_item_link
118
+            )
119
+
120
+        if self.max_items is not None:
121
+            final_attrs['max_items'] = self.max_items
122
+
123
+        if self.allocated_filter:
124
+            final_attrs['allocated_filter'] = "True"
125
+
126
+        final_attrs['allocated_help_text'] = self.allocated_help_text
127
+        final_attrs['available_help_text'] = self.available_help_text
128
+        final_attrs['no_allocated_text'] = self.no_allocated_text
129
+        final_attrs['no_available_text'] = self.no_available_text
130
+
131
+        open_tag = format_html('<d-table {}>', flatatt(final_attrs))
132
+
133
+        output = [open_tag, options, '</d-table>']
134
+
135
+        return mark_safe('\n'.join(output))
136
+
137
+    # ...this adds the 'add item button' just by existing and returning a
138
+    # true-y value
139
+    def get_add_item_url(self):
140
+        return None
141
+
142
+
143
+class TransferTableField(fields.MultipleChoiceField):
144
+    widget = TransferTableWidget
145
+
146
+    def __init__(self, add_item_link=None, max_items=-1,
147
+                 allocated_filter=False,
148
+                 allocated_help_text="",
149
+                 available_help_text="",
150
+                 no_allocated_text=_("Select items from bellow"),
151
+                 no_available_text=_("No available items"),
152
+                 *args, **kwargs):
153
+        super(TransferTableField, self).__init__(*args, **kwargs)
154
+
155
+        self.widget.add_item_link = add_item_link
156
+        self.widget.max_items = max_items
157
+        self.widget.allocated_filter = allocated_filter
158
+
159
+        self.widget.allocated_help_text = allocated_help_text
160
+        self.widget.available_help_text = available_help_text
161
+
162
+        self.widget.no_allocated_text = no_allocated_text
163
+        self.widget.no_available_text = no_available_text
164
+
165
+    def validate(self, *args, **kwargs):
166
+        return True

+ 9
- 3
gbpui/panels/application_policy/forms.py View File

@@ -55,7 +55,7 @@ class BaseUpdateForm(forms.SelfHandlingForm):
55 55
 class UpdatePolicyRuleSetForm(BaseUpdateForm):
56 56
     name = forms.CharField(label=_("Name"))
57 57
     description = forms.CharField(label=_("Description"), required=False)
58
-    policy_rules = forms.MultipleChoiceField(label=_("Policy Rules"),)
58
+    policy_rules = fields.TransferTableField(label=_("Policy Rules"), )
59 59
     shared = forms.BooleanField(label=_("Shared"), required=False)
60 60
 
61 61
     def __init__(self, request, *args, **kwargs):
@@ -298,7 +298,11 @@ class UpdatePolicyRuleForm(BaseUpdateForm):
298 298
     name = forms.CharField(max_length=80, label=_("Name"), required=False)
299 299
     description = forms.CharField(label=_("Description"), required=False)
300 300
     policy_classifier_id = forms.ChoiceField(label=_("Policy Classifier"))
301
-    policy_actions = forms.MultipleChoiceField(label=_("Policy Actions"))
301
+    policy_actions = fields.TransferTableField(
302
+        label=_("Policy Actions"),
303
+        required=False,
304
+    )
305
+
302 306
     shared = forms.BooleanField(label=_("Shared"), required=False)
303 307
 
304 308
     def __init__(self, request, *args, **kwargs):
@@ -306,17 +310,19 @@ class UpdatePolicyRuleForm(BaseUpdateForm):
306 310
         try:
307 311
             policyrule_id = self.initial['policyrule_id']
308 312
             rule = client.policyrule_get(request, policyrule_id)
313
+
309 314
             for item in ['name', 'description',
310 315
                          'policy_classifier_id', 'policy_actions', 'shared']:
311 316
                 self.fields[item].initial = getattr(rule, item)
317
+
312 318
             actions = client.policyaction_list(request,
313 319
                 tenant_id=request.user.tenant_id)
314
-            action_list = [a.id for a in actions]
315 320
             for action in actions:
316 321
                 action.set_id_as_name_if_empty()
317 322
             actions = sorted(actions, key=lambda action: action.name)
318 323
             action_list = [(a.id, a.name) for a in actions]
319 324
             self.fields['policy_actions'].choices = action_list
325
+
320 326
             classifiers = client.policyclassifier_list(request,
321 327
                 tenant_id=request.user.tenant_id)
322 328
             classifier_list = [(c.id, c.name) for c in classifiers]

+ 13
- 8
gbpui/panels/application_policy/workflows.py View File

@@ -21,6 +21,7 @@ from horizon import workflows
21 21
 from gbpui import client
22 22
 from gbpui import fields
23 23
 
24
+
24 25
 ADD_POLICY_ACTION_URL = "horizon:project:application_policy:addpolicyaction"
25 26
 ADD_POLICY_CLASSIFIER_URL = "horizon:project:application_policy:"
26 27
 ADD_POLICY_CLASSIFIER_URL = ADD_POLICY_CLASSIFIER_URL + "addpolicyclassifier"
@@ -28,11 +29,12 @@ ADD_POLICY_RULE_URL = "horizon:project:application_policy:addpolicyrule"
28 29
 
29 30
 
30 31
 class SelectPolicyRuleAction(workflows.Action):
31
-    policy_rules = fields.DynamicMultiChoiceField(
32
+    policy_rules = fields.TransferTableField(
32 33
         label=_("Policy Rules"),
33 34
         required=False,
34 35
         add_item_link=ADD_POLICY_RULE_URL,
35
-        help_text=_("Create a policy rule set with selected rules."))
36
+        help_text=_("Create a policy rule set with selected rules.")
37
+    )
36 38
 
37 39
     class Meta(object):
38 40
         name = _("Rules")
@@ -162,11 +164,17 @@ class SelectPolicyClassifierAction(workflows.Action):
162 164
 
163 165
 
164 166
 class SelectPolicyActionAction(workflows.Action):
165
-    actions = fields.DynamicMultiChoiceField(
167
+    actions = fields.TransferTableField(
166 168
         label=_("Policy Action"),
167 169
         required=False,
168
-        help_text=_("Create a policy-rule with selected action."),
169
-        add_item_link=ADD_POLICY_ACTION_URL)
170
+        add_item_link=ADD_POLICY_ACTION_URL,
171
+        help_text=_("Create a policy-rule with selected action.")
172
+    )
173
+
174
+    def __init__(self, request, context, *args, **kwargs):
175
+        super(SelectPolicyActionAction, self).__init__(
176
+            request, context, *args, **kwargs
177
+        )
170 178
 
171 179
     class Meta(object):
172 180
         name = _("actions")
@@ -176,14 +184,11 @@ class SelectPolicyActionAction(workflows.Action):
176 184
         try:
177 185
             actions = client.policyaction_list(request,
178 186
                 tenant_id=request.user.tenant_id)
179
-            action_list = [a.id for a in actions]
180 187
             for action in actions:
181 188
                 action.set_id_as_name_if_empty()
182 189
             actions = sorted(actions,
183 190
                              key=lambda action: action.name)
184 191
             action_list = [(a.id, a.name) for a in actions]
185
-            if len(action_list) > 0:
186
-                self.fields['actions'].initial = action_list[0]
187 192
         except Exception as e:
188 193
             action_list = []
189 194
             exceptions.handle(request,

+ 15
- 10
gbpui/panels/network_policy/forms.py View File

@@ -63,10 +63,11 @@ class AddL3PolicyForm(forms.SelfHandlingForm):
63 63
                                            label=_("Subnet Prefix Length"),
64 64
                                            help_text=_("Between 2 - 30 for IP4"
65 65
                                                        "and 2-127 for IP6."),)
66
-    external_segments = \
67
-        fields.CustomMultiChoiceField(label=_("External Segments"),
68
-                                      add_item_link=EXT_SEG_PARAM_URL,
69
-                                      required=False)
66
+    external_segments = fields.TransferTableField(
67
+        label=_("External Segments"),
68
+        add_item_link=EXT_SEG_PARAM_URL,
69
+        required=False
70
+    )
70 71
     shared = forms.BooleanField(label=_("Shared"),
71 72
                                 initial=False,
72 73
                                 required=False)
@@ -296,9 +297,11 @@ class CreateServicePolicyForm(forms.SelfHandlingForm):
296 297
     name = forms.CharField(max_length=80, label=_("Name"))
297 298
     description = forms.CharField(
298 299
         max_length=80, label=_("Description"), required=False)
299
-    network_service_params = fields.CustomMultiChoiceField(label=_(
300
-        "Network Service Parameters"), add_item_link=NETWORK_PARAM_URL,
301
-        required=False)
300
+    network_service_params = fields.TransferTableField(
301
+        label=_("Network Service Parameters"),
302
+        add_item_link=NETWORK_PARAM_URL,
303
+        required=False
304
+    )
302 305
     shared = forms.BooleanField(label=_("Shared"),
303 306
                                 initial=False, required=False)
304 307
 
@@ -555,9 +558,11 @@ class CreateExternalConnectivityForm(forms.SelfHandlingForm):
555 558
                                         "(e.g. 192.168.0.0/24,"
556 559
                                         "2001:DB8::/48)"),
557 560
                             version=forms.IPv4 | forms.IPv6, mask=True)
558
-    external_routes = fields.CustomMultiChoiceField(
559
-        label=_("External Routes"), add_item_link=ROUTE_URL,
560
-        required=False)
561
+    external_routes = fields.TransferTableField(
562
+        label=_("External Routes"),
563
+        add_item_link=ROUTE_URL,
564
+        required=False
565
+    )
561 566
     subnet_id = forms.ChoiceField(label=_("Subnet ID"), required=False)
562 567
     port_address_translation = forms.BooleanField(
563 568
         label=_("Port Address Translation"),

+ 9
- 6
gbpui/panels/policytargets/forms.py View File

@@ -22,6 +22,7 @@ from horizon import forms
22 22
 from horizon import messages
23 23
 
24 24
 from gbpui import client
25
+from gbpui import fields
25 26
 
26 27
 LOG = logging.getLogger(__name__)
27 28
 
@@ -31,10 +32,12 @@ class UpdatePolicyTargetForm(forms.SelfHandlingForm):
31 32
                            label=_("Name"), required=False)
32 33
     description = forms.CharField(max_length=80,
33 34
                                   label=_("Description"), required=False)
34
-    provided_policy_rule_sets = forms.MultipleChoiceField(
35
-        label=_("Provided Policy Rule Set"), required=False)
36
-    consumed_policy_rule_sets = forms.MultipleChoiceField(
37
-        label=_("Consumed Policy Rule Set"), required=False)
35
+    provided_policy_rule_sets = fields.TransferTableField(
36
+        label=_("Provided Policy Rule Set"), required=False
37
+    )
38
+    consumed_policy_rule_sets = fields.TransferTableField(
39
+        label=_("Consumed Policy Rule Set"), required=False
40
+    )
38 41
     l2_policy_id = forms.ChoiceField(
39 42
         label=_("Network Policy"),
40 43
         required=False,
@@ -141,9 +144,9 @@ class UpdateExternalPolicyTargetForm(forms.SelfHandlingForm):
141 144
                            label=_("Name"), required=False)
142 145
     description = forms.CharField(max_length=80,
143 146
                                   label=_("Description"), required=False)
144
-    provided_policy_rule_sets = forms.MultipleChoiceField(
147
+    provided_policy_rule_sets = fields.TransferTableField(
145 148
         label=_("Provided Policy Rule Set"), required=False)
146
-    consumed_policy_rule_sets = forms.MultipleChoiceField(
149
+    consumed_policy_rule_sets = fields.TransferTableField(
147 150
         label=_("Consumed Policy Rule Set"), required=False)
148 151
     external_segments = forms.MultipleChoiceField(
149 152
         label=_("External Connectivity"), required=True,

+ 9
- 12
gbpui/panels/policytargets/workflows.py View File

@@ -48,12 +48,12 @@ ADD_EXTERNAL_CONNECTIVITY = \
48 48
 
49 49
 
50 50
 class SelectPolicyRuleSetAction(workflows.Action):
51
-    provided_policy_rule_set = fields.DynamicMultiChoiceField(
51
+    provided_policy_rule_set = fields.TransferTableField(
52 52
         label=_("Provided Policy Rule Set"),
53 53
         help_text=_("Choose a policy rule set for an Group."),
54 54
         add_item_link=POLICY_RULE_SET_URL,
55 55
         required=False)
56
-    consumed_policy_rule_set = fields.DynamicMultiChoiceField(
56
+    consumed_policy_rule_set = fields.TransferTableField(
57 57
         label=_("Consumed Policy Rule Set"),
58 58
         help_text=_("Select consumed policy rule set for Group."),
59 59
         add_item_link=POLICY_RULE_SET_URL,
@@ -64,8 +64,10 @@ class SelectPolicyRuleSetAction(workflows.Action):
64 64
         help_text = _("Select Policy Rule Set for Group.")
65 65
 
66 66
     def _policy_rule_set_list(self, request):
67
-        policy_rule_sets = client.policy_rule_set_list(request,
68
-            tenant_id=request.user.tenant_id)
67
+        policy_rule_sets = client.policy_rule_set_list(
68
+            request,
69
+            tenant_id=request.user.tenant_id
70
+        )
69 71
         for c in policy_rule_sets:
70 72
             c.set_id_as_name_if_empty()
71 73
         policy_rule_sets = sorted(policy_rule_sets,
@@ -75,12 +77,8 @@ class SelectPolicyRuleSetAction(workflows.Action):
75 77
     def populate_provided_policy_rule_set_choices(self, request, context):
76 78
         policy_rule_set_list = []
77 79
         try:
78
-            rsets = self._policy_rule_set_list(request)
79
-            if len(rsets) == 0:
80
-                rsets.extend([('None', 'No Provided Policy Rule Sets')])
81
-            policy_rule_set_list = rsets
80
+            policy_rule_set_list = self._policy_rule_set_list(request)
82 81
         except Exception as e:
83
-            policy_rule_set_list = []
84 82
             msg = _('Unable to retrieve policy rule set. %s.') % (str(e))
85 83
             exceptions.handle(request, msg)
86 84
         return policy_rule_set_list
@@ -88,9 +86,7 @@ class SelectPolicyRuleSetAction(workflows.Action):
88 86
     def populate_consumed_policy_rule_set_choices(self, request, context):
89 87
         policy_rule_set_list = []
90 88
         try:
91
-            policy_rule_set_list = [('None', 'No Consumed Policy Rule Sets')]
92
-            policy_rule_set_list =\
93
-                self._policy_rule_set_list(request)
89
+            policy_rule_set_list = self._policy_rule_set_list(request)
94 90
         except Exception as e:
95 91
             msg = _('Unable to retrieve policy rule set. %s.') % (str(e))
96 92
             exceptions.handle(request, msg)
@@ -342,6 +338,7 @@ class SetAccessControlsAction(workflows.Action):
342 338
                                        help_text=_("Key pair to use for "
343 339
                                                    "authentication."),
344 340
                                        add_item_link=KEYPAIR_IMPORT_URL)
341
+
345 342
     admin_pass = forms.RegexField(
346 343
         label=_("Admin Password"),
347 344
         required=False,

+ 25
- 0
gbpui/static/dashboard/gbpui/gbpui.module.js View File

@@ -0,0 +1,25 @@
1
+/**
2
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
3
+ * not use this file except in compliance with the License. You may obtain
4
+ * a copy of the License at
5
+ *
6
+ *    http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
+ * License for the specific language governing permissions and limitations
12
+ * under the License.
13
+ */
14
+(function () {
15
+    angular
16
+        .module('gbpui', ['gbpui.transfer-table-bridge'])
17
+        .config(module_config);
18
+
19
+    module_config.$inject = ["$provide","$windowProvider"];
20
+
21
+    function module_config($provide, $windowProvider) {
22
+        var path = $windowProvider.$get().STATIC_URL + 'dashboard/gbpui/';
23
+        $provide.constant('gbpui.basePath', path);
24
+    }
25
+})();

+ 90
- 0
gbpui/static/dashboard/gbpui/transfer-table-bridge/d-select.directive.js View File

@@ -0,0 +1,90 @@
1
+/**
2
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
3
+ * not use this file except in compliance with the License. You may obtain
4
+ * a copy of the License at
5
+ *
6
+ *    http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
+ * License for the specific language governing permissions and limitations
12
+ * under the License.
13
+ */
14
+(function () {
15
+    angular
16
+        .module('gbpui.transfer-table-bridge')
17
+        .directive('dSelect', function () {
18
+            return {
19
+                restrict: 'A',
20
+                scope: true,
21
+                link: function ($scope, $elem, $attrs, $ctrl) {
22
+
23
+
24
+                    $.each($scope.tableData.available, function (index, optionObject) {
25
+                        var option = $("<option></option>");
26
+                        option.attr("value", optionObject.id);
27
+                        option.append(optionObject.name);
28
+                        $elem.append(option);
29
+                    });
30
+
31
+                    // This change listener watches for changes to the raw
32
+                    // HTML select element; since the select should be hidden,
33
+                    // the only possible change is the creation of a new
34
+                    // option using the horizon add button.
35
+                    $elem.change(function () {
36
+                        // Find the last option in the select, since the
37
+                        // addition is done by Horizon appending the a new
38
+                        // option element
39
+                        var option = $(this).find("option").last();
40
+
41
+                        // Create a valid option object and make it available
42
+                        // at the end of the available list
43
+                        var val = {
44
+                            'id': option.attr('value'),
45
+                            'name': option.text()
46
+                        };
47
+                        $scope.tableData.available.push(val);
48
+
49
+                        // Deallocate all the objects using the built in
50
+                        // transfer table controller deallocation method
51
+                        var toDeallocate = $scope.tableData.allocated.slice();
52
+                        $.each(toDeallocate, function (index, object) {
53
+                            $scope.trCtrl.deallocate(object);
54
+                        });
55
+                        // Notify the scope of the deallocations
56
+                        $scope.$apply();
57
+
58
+                        // Allocate the new option; this mimicks te behaviour
59
+                        // of the normal Horizon based adding
60
+                        $scope.trCtrl.allocate(val);
61
+
62
+                        // Notify the scope of the allocation changes
63
+                        $scope.$apply();
64
+                    });
65
+
66
+                    // The directive watches for a changes in the allocated
67
+                    // list to dynamically set values for the hidden element.
68
+                    $scope.$watchCollection(
69
+                        function (scope) {
70
+                            return $scope.tableData.allocated;
71
+                        },
72
+                        function (newValue, oldValue) {
73
+                            var values = $.map(
74
+                                newValue, function (value, index) {
75
+                                    return value.id;
76
+                                });
77
+                            $elem.val(values);
78
+                        }
79
+                    );
80
+
81
+                    // Sets initial values as allocated when appropriate
82
+                    $.each($scope.initial, function (index, initialObject) {
83
+                        $scope.trCtrl.allocate(initialObject);
84
+                    });
85
+
86
+
87
+                }
88
+            }
89
+        });
90
+})();

+ 91
- 0
gbpui/static/dashboard/gbpui/transfer-table-bridge/d-table.directive.js View File

@@ -0,0 +1,91 @@
1
+/**
2
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
3
+ * not use this file except in compliance with the License. You may obtain
4
+ * a copy of the License at
5
+ *
6
+ *    http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
+ * License for the specific language governing permissions and limitations
12
+ * under the License.
13
+ */
14
+(function () {
15
+    angular
16
+        .module('gbpui.transfer-table-bridge')
17
+        .directive('dTable', ['gbpui.basePath', function(basePath){
18
+            return {
19
+                restrict: 'E',
20
+                scope: true,
21
+                templateUrl: basePath +
22
+                    "transfer-table-bridge/transfer-table-bridge.html",
23
+                transclude: true,
24
+                link: function($scope, $elem, $attrs, $ctrl, $transclude) {
25
+
26
+                    var initial = [];
27
+                    var available = [];
28
+
29
+                    var transcluded = $transclude();
30
+
31
+                    transcluded.each(function(index, element) {
32
+                        if(element.localName=="option") {
33
+                            var val = {
34
+                                'id': $(element).attr('value'),
35
+                                'name': $(element).text()
36
+                            };
37
+                            available.push(val);
38
+
39
+                            if($(element).prop('selected')) {
40
+                                initial.push(val);
41
+                            }
42
+                        }
43
+                    });
44
+                    $scope.initial = initial;
45
+
46
+                    var allocated = [];
47
+
48
+                    $scope.tableData = {
49
+                        available: available,
50
+                        allocated: allocated,
51
+                        displayedAvailable: [],
52
+                        displayedAllocated: [],
53
+                        minItems: -1
54
+                    };
55
+
56
+                    var maxAllocation =  "maxItems" in $attrs
57
+                        ? Number($attrs["maxItems"])
58
+                        : -1;
59
+                    $scope.tableLimits = {
60
+                        maxAllocation: maxAllocation
61
+                    };
62
+
63
+                    $scope.tableHelpText = {
64
+                        allocHelpText: $attrs['allocatedHelpText'],
65
+                        availHelpText: $attrs['availableHelpText'],
66
+                        noAllocText: $attrs['noAllocatedText'],
67
+                        noAvailText: $attrs['noAvailableText']
68
+                    };
69
+
70
+                    $scope.facets = [{
71
+                            label: gettext("Name"),
72
+                            name: "name",
73
+                            singleton: true
74
+                    }];
75
+
76
+                    if("addItemLink" in $attrs) {
77
+                        $scope.addItemLink = $attrs["addItemLink"];
78
+                    }
79
+
80
+                    if("allocatedFilter" in $attrs) {
81
+                        $scope.allocatedFilter = true;
82
+                    }
83
+
84
+                    $scope.id = $attrs["id"];
85
+                    $scope.name = $attrs["name"];
86
+
87
+                }
88
+            }
89
+        }])
90
+
91
+})();

+ 114
- 0
gbpui/static/dashboard/gbpui/transfer-table-bridge/transfer-table-bridge.html View File

@@ -0,0 +1,114 @@
1
+<transfer-table tr-model="tableData" limits="tableLimits" help-text="tableHelpText">
2
+
3
+    <allocated ng-model="tableData.allocated.length">
4
+        <table  st-table="tableData.displayedAllocated"
5
+                st-safe-src="tableData.allocated"
6
+                hz-table
7
+                class="table table-striped table-rsp table-detail table-condensed">
8
+            <thead>
9
+                <tr ng-if="allocatedFilter">
10
+                    <th colspan="2">
11
+                        <hz-magic-search-bar filter-facets="facets"></hz-magic-search-bar>
12
+                    </th>
13
+                </tr>
14
+                <tr>
15
+                    <th colspan="2">Name</th>
16
+                </tr>
17
+            </thead>
18
+            <tbody>
19
+                <tr ng-if="tableData.allocated.length === 0">
20
+                    <td colspan="{{ addItemLink ? 2 : 1 }}">
21
+                         <div class="no-rows-help">
22
+                             {$ ::tableHelpText.noAllocText $}
23
+                         </div>
24
+                    </td>
25
+                </tr>
26
+                <tr ng-repeat="row in tableData.displayedAllocated track by row.id">
27
+                    <td>
28
+                        {$ row.name $}
29
+                    </td>
30
+                    <td class="actions_column">
31
+                        <action-list>
32
+                            <button tabIndex="0"
33
+                                    ng-class="'btn btn-default'"
34
+                                    ng-click="trCtrl.deallocate(row)"
35
+                                    type="button">
36
+                                <span class="fa fa-arrow-down"></span>
37
+                            </button>
38
+                        </action-list>
39
+                    </td>
40
+                </tr>
41
+            </tbody>
42
+        </table>
43
+    </allocated>
44
+
45
+    <available>
46
+        <table
47
+               st-table="tableData.displayedAvailable"
48
+               st-safe-src="tableData.available"
49
+               hz-table
50
+               class="table table-striped table-rsp table-detail table-condensed">
51
+            <thead>
52
+                <tr>
53
+                    <th colspan="{$ addItemLink ? 1 : 2 $}">
54
+                        <hz-magic-search-bar filter-facets="facets"></hz-magic-search-bar>
55
+                    </th>
56
+                    <th ng-if="addItemLink">
57
+                        <span class="input-group-btn">
58
+                            <a href="{$ addItemLink $}" data-add-to-field="{$ id $}_select" class="btn btn-default ajax-add ajax-modal">
59
+                                <span class="fa fa-plus"></span>
60
+                            </a>
61
+                        </span>
62
+                    </th>
63
+                </tr>
64
+                <tr>
65
+                    <th colspan="2">Name</th>
66
+                </tr>
67
+            </thead>
68
+            <tbody>
69
+
70
+                <tr ng-if="trCtrl.numAvailable() === 0">
71
+                    <td colspan="{{ addItemLink ? 2 : 1 }}">
72
+                        <div class="no-rows-help">
73
+                             {$ ::tableHelpText.noAvailText $}
74
+                        </div>
75
+                    </td>
76
+                </tr>
77
+
78
+                <tr ng-repeat="row in tableData.displayedAvailable track by row.id"
79
+                    ng-if="!trCtrl.allocatedIds[row.id]"
80
+                >
81
+                    <td>{$ row.name $}</td>
82
+                    <td class="actions_column">
83
+                        <action-list button-tooltip="row.warningMessage"
84
+                                     bt-model="ctrl.tooltipModel"
85
+                                     bt-disabled="!row.disabled"
86
+                                     warning-classes="'invalid'">
87
+                            <notifications>
88
+                                <span class="fa fa-exclamation-circle invalid"
89
+                                      ng-show="row.disabled"></span>
90
+                            </notifications>
91
+                            <button tabIndex="0"
92
+                                    ng-class="'btn btn-default'"
93
+                                    ng-click="trCtrl.allocate(row)"
94
+                                    type="button">
95
+                                <span class="fa fa-arrow-up"></span>
96
+                            </button>
97
+                        </action-list>
98
+                    </td>
99
+                </tr>
100
+            </tbody>
101
+        </table>
102
+
103
+        <div style="display:None">
104
+            <select
105
+                    d-select
106
+                    id="{$ id $}_select"
107
+                    data-add-item-url
108
+                    multiple
109
+                    name="{$ name $}" >
110
+            </select>
111
+        </div>
112
+    </available>
113
+
114
+</transfer-table>

+ 17
- 0
gbpui/static/dashboard/gbpui/transfer-table-bridge/transfer-table.module.js View File

@@ -0,0 +1,17 @@
1
+/**
2
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
3
+ * not use this file except in compliance with the License. You may obtain
4
+ * a copy of the License at
5
+ *
6
+ *    http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
+ * License for the specific language governing permissions and limitations
12
+ * under the License.
13
+ */
14
+(function () {
15
+    angular
16
+        .module('gbpui.transfer-table-bridge', ['horizon.app.core.workflow']);
17
+})();

Loading…
Cancel
Save