Merge ~lyubomir-popov/maas:ellipsis into maas:master

Proposed by Lyubomir Popov
Status: Rejected
Rejected by: Adam Collard
Proposed branch: ~lyubomir-popov/maas:ellipsis
Merge into: maas:master
Diff against target: 2453 lines (+1115/-978)
25 files modified
src/maasserver/static/partials/machines-table.html (+131/-125)
src/maasserver/static/partials/node-details.html (+24/-21)
src/maasserver/static/scss/_breakpoints.scss (+47/-0)
src/maasserver/static/scss/_settings.scss (+2/-0)
src/maasserver/static/scss/_settings_breakpoints.scss (+5/-0)
src/maasserver/static/scss/_tables.scss (+202/-831)
src/maasserver/static/scss/_utilities_breakpoints.scss (+47/-0)
src/maasserver/static/scss/_utilities_hide.scss (+25/-0)
src/maasserver/static/scss/_utils.scss (+5/-0)
src/maasserver/static/scss/build.scss (+0/-1)
src/maasserver/static/scss/tables/_bcache.scss (+21/-0)
src/maasserver/static/scss/tables/_controller-interfaces.scss (+48/-0)
src/maasserver/static/scss/tables/_controller-vlans.scss (+29/-0)
src/maasserver/static/scss/tables/_controllers-commissioning.scss (+27/-0)
src/maasserver/static/scss/tables/_controllers.scss (+31/-0)
src/maasserver/static/scss/tables/_create-raid.scss (+24/-0)
src/maasserver/static/scss/tables/_create-volume-group.scss (+21/-0)
src/maasserver/static/scss/tables/_devices.scss (+31/-0)
src/maasserver/static/scss/tables/_disk-partitions.scss (+43/-0)
src/maasserver/static/scss/tables/_images.scss (+27/-0)
src/maasserver/static/scss/tables/_machines.scss (+153/-0)
src/maasserver/static/scss/tables/_network-discovery.scss (+37/-0)
src/maasserver/static/scss/tables/_pod-networking-config.scss (+58/-0)
src/maasserver/static/scss/tables/_pod-storage-config.scss (+38/-0)
src/maasserver/static/scss/tables/_pods.scss (+39/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Needs Fixing
Anthony Dillon Needs Fixing
Andres Rodriguez (community) Approve
Caleb Ellis (community) Needs Fixing
Review via email: mp+367116@code.launchpad.net

Commit message

Refactor the huge _tables.scss file;
implement horizontal 3-dot contextual menu icon;
replace ellipsis with a subtle fade

To post a comment you must log in.
Revision history for this message
Caleb Ellis (caleb-ellis) wrote :

Just a few things need fixing:
- In table column header, text for IP is 14px but everywhere else is 12.25px.
- There's hanging markup on line 140 of machines-table.html. Can you please re-add it so you can view by MAC address (i.e. click on MAC)?
- Can you add a conditional class for p-table-menu if hideActions is true that makes it so hovering over a row does not truncate text if the chevron won't show.
  e.g. data-ng-class="{'is-hidden': hideActions}"
  Otherwise in the pod details machine list the text gets truncated on hover for no reason
https://user-images.githubusercontent.com/25733845/57619864-f21fa500-757e-11e9-8d2a-c8d5780e185e.png

review: Needs Fixing
Revision history for this message
Andres Rodriguez (andreserl) wrote :

This seems the type of refactoring we don't want to do right before we are about to release a Release Candidate or a Final release.

Since technically master is frozen with the exception of bug fixes, ESXi and Dismiss test work, is there a reason why this would need to land now?

review: Needs Information
Revision history for this message
Lyubomir Popov (lyubomir-popov) wrote :

Caleb thanks for catching those, should be all fixed now.
Andres just trying to get the functionality nailed, not insisting on merging this now.

Revision history for this message
Andres Rodriguez (andreserl) wrote :

master is now open for development, feel free to land!

review: Approve
Revision history for this message
Lyubomir Popov (lyubomir-popov) wrote :

Thanks, this is with a lower priority now, I will try to merge once the vanilla upgrades are complete.

~lyubomir-popov/maas:ellipsis updated
5f7c8bd... by Lyubomir Popov

var-renaming

a541445... by Lyubomir Popov

fix merge issues and a rename

ffc26ed... by Lyubomir Popov

prettier

04d5042... by Lyubomir Popov

fixes

a992099... by Lyubomir Popov

fixes

Revision history for this message
Lyubomir Popov (lyubomir-popov) wrote :

This is ready for re-review.

Revision history for this message
Anthony Dillon (ya-bo-ng) wrote :

Looks good! Few comments inline and some QA issues:
- Hovers on table jump
- Machine names do not ellipse anymore

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b ellipsis lp:~lyubomir-popov/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci-jenkins.internal:8080/job/maas/job/branch-tester/6128/console
COMMIT: a99209990c39fc9dc3f3da484f6eb0fe15d934e6

review: Needs Fixing

Unmerged commits

a992099... by Lyubomir Popov

fixes

04d5042... by Lyubomir Popov

fixes

ffc26ed... by Lyubomir Popov

prettier

a541445... by Lyubomir Popov

fix merge issues and a rename

5f7c8bd... by Lyubomir Popov

var-renaming

c639846... by Lyubomir Popov <email address hidden>

refactor tables.scss; improve p-table-menu__toggle

remove duplicated code

remove redundant line

refactor selector for clarity

remove duplicate code; place all global vars in one place

refactor; hover fade of overflowing text fixes fix

move placeholders to top;adjust bg fade

replace fade and dots with chevron; refactor;

fix pool desc overflow

fix column alignment for cores; ip muted row fixes (wip
)

wip: ip, pxe, ipcount and truncation

remove bg color of ip count string

address feedback

fix interfaces double row wrapping regression

conditionally hide checkbox parent

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/static/partials/machines-table.html b/src/maasserver/static/partials/machines-table.html
2index cb0f4fb..35cd7e4 100644
3--- a/src/maasserver/static/partials/machines-table.html
4+++ b/src/maasserver/static/partials/machines-table.html
5@@ -1,19 +1,21 @@
6 <table class="p-table--sortable p-table--machines" role="grid">
7 <thead>
8 <tr class="p-table__header p-table__row">
9- <th class="p-table__col--name p-double-row u-align--left">
10- <div class="p-double-row__checkbox" data-ng-if="!hideActions">
11- <input class="checkbox" type="checkbox" data-ng-click="toggleCheckAll()" data-ng-checked="table.allViewableChecked" id="check-all" data-ng-disabled="ngDisabled()" />
12- <label class="p-checkbox--action" for="check-all" ng-class="getAllCheckboxClass(table.filteredMachines)"></label>
13- </div>
14- <div class="p-double-row__rows-container--checkbox">
15- <div>
16- <span role="columnheader" data-ng-click="selectColumnOrSort('fqdn')" data-ng-class="{'is-active': table.column === 'fqdn', 'is-sorted': table.predicate === 'fqdn', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="FQDN">FQDN</span>
17- |
18- <span role="columnheader" data-ng-click="selectColumnOrSort('pxe_mac')" data-ng-class="{'is-active': table.column === 'pxe_mac', 'is-sorted': table.predicate === 'pxe_mac', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="MAC">MAC</span>
19+ <th class="p-table__col--name p-double-row">
20+ <div class="p-double-row__wrapper">
21+ <div class="p-double-row__checkbox" data-ng-if="!hideActions">
22+ <input class="checkbox" type="checkbox" data-ng-click="toggleCheckAll()" data-ng-checked="table.allViewableChecked" id="check-all" data-ng-disabled="ngDisabled()" />
23+ <label class="p-checkbox--action" for="check-all" ng-class="getAllCheckboxClass(table.filteredMachines)"></label>
24 </div>
25- <div>
26- <span role="columnheader" data-ng-click="sortTable('ip_addresses[0]')" data-ng-class="{'is-active': table.column === 'ip_addresses[0]', 'is-sorted': table.predicate === 'ip_addresses[0]', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="IP">IP</span>
27+ <div class="p-double-row__rows-container--checkbox">
28+ <div class="p-double-row__main-row">
29+ <span role="columnheader" data-ng-click="selectColumnOrSort('fqdn')" data-ng-class="{'is-active': table.column === 'fqdn', 'is-sorted': table.predicate === 'fqdn', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="FQDN">FQDN</span>
30+ |
31+ <span role="columnheader" data-ng-click="selectColumnOrSort('pxe_mac')" data-ng-class="{'is-active': table.column === 'pxe_mac', 'is-sorted': table.predicate === 'pxe_mac', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="MAC">MAC</span>
32+ </div>
33+ <div class="p-double-row__muted-header">
34+ <span role="columnheader" data-ng-click="sortTable('ip_addresses[0]')" data-ng-class="{'is-active': table.column === 'ip_addresses[0]', 'is-sorted': table.predicate === 'ip_addresses[0]', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="IP">IP</span>
35+ </div>
36 </div>
37 </div>
38 </th>
39@@ -21,11 +23,13 @@
40 <span class="u-hide--br3"><i class="p-icon--placeholder"></i>Power</span>
41 </th>
42 <th class="p-table__col--status p-double-row" title="Status">
43- <div class="p-double-row__icon-container">
44- <i class="p-icon--placeholder"></i>
45- </div>
46- <div class="p-double-row__rows-container--icon">
47- <span role="columnheader" data-ng-click="sortTable('status')" data-ng-class="{'is-sorted': table.predicate === 'status', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="Status">Status</span>
48+ <div class="p-double-row__wrapper">
49+ <div class="p-double-row__icon-container">
50+ <i class="p-icon--placeholder"></i>
51+ </div>
52+ <div class="p-double-row__rows-container--icon">
53+ <span role="columnheader" data-ng-click="sortTable('status')" data-ng-class="{'is-sorted': table.predicate === 'status', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="Status">Status</span>
54+ </div>
55 </div>
56 </th>
57 <th class="p-table__col--owner p-double-row" title="Owner, Tags">
58@@ -65,7 +69,7 @@
59 'p-table__placeholder': group.label === 'none'
60 }"
61 >
62- <th class="p-table__group-label p-table__col--name p-double-row u-align--left">
63+ <th class="p-table__group-label p-table__col--name p-double-row">
64 <input type="checkbox" id="{$ group.label $}" data-ng-click="toggleCheckGroup(group.label)" data-ng-checked="getGroupSelectedState(group.label)" />
65 <label class="p-checkbox--action u-no-margin--bottom" for="{$ group.label $}">{$ group.label $}</label>
66 <div class="p-muted-text">{$ getGroupCountString(group.label) $}</div>
67@@ -98,33 +102,37 @@
68 'is-grouped': group.label !== 'none'
69 }">
70 <td class="p-table__col--name p-double-row" aria-label="FQDN" data-ng-if="table.column === 'fqdn' || table.column === 'ip_address'">
71- <div class="p-double-row__checkbox" data-ng-if="!hideActions">
72- <input type="checkbox" data-ng-click="toggleChecked(node)" data-ng-checked="node.$selected" id="{$ node.fqdn $}" data-ng-disabled="ngDisable()" />
73- <label class="p-checkbox--action" for="{$ node.fqdn $}" ng-class="getCheckboxClass(node)"></label>
74- </div>
75- <div class="p-double-row__rows-container--checkbox">
76- <div class="p-double-row__main-row">
77- <a class="p-domain-name u-text-overflow" href="#/{$ node.link_type $}/{$ node.system_id $}" title="{$ node.fqdn $}">
78- <span data-ng-if="node.locked" title="This machine is locked. You have to unlock it to perform any actions." aria-describedby="{$ node.fqdn $}-locked-state">
79- <i class="p-icon--locked">Locked: </i>
80- </span>
81- <span class="p-domain-name__host">{$ node.hostname $}</span><span class="p-domain-name__tld">.{$ node.domain.name $}</span>
82- </a>
83+ <div class="p-double-row__wrapper">
84+ <div class="p-double-row__checkbox" data-ng-if="!hideActions">
85+ <input type="checkbox" data-ng-click="toggleChecked(node)" data-ng-checked="node.$selected" id="{$ node.fqdn $}" data-ng-disabled="ngDisable()" />
86+ <label class="p-checkbox--action" for="{$ node.fqdn $}" ng-class="getCheckboxClass(node)"></label>
87 </div>
88- <span class="p-tooltip--bottom-left" aria-describedby="ip-addresses-{$ node.fqdn $}">
89- <div data-ng-if="removeDuplicates(node.ip_addresses, 'ip').length" class="p-double-row__muted-row">
90- <span class="u-text-overflow">
91- <span>{$ getBootIp(node.ip_addresses) || node.ip_addresses[0].ip $}</span><span data-ng-if="getBootIp(node.ip_addresses)"> (PXE)</span>
92- <span data-ng-if="removeDuplicates(node.ip_addresses, 'ip').length > 1">(+{$ removeDuplicates(node.ip_addresses, 'ip').length - 1 $})</span>
93- </span>
94- <span class="p-tooltip__message" style="white-space:initial;left:3.5rem" role="tooltip" data-ng-if="removeDuplicates(node.ip_addresses, 'ip').length > 1" id="ip-addresses-{$ node.fqdn $}">
95- <div><strong>{$ removeDuplicates(node.ip_addresses, 'ip').length $} interfaces:</strong></div>
96- <div data-ng-repeat="ip_address in removeDuplicates(node.ip_addresses, 'ip')">
97- <span>{$ ip_address.ip $}</span><span data-ng-if="ip_address.is_boot"> (PXE)</span>
98- </div>
99- </span>
100+
101+ <div class="p-double-row__rows-container--checkbox">
102+ <div class="p-double-row__main-row">
103+ <a class="p-domain-name u-text-overflow" href="#/{$ node.link_type $}/{$ node.system_id $}" title="{$ node.fqdn $}">
104+ <span data-ng-if="node.locked" title="This machine is locked. You have to unlock it to perform any actions." aria-describedby="{$ node.fqdn $}-locked-state">
105+ <i class="p-icon--locked">Locked: </i>
106+ </span>
107+ <span class="p-domain-name__host">{$ node.hostname $}</span><span class="p-domain-name__tld">.{$ node.domain.name $}</span>
108+ </a>
109 </div>
110- </span>
111+ <span class="p-tooltip--bottom-left" aria-describedby="ip-addresses-{$ node.fqdn $}">
112+ <div data-ng-if="removeDuplicates(node.ip_addresses, 'ip').length" class="p-double-row__muted-row">
113+ <span class="u-text-overflow">
114+ <span>{$ getBootIp(node.ip_addresses) || node.ip_addresses[0].ip $}</span>
115+ <span data-ng-if="getBootIp(node.ip_addresses)"> (PXE)</span>
116+ <span data-ng-if="removeDuplicates(node.ip_addresses, 'ip').length > 1">(+{$ removeDuplicates(node.ip_addresses, 'ip').length - 1 $})</span>
117+ </span>
118+ <span class="p-tooltip__message" style="white-space:initial" role="tooltip" data-ng-if="removeDuplicates(node.ip_addresses, 'ip').length > 1" id="ip-addresses-{$ node.fqdn $}">
119+ <div><strong>{$ removeDuplicates(node.ip_addresses, 'ip').length $} interfaces:</strong></div>
120+ <div data-ng-repeat="ip_address in removeDuplicates(node.ip_addresses, 'ip')">
121+ <span>{$ ip_address.ip $}</span><span data-ng-if="ip_address.is_boot"> (PXE)</span>
122+ </div>
123+ </span>
124+ </div>
125+ </span>
126+ </div>
127 </div>
128 </td>
129 <td class="p-table__col--name" aria-label="MAC" data-ng-if="table.column === 'pxe_mac'">
130@@ -155,43 +163,43 @@
131 <div class="p-double-row__rows-container--icon u-hide--br3">
132 <div class="p-double-row__main-row u-upper-case--first">
133 <span class="u-text-overflow" title="{$ node.power_state $}">{$ node.power_state $}</span>
134- <button
135- class="p-table-menu__toggle p-icon--chevron u-hide--br3"
136- data-ng-if="!hideActions"
137- data-ng-class="{'u-mirror--y' : openMenu === node.system_id + '-power'}"
138- data-ng-click="toggleMenu(node.system_id + '-power')"
139- ></button>
140 </div>
141+ <button
142+ class="p-table-menu__toggle p-icon--chevron u-hide--br3"
143+ data-ng-if="!hideActions"
144+ data-ng-class="{'u-mirror--y' : openMenu === node.system_id + '-power'}"
145+ data-ng-click="toggleMenu(node.system_id + '-power')"
146+ ></button>
147 <div class="p-double-row__muted-row u-upper-case--first">
148 <span class="u-text-overflow" title="{$ node.power_type $}">{$ node.power_type $}</span>
149 </div>
150 </div>
151 <span class="p-table-menu__dropdown" data-ng-if="!node.powerTransition && openMenu === node.system_id + '-power'">
152- <div class="p-table-menu__title--icon">Take action:</div>
153+ <div class="p-table-menu__title">Take action:</div>
154 <button
155- class="p-table-menu__power-on"
156+ class="p-table-menu__link p-table-menu__power-on"
157 data-ng-click="changePowerState(node, 'on')"
158 data-ng-if="node.actions.indexOf('on') !== -1 && node.power_state !== 'on'"
159 >
160 Turn on
161 </button>
162 <button
163- class="p-table-menu__power-off"
164+ class="p-table-menu__link p-table-menu__power-off"
165 data-ng-click="changePowerState(node, 'off')"
166 data-ng-if="node.actions.indexOf('off') !== -1 && node.power_state !== 'off'"
167 >
168 Turn off
169 </button>
170 <button
171+ class="p-table-menu__link p-table-menu__check-power"
172 data-ng-click="changePowerState(node, 'check')"
173- class="p-table-menu__check-power"
174 data-ng-if="node.power_state !== 'unknown'"
175 >
176 Check power
177 </button>
178 <button
179+ class="p-table-menu__link p-table-menu__check-power"
180 data-ng-if="node.actions.indexOf('on') === -1 && node.actions.indexOf('off') === -1 && node.power_state === 'unknown'"
181- class="p-table-menu__check-power"
182 disabled
183 >
184 No power actions available
185@@ -230,7 +238,6 @@
186 <span
187 class="p-table-menu__dropdown"
188 data-ng-if="openMenu === node.system_id + '-status'"
189- style="left: .5rem"
190 >
191 <div class="p-table-menu__title">Take action:</div>
192 <div class="p-contextual-menu__group" data-ng-if="getStatusActions(node).length">
193@@ -264,42 +271,43 @@
194 <div class="p-double-row__rows-container">
195 <div class="p-double-row__main-row" aria-label="Owner">
196 <i class="p-icon--spinner u-animation--spin" data-ng-if="node['acquire-transition'] || node['release-transition']">Changing owner</i>
197- <span class="u-text-overflow" data-ng-if="node.owner">{$ node.owner $}</span>
198- <span class="u-text-overflow" data-ng-if="!node.owner">-</span>
199- <button
200- class="p-table-menu__toggle p-icon--chevron"
201- data-ng-if="!hideActions"
202- data-ng-class="{'u-mirror--y' : openMenu === node.system_id + '-owner'}"
203- data-ng-click="toggleMenu(node.system_id + '-owner')"
204- ></button> </div>
205+ <span data-ng-if="node.owner">{$ node.owner $}</span>
206+ <span data-ng-if="!node.owner">-</span>
207+ </div>
208+ <button
209+ class="p-table-menu__toggle p-icon--chevron u-hide--br2"
210+ data-ng-if="!hideActions"
211+ data-ng-class="{'u-mirror--y' : openMenu === node.system_id + '-owner'}"
212+ data-ng-click="toggleMenu(node.system_id + '-owner')"
213+ ></button>
214 <div data-ng-if="node.tags.length !== 0" class="p-double-row__muted-row" aria-label="Tags" title="{$ node.tags.join(', ') $}">
215 <span class="u-text-overflow">{$ node.tags.join(', ') $}</span>
216 </div>
217+ <span class="p-table-menu__dropdown" data-ng-if="openMenu === node.system_id + '-owner'">
218+ <div class="p-table-menu__title">Take action:</div>
219+ <button
220+ data-ng-if="node.actions.indexOf('acquire') !== -1"
221+ data-ng-click="performAction(node, 'acquire')"
222+ class="p-table-menu__link"
223+ >
224+ {$ getActionTitle('acquire') $}
225+ </button>
226+ <button
227+ data-ng-if="node.actions.indexOf('release') !== -1"
228+ data-ng-click="performAction(node, 'release')"
229+ class="p-table-menu__link"
230+ >
231+ {$ getActionTitle('release') $}
232+ </button>
233+ <button
234+ data-ng-if="node.actions.indexOf('acquire') === -1 && node.actions.indexOf('release') === -1"
235+ class="p-table-menu__link"
236+ disabled
237+ >
238+ No owner actions available
239+ </button>
240+ </span>
241 </div>
242- <span class="p-table-menu__dropdown" data-ng-if="openMenu === node.system_id + '-owner'">
243- <div class="p-table-menu__title">Take action:</div>
244- <button
245- data-ng-if="node.actions.indexOf('acquire') !== -1"
246- data-ng-click="performAction(node, 'acquire')"
247- class="p-table-menu__link"
248- >
249- {$ getActionTitle('acquire') $}
250- </button>
251- <button
252- data-ng-if="node.actions.indexOf('release') !== -1"
253- data-ng-click="performAction(node, 'release')"
254- class="p-table-menu__link"
255- >
256- {$ getActionTitle('release') $}
257- </button>
258- <button
259- data-ng-if="node.actions.indexOf('acquire') === -1 && node.actions.indexOf('release') === -1"
260- class="p-table-menu__link"
261- disabled
262- >
263- No owner actions available
264- </button>
265- </span>
266 </div>
267 </td>
268 <td class="p-table__col--pool p-double-row" aria-label="Pool, Note">
269@@ -309,15 +317,15 @@
270 <i class="p-icon--spinner u-animation--spin" data-ng-if="node['set-pool-transition']">Setting pool</i>
271 <span class="u-text-overflow" data-ng-if="node.pool.name"><a class="p-link--soft" href="#/pools" title="{$ node.pool.name $}"> {$ node.pool.name $}</a></span>
272 <span class="u-text-overflow" data-ng-if="!node.pool.name">-</span>
273- <button
274- class="p-table-menu__toggle p-icon--chevron u-hide--br3"
275- data-ng-if="node.actions.indexOf('set-pool') !== -1 && !hideActions"
276- data-ng-class="{'u-mirror--y' : openMenu === node.system_id + '-pool'}"
277- data-ng-click="toggleMenu(node.system_id + '-pool')"
278- ></button>
279 </div>
280- <div class="p-double-row__muted-row" aria-label="Note" title="{$ node.description $}">
281- <span class="u-text-overflow" data-ng-if="node.description">{$ node.description $}</span>
282+ <button
283+ class="p-table-menu__toggle p-icon--chevron u-hide--br3"
284+ data-ng-if="node.actions.indexOf('set-pool') !== -1 && !hideActions"
285+ data-ng-class="{'u-mirror--y' : openMenu === node.system_id + '-pool'}"
286+ data-ng-click="toggleMenu(node.system_id + '-pool')"
287+ ></button>
288+ <div class="p-double-row__muted-row" aria-label="Note" title="{$ node.description $}" data-ng-if="node.description" >
289+ {$ node.description $}
290 </div>
291 </div>
292 <span class="p-table-menu__dropdown" data-ng-if="openMenu === node.system_id + '-pool'">
293@@ -347,43 +355,41 @@
294 <i class="p-icon--spinner u-animation--spin" data-ng-if="node['set-zone-transition']">Setting zone</i>
295 <span class="u-text-overflow" data-ng-if="node.zone.name"><a class="p-link--soft" href="#/zone/{$ node.zone.id $}" title="{$ node.zone.name $}">{$ node.zone.name $}</a></span>
296 <span class="u-text-overflow" data-ng-if="!node.zone.name">-</span>
297- <button
298- class="p-table-menu__toggle p-icon--chevron u-hide--br3"
299- data-ng-if="node.actions.indexOf('set-zone') !== -1 && !hideActions"
300- data-ng-class="{'u-mirror--y' : openMenu === node.system_id + '-zone'}"
301- data-ng-click="toggleMenu(node.system_id + '-zone')"
302- ></button>
303 </div>
304+ <button
305+ class="p-table-menu__toggle p-icon--chevron u-hide--br3"
306+ data-ng-if="node.actions.indexOf('set-zone') !== -1 && !hideActions"
307+ data-ng-class="{'u-mirror--y' : openMenu === node.system_id + '-zone'}"
308+ data-ng-click="toggleMenu(node.system_id + '-zone')"
309+ ></button>
310 <div class="p-double-row__muted-row" style="overflow: visible">
311 <span class="u-text-overflow" data-ng-if="node.spaces.length === 1">
312 {$ node.spaces[0] $}
313 </span>
314 <span data-ng-if="node.spaces.length > 1" class="p-tooltip--btm-left" aria-described-by="{$ node.hostname $}-spaces" style="overflow: visible">
315- <span class="u-text-overflow">
316- {$ node.spaces.length $} spaces
317- </span>
318+ {$ node.spaces.length $} spaces
319 <span class="p-tooltip__message" role="tooltip" id="{$ node.hostname $}-spaces">{$ getSpacesTooltipMessage(node.spaces) $}</span>
320 </span>
321 </div>
322+ <span class="p-table-menu__dropdown" data-ng-if="openMenu === node.system_id + '-zone'">
323+ <div class="p-table-menu__title">Change AZ:</div>
324+ <button
325+ data-ng-repeat="zone in zones | orderBy:'name'"
326+ data-ng-if="node.zone.id !== zone.id && zones.length > 1 && node.actions.indexOf('set-zone') !== -1"
327+ data-ng-click="performAction(node, 'set-zone', { zone_id: zone.id })"
328+ class="p-table-menu__link"
329+ >
330+ {$ zone.name $}
331+ </button>
332+ <button
333+ data-ng-if="zones.length < 2 && node.actions.indexOf('set-zone') !== -1"
334+ class="p-table-menu__link"
335+ disabled
336+ >
337+ No other zones available
338+ </button>
339+ </span>
340 </div>
341- <span class="p-table-menu__dropdown" data-ng-if="openMenu === node.system_id + '-zone'">
342- <div class="p-table-menu__title">Change AZ:</div>
343- <button
344- data-ng-repeat="zone in zones | orderBy:'name'"
345- data-ng-if="node.zone.id !== zone.id && zones.length > 1 && node.actions.indexOf('set-zone') !== -1"
346- data-ng-click="performAction(node, 'set-zone', { zone_id: zone.id })"
347- class="p-table-menu__link"
348- >
349- {$ zone.name $}
350- </button>
351- <button
352- data-ng-if="zones.length < 2 && node.actions.indexOf('set-zone') !== -1"
353- class="p-table-menu__link"
354- disabled
355- >
356- No other zones available
357- </button>
358- </span>
359 </div>
360 </td>
361 <td class="p-table__col--fabric p-double-row" aria-label="Fabric, VLAN" title="{$ node.fabric.name $}">
362@@ -397,9 +403,9 @@
363 </div>
364 </div>
365 </td>
366- <td class="p-table__col--cores p-table--action-cell u-align--right p-double-row" aria-label="CPU, Architecture">
367- <div class="p-double-row__rows-container">
368- <div class="p-double-row__main-row u-align--right" aria-label="CPU" style="overflow: visible"> <!-- overflow override so tooltip is visible -->
369+ <td class="p-table__col--cores p-table--action-cell p-double-row" aria-label="CPU, Architecture">
370+ <div class="p-double-row__rows-container u-align--right">
371+ <div class="p-double-row__main-row" aria-label="CPU" style="overflow: visible"> <!-- overflow override so tooltip is visible -->
372 <span class="p-tooltip--left">
373 <span data-maas-script-status="script-status" data-script-status="node.cpu_test_status" data-ng-if="node.cpu_test_status !== -1 && node.cpu_test_status !== 2 && !hideFailedTests" aria-describedby="node-cpu-tooltip-{$ node.fqdn $}"></span>
374 <span class="u-text-overflow">{$ node.cpu_count $}</span>
375diff --git a/src/maasserver/static/partials/node-details.html b/src/maasserver/static/partials/node-details.html
376index 9eb044b..f5d4764 100755
377--- a/src/maasserver/static/partials/node-details.html
378+++ b/src/maasserver/static/partials/node-details.html
379@@ -2214,13 +2214,14 @@
380 <th>IP Address</th>
381 <th><div class="u-align--right">Actions</div></th>
382 </tr>
383-
384 <tr data-ng-if="!isDevice" class="p-table--is-not-device">
385 <th class="p-double-row">
386- <div class="p-double-row__checkbox"><span data-ng-hide="isAllNetworkingDisabled() || isController">&nbsp;</span></div>
387- <div class="p-double-row__rows-container--checkbox">
388- <div>Name</div>
389- <div>MAC</div>
390+ <div class="p-double-row__wrapper">
391+ <div class="p-double-row__checkbox" data-ng-if="!isController && !isAllNetworkingDisabled() && !isEditing(interface)"><span data-ng-hide="isAllNetworkingDisabled() || isController">&nbsp;</span></div>
392+ <div class="p-double-row__rows-container--checkbox">
393+ <div>Name</div>
394+ <div class="p-double-row__muted-header">MAC</div>
395+ </div>
396 </div>
397 </th>
398 <th><div data-ng-if="!isController" class="u-align--center">PXE</div></th>
399@@ -2284,23 +2285,25 @@
400 <tr data-ng-if="!isDevice" class="p-table--is-not-device" data-ng-class="{ disabled: isDisabled(), 'is-active': isInterfaceSelected(interface) && (!isAllNetworkingDisabled() || isLimitedEditingAllowed(interface)), noEdit: cannotEditInterface(interface) }"
401 data-ng-repeat="interface in interfaces | removeInterfaceParents:newBondInterface:isAllNetworkingDisabled() | removeInterfaceParents:newBridgeInterface:isAllNetworkingDisabled()">
402 <td class="p-double-row" aria-label="Name" data-ng-class="{ 'is-error': isInterfaceNameInvalid(editInterface) }">
403- <div class="p-double-row__checkbox" data-ng-if="!isController && !isAllNetworkingDisabled() && !isEditing(interface)">
404- <input type="checkbox" class="checkbox" id="{$ getUniqueKey(interface) $}"
405- data-ng-hide="isAllNetworkingDisabled()"
406- data-ng-checked="isInterfaceSelected(interface)"
407- data-ng-click="toggleInterfaceSelect(interface)"
408- data-ng-disabled="isDisabled()">
409- <label for="{$ getUniqueKey(interface) $}"></label>
410- </div>
411- <div class="p-double-row__rows-container--checkbox">
412- <div class="p-double-row__main-row">
413- <div data-ng-if="!isEditing(interface) || (!isEditing(interface) && interface.type === 'vlan')" title="{$ interface.name $}">
414- {$ interface.name $}
415- </div>
416+ <div class="p-double-row__wrapper">
417+ <div class="p-double-row__checkbox" data-ng-if="!isController && !isAllNetworkingDisabled() && !isEditing(interface)">
418+ <input type="checkbox" class="checkbox" id="{$ getUniqueKey(interface) $}"
419+ data-ng-hide="isAllNetworkingDisabled()"
420+ data-ng-checked="isInterfaceSelected(interface)"
421+ data-ng-click="toggleInterfaceSelect(interface)"
422+ data-ng-disabled="isDisabled()">
423+ <label for="{$ getUniqueKey(interface) $}"></label>
424 </div>
425- <div class="p-double-row__muted-row">
426- <div data-ng-if="!isEditing(interface) || (!isEditing(interface) && interface.type === 'vlan')" title="{$ interface.mac_address $}">
427- {$ interface.mac_address $}
428+ <div class="p-double-row__rows-container--checkbox">
429+ <div class="p-double-row__main-row">
430+ <div data-ng-if="!isEditing(interface) || (!isEditing(interface) && interface.type === 'vlan')" title="{$ interface.name $}">
431+ {$ interface.name $}
432+ </div>
433+ </div>
434+ <div class="p-double-row__muted-row">
435+ <div data-ng-if="!isEditing(interface) || (!isEditing(interface) && interface.type === 'vlan')" title="{$ interface.mac_address $}">
436+ {$ interface.mac_address $}
437+ </div>
438 </div>
439 </div>
440 </div>
441diff --git a/src/maasserver/static/scss/_breakpoints.scss b/src/maasserver/static/scss/_breakpoints.scss
442new file mode 100644
443index 0000000..cb466f4
444--- /dev/null
445+++ b/src/maasserver/static/scss/_breakpoints.scss
446@@ -0,0 +1,47 @@
447+@mixin breakpoint-widths(
448+ $width-one,
449+ $width-two: $width-one,
450+ $width-three: $width-two,
451+ $width-four: $width-three,
452+ $width-five: $width-four
453+) {
454+ @media (max-width: $breakpoint-first - 1px) {
455+ @if $width-one == 0 {
456+ display: none !important;
457+ } @else {
458+ width: $width-one;
459+ }
460+ }
461+
462+ @media (min-width: $breakpoint-first) and (max-width: $breakpoint-second - 1px) {
463+ @if $width-two == 0 {
464+ display: none !important;
465+ } @else {
466+ width: $width-two;
467+ }
468+ }
469+
470+ @media (min-width: $breakpoint-second) and (max-width: $breakpoint-third - 1px) {
471+ @if $width-three == 0 {
472+ display: none !important;
473+ } @else {
474+ width: $width-three;
475+ }
476+ }
477+
478+ @media (min-width: $breakpoint-third) and (max-width: $breakpoint-fourth - 1px) {
479+ @if $width-four == 0 {
480+ display: none !important;
481+ } @else {
482+ width: $width-four;
483+ }
484+ }
485+
486+ @media (min-width: $breakpoint-fourth) {
487+ @if $width-five == 0 {
488+ display: none !important;
489+ } @else {
490+ width: $width-five;
491+ }
492+ }
493+}
494diff --git a/src/maasserver/static/scss/_settings.scss b/src/maasserver/static/scss/_settings.scss
495index cb8eb7b..361370e 100644
496--- a/src/maasserver/static/scss/_settings.scss
497+++ b/src/maasserver/static/scss/_settings.scss
498@@ -1,3 +1,5 @@
499+@import "settings_breakpoints";
500+
501 $grid-max-width: 1440 / 16 * 1rem; // express in rems for easier calculations
502
503 $color-navigation-background: #333;
504diff --git a/src/maasserver/static/scss/_settings_breakpoints.scss b/src/maasserver/static/scss/_settings_breakpoints.scss
505new file mode 100644
506index 0000000..5267ebb
507--- /dev/null
508+++ b/src/maasserver/static/scss/_settings_breakpoints.scss
509@@ -0,0 +1,5 @@
510+// breakpoints used to hide content in responsive tables
511+$breakpoint-first: 600px;
512+$breakpoint-second: 900px;
513+$breakpoint-third: 1030px;
514+$breakpoint-fourth: 1360px;
515diff --git a/src/maasserver/static/scss/_tables.scss b/src/maasserver/static/scss/_tables.scss
516index c0d1fd2..d061214 100644
517--- a/src/maasserver/static/scss/_tables.scss
518+++ b/src/maasserver/static/scss/_tables.scss
519@@ -1,768 +1,143 @@
520-$breakpoint-first: 600px;
521-$breakpoint-second: 900px;
522-$breakpoint-third: 1030px;
523-$breakpoint-fourth: 1360px;
524-
525-@mixin breakpoint-widths(
526- $width-one,
527- $width-two: $width-one,
528- $width-three: $width-two,
529- $width-four: $width-three,
530- $width-five: $width-four
531-) {
532- @media (max-width: $breakpoint-first - 1px) {
533- @if $width-one == 0 {
534- display: none !important;
535- } @else {
536- width: $width-one;
537- }
538- }
539+@import "tables/bcache";
540+@import "tables/controllers";
541+@import "tables/controller-interfaces";
542+@import "tables/controllers-commissioning";
543+@import "tables/controller-vlans";
544+@import "tables/create-raid";
545+@import "tables/create-volume-group";
546+@import "tables/devices";
547+@import "tables/disk-partitions";
548+@import "tables/images";
549+@import "tables/machines";
550+@import "tables/network-discovery";
551+@import "tables/pod-networking-config";
552+@import "tables/pod-storage-config";
553+@import "tables/pods";
554+
555+$checkbox-space: 1rem + $sph-inner;
556+$icon-space: map-get($icon-sizes, default) + $sph-inner--small;
557+$icon-margin-right: $sph-inner--small;
558+$icon-button-width: $icon-margin-right + 2 * $vanilla-2-icon-button-side-padding +
559+ map-get($icon-sizes, default);
560+
561+$chevron-cell-width: 50px;
562
563- @media (min-width: $breakpoint-first) and (max-width: $breakpoint-second - 1px) {
564- @if $width-two == 0 {
565- display: none !important;
566- } @else {
567- width: $width-two;
568- }
569- }
570-
571- @media (min-width: $breakpoint-second) and (max-width: $breakpoint-third - 1px) {
572- @if $width-three == 0 {
573- display: none !important;
574- } @else {
575- width: $width-three;
576- }
577- }
578-
579- @media (min-width: $breakpoint-third) and (max-width: $breakpoint-fourth - 1px) {
580- @if $width-four == 0 {
581- display: none !important;
582- } @else {
583- width: $width-four;
584- }
585- }
586-
587- @media (min-width: $breakpoint-fourth) {
588- @if $width-five == 0 {
589- display: none !important;
590- } @else {
591- width: $width-five;
592- }
593+@mixin maas-table-widths {
594+ @include maas-table--bcache;
595+ @include maas-table--controllers;
596+ @include maas-table--controller-interfaces;
597+ @include maas-table--controllers-commissioning;
598+ @include maas-table--controller-vlans;
599+ @include maas-table--create-raid;
600+ @include maas-table--create-volume-group;
601+ @include maas-table--devices;
602+ @include maas-table--disk-partitions;
603+ @include maas-table--images;
604+ @include maas-table--machines;
605+ @include maas-table--pods;
606+ @include maas-table--pod-networking-config;
607+ @include maas-table--pod-storage-config;
608+ @include maas-table--network-discovery;
609+
610+ %p-double-row__icon-container {
611+ display: block;
612+ width: map-get($icon-sizes, default);
613+ }
614+
615+ %ellipse-single-line {
616+ overflow: hidden;
617+ text-overflow: ellipsis;
618+ white-space: nowrap;
619+ }
620+
621+ %double-row-flex-behaviour {
622+ display: flex;
623+ flex: 0 0 auto;
624+ flex-wrap: wrap;
625 }
626-}
627
628-@mixin maas-table-widths {
629 .p-table__row {
630- .p-table--machines tbody &:hover {
631- background-color: $color-x-light;
632- box-shadow: 0 1px 3px 0 transparentize($color-dark, 0.8);
633-
634- .p-table-menu__toggle {
635- display: inline-block;
636- }
637-
638- .p-table-menu:not(.is-hidden) .p-double-row__main-row .u-text-overflow {
639- max-width: calc(100% - 1.5rem);
640- }
641- }
642-
643 &--muted {
644 background: $color-light;
645 }
646 }
647
648- .p-table--network-discovery {
649- $chevron-cell-width: 50px;
650-
651- tr {
652- justify-content: space-between;
653- }
654-
655- th,
656- td {
657- flex: 0 0 auto;
658- }
659-
660- &__name {
661- width: 15%;
662- }
663-
664- &__mac {
665- width: 20%;
666- }
667-
668- &__ip {
669- width: 25%;
670- }
671-
672- &__rack {
673- width: 15%;
674- }
675-
676- &__last-seen {
677- width: calc(25% - #{$chevron-cell-width});
678- }
679-
680- &__chevron {
681- flex: 0 0 auto;
682- width: $chevron-cell-width; // chevron needs a static width
683- }
684- }
685-
686- .p-table--pods {
687- .p-table__row {
688- .p-table__cell {
689- &:nth-child(1) {
690- width: 10%;
691- }
692-
693- &:nth-child(2) {
694- width: 10%;
695- }
696-
697- &:nth-child(3) {
698- width: 10%;
699- }
700-
701- &:nth-child(4) {
702- width: 10%;
703- }
704-
705- &:nth-child(5) {
706- width: 16%;
707- }
708-
709- &:nth-child(6) {
710- width: 8%;
711- }
712-
713- &:nth-child(7) {
714- width: 8%;
715- }
716-
717- &:nth-child(8) {
718- width: 8%;
719- }
720- }
721- }
722- }
723-
724- .p-table--pod-networking-config,
725- .p-table--pod-storage-config {
726- input {
727- // overriding min-width to make inputs fit within container
728- min-width: auto;
729- @extend %u-input-min-margin--bottom;
730- }
731- }
732-
733- $icon-button-width: calc(
734- 2px + #{$sph-inner--small + $vanilla-2-icon-button-side-padding * 2 +
735- map-get($icon-sizes, default)}
736- );
737-
738- .p-table--pod-networking-config {
739- select {
740- @extend %u-input-min-margin--bottom;
741- }
742-
743- @media (min-width: $breakpoint-small) {
744- margin-bottom: 0;
745-
746- .p-table__row {
747- th,
748- td {
749- &:nth-child(1) {
750- width: $icon-button-width;
751- }
752-
753- &:nth-child(2) {
754- width: 10%;
755- }
756-
757- &:nth-child(3) {
758- width: 25%;
759- }
760-
761- &:nth-child(4) {
762- width: 15%;
763- }
764-
765- &:nth-child(5) {
766- width: 23%;
767- }
768-
769- &:nth-child(6) {
770- width: 10%;
771- }
772-
773- &:nth-child(7) {
774- width: 12%;
775- }
776-
777- &:nth-child(8) {
778- width: 5%;
779- }
780- }
781- }
782- }
783- }
784-
785- .p-table--pod-storage-config {
786- @media (min-width: $breakpoint-small) {
787- margin-bottom: 0;
788-
789- .p-table__row {
790- th,
791- td {
792- &:nth-child(1) {
793- width: $icon-button-width;
794- }
795-
796- &:nth-child(2) {
797- width: 10%;
798- }
799-
800- &:nth-child(3) {
801- width: 40%;
802- }
803-
804- &:nth-child(4) {
805- width: 40%;
806- }
807-
808- &:nth-child(5) {
809- width: 10%;
810- }
811- }
812- }
813- }
814- }
815-
816- .p-table--pod-networking-config--message {
817- margin-left: 35%;
818- }
819-
820- .p-table--devices {
821- .p-table__row {
822- .p-table__cell {
823- &:nth-child(1) {
824- width: 33%;
825- }
826-
827- &:nth-child(2) {
828- width: 17%;
829- }
830-
831- &:nth-child(3) {
832- width: 15%;
833-
834- @media (max-width: 1000px) {
835- display: none !important;
836- }
837- }
838-
839- &:nth-child(4) {
840- width: 20%;
841- }
842-
843- &:nth-child(5) {
844- width: 15%;
845- }
846- }
847- }
848+ .p-double-row {
849+ overflow: visible;
850 }
851
852- .p-table--controllers {
853- .p-table__row {
854- .p-table__cell {
855- &:nth-child(1) {
856- width: 30%;
857- }
858-
859- &:nth-child(2) {
860- width: 10%;
861- }
862-
863- &:nth-child(3) {
864- width: 20%;
865- }
866-
867- &:nth-child(4) {
868- width: 15%;
869- }
870-
871- &:nth-child(5) {
872- width: 20%;
873- }
874-
875- &:nth-child(6) {
876- width: 15%;
877- }
878- }
879- }
880+ .p-double-row__wrapper {
881+ @extend %double-row-flex-behaviour;
882+ width: 100%;
883 }
884
885- .p-table--images {
886- .p-table__row {
887- .p-table__cell {
888- &:nth-child(1) {
889- width: 20%;
890- }
891-
892- &:nth-child(2) {
893- width: 15%;
894- }
895-
896- &:nth-child(3) {
897- width: 15%;
898- }
899-
900- &:nth-child(4) {
901- width: 35%;
902- }
903-
904- &:nth-child(5) {
905- width: 15%;
906- }
907- }
908- }
909+ .p-double-row__checkbox {
910+ @extend %p-double-row__icon-container;
911+ margin-right: $sph-inner;
912 }
913
914- .p-table--disks-partitions,
915- .p-table--used-disks {
916- .p-table__row {
917- .p-table__cell {
918- flex: 0 0 auto !important;
919-
920- &:nth-child(1) {
921- width: 15%;
922- }
923-
924- &:nth-child(2) {
925- width: 15%;
926- }
927-
928- &:nth-child(3) {
929- width: 7%;
930- }
931-
932- &:nth-child(4) {
933- width: 9%;
934- }
935-
936- &:nth-child(5) {
937- width: 22%;
938- }
939-
940- &:nth-child(6) {
941- width: 22%;
942- }
943-
944- &:nth-child(7) {
945- width: 10%;
946- }
947- }
948- }
949+ .p-double-row__icon-container {
950+ @extend %p-double-row__icon-container;
951+ margin-right: $sph-inner--small;
952 }
953
954- .p-table--used-disks {
955- .p-table__row {
956- .p-table__cell {
957- &:nth-child(6) {
958- width: 7%;
959- }
960-
961- &:nth-child(7) {
962- width: 25%;
963- }
964- }
965- }
966+ %p-double-row__rows-container {
967+ @extend %double-row-flex-behaviour;
968+ position: relative;
969 }
970-
971- .p-table--datastores {
972- flex: 0 0 auto !important;
973-
974- .p-table__row {
975- .p-table__cell {
976- flex: 0 0 auto !important;
977-
978- &:nth-child(1) {
979- width: 15%;
980- }
981-
982- &:nth-child(2) {
983- width: 22%;
984- }
985-
986- &:nth-child(3) {
987- width: 9%;
988- }
989-
990- &:nth-child(4) {
991- width: 44%;
992- }
993-
994- &:nth-child(5) {
995- width: 10%;
996- }
997- }
998- }
999+ .p-double-row__rows-container {
1000+ @extend %p-double-row__rows-container;
1001+ width: 100%;
1002 }
1003
1004- .p-table--machines {
1005- $group-padding-left: 2.5rem;
1006- @extend %vf-pseudo-border--bottom;
1007- margin: 0;
1008- position: relative;
1009-
1010- .p-table__header {
1011- border-bottom: 1px solid $color-mid-light;
1012- }
1013-
1014- .p-table__group {
1015- border: 0;
1016- position: relative;
1017-
1018- .p-table__group-label {
1019- color: $color-dark;
1020- font-size: 1rem;
1021- padding: $spv-inner--small 0 $spv-inner--small $sph-inner--small;
1022- text-transform: none;
1023- }
1024-
1025- .p-table__group-toggle {
1026- padding: 0 $sp-x-small;
1027- position: absolute;
1028- right: $spv-inner--medium;
1029- top: $spv-outer--medium;
1030- }
1031-
1032- &.is-open {
1033- @include vf-icon-minus($color-mid-dark);
1034- }
1035- }
1036-
1037- .p-table__row {
1038- position: relative;
1039-
1040- &::after {
1041- content: "";
1042- }
1043-
1044- &.is-grouped {
1045- border: 0;
1046-
1047- &::after {
1048- position: absolute;
1049- left: $group-padding-left;
1050- right: 0;
1051- height: 1px;
1052- background-color: $color-light-new;
1053- }
1054-
1055- & td:first-child {
1056- padding-left: $group-padding-left;
1057- }
1058- }
1059-
1060- td {
1061- vertical-align: top;
1062- }
1063-
1064- .p-table__col--name {
1065- @include breakpoint-widths(46%, 30%, 22%, 20%, 17%);
1066- position: relative;
1067-
1068- .p-tooltip {
1069- position: static;
1070- }
1071- }
1072-
1073- .p-table__col--power {
1074- @include breakpoint-widths(8%, 8%, 4%, 10%, 9%);
1075- }
1076-
1077- .p-table__col--status {
1078- @include breakpoint-widths(46%, 44%, 22%, 22%, 18%);
1079- position: relative;
1080-
1081- .p-tooltip {
1082- position: static;
1083- }
1084- }
1085-
1086- .p-table__col--owner {
1087- @include breakpoint-widths(0, 18%, 8%, 10%, 9%);
1088- }
1089-
1090- .p-table__col--pool {
1091- @include breakpoint-widths(0, 0, 0, 0, 7%);
1092- overflow: visible;
1093- }
1094-
1095- .p-table__col--zone {
1096- @include breakpoint-widths(0, 0, 0, 10%, 9%);
1097- }
1098-
1099- .p-table__col--fabric {
1100- @include breakpoint-widths(0, 0, 0, 0, 8%);
1101- }
1102-
1103- .p-table__col--cores {
1104- @include breakpoint-widths(0, 0, 10%, 6%, 5%);
1105- }
1106-
1107- .p-table__col--ram {
1108- @include breakpoint-widths(0, 0, 12%, 8%, 7%);
1109- }
1110-
1111- .p-table__col--disks {
1112- @include breakpoint-widths(0, 0, 10%, 6%, 5%);
1113- }
1114-
1115- .p-table__col--storage {
1116- @include breakpoint-widths(0, 0, 10%, 8%, 6%);
1117- }
1118- }
1119-
1120- // Needed to keep widths of machine table correct when no grouping selected
1121- .p-table__placeholder {
1122- * {
1123- height: 0 !important;
1124- padding: 0 !important;
1125- visibility: hidden;
1126- }
1127- }
1128-
1129- .p-icon--placeholder {
1130- @extend %icon;
1131- height: map-get($icon-sizes, default);
1132- margin-right: $sph-inner--small;
1133- width: map-get($icon-sizes, default);
1134- }
1135-
1136- .p-tooltip__message--latest-event {
1137- max-width: 500px;
1138- white-space: inherit;
1139- }
1140-
1141- &:last-of-type::after {
1142- display: none;
1143- }
1144+ .p-double-row__rows-container--icon {
1145+ @extend %p-double-row__rows-container;
1146+ width: calc(100% - #{$icon-space});
1147 }
1148
1149- .p-table--controller-interfaces {
1150- .p-table--is-device {
1151- th,
1152- td {
1153- &:nth-child(1) {
1154- width: 30%;
1155- }
1156- &:nth-child(2) {
1157- width: 25%;
1158- }
1159- &:nth-child(3) {
1160- width: 25%;
1161- }
1162- &:nth-child(4) {
1163- width: 15%;
1164- }
1165- }
1166- }
1167-
1168- .p-table--is-not-device {
1169- th,
1170- td {
1171- &:nth-child(1) {
1172- width: 20%;
1173- }
1174- &:nth-child(2) {
1175- width: 6%;
1176- }
1177- &:nth-child(3) {
1178- width: 10%;
1179- }
1180- &:nth-child(4) {
1181- width: 14%;
1182- }
1183- &:nth-child(5) {
1184- width: 16%;
1185- }
1186- &:nth-child(6) {
1187- width: 28%;
1188- }
1189- &:nth-child(7) {
1190- width: 6%;
1191- }
1192- }
1193- }
1194+ .p-double-row__rows-container--checkbox {
1195+ @extend %p-double-row__rows-container;
1196+ width: calc(100% - #{$checkbox-space});
1197 }
1198
1199- .p-table--controllers-commissioning {
1200- .p-table__row {
1201- th,
1202- td {
1203- &:nth-child(1) {
1204- width: 15%;
1205- }
1206- &:nth-child(2) {
1207- width: 15%;
1208- }
1209- &:nth-child(3) {
1210- width: 20%;
1211- }
1212- &:nth-child(4) {
1213- width: 20%;
1214- }
1215- &:nth-child(5) {
1216- width: 25%;
1217- }
1218- &:nth-child(6) {
1219- width: 5%;
1220- }
1221- }
1222- }
1223- }
1224- .p-table--controller-vlans {
1225- .p-table__row {
1226- @media (min-width: $breakpoint-small) {
1227- th,
1228- td {
1229- &:nth-child(1) {
1230- width: 15%;
1231- }
1232- &:nth-child(2) {
1233- width: 15%;
1234- }
1235- &:nth-child(3) {
1236- width: 10%;
1237- }
1238- &:nth-child(4) {
1239- width: 20%;
1240- }
1241- &:nth-child(5) {
1242- width: 20%;
1243- }
1244- &:nth-child(6) {
1245- width: 20%;
1246- }
1247- }
1248- }
1249+ .p-double-row__main-row {
1250+ @extend %ellipse-single-line;
1251+ @at-root .p-table--machines
1252+ .p-table__row:hover
1253+ .p-table-menu.has-actions
1254+ & {
1255+ max-width: calc(100% - #{$icon-space + $sph-inner});
1256+ margin-right: 0.5rem;
1257 }
1258 }
1259
1260- .p-table--create-raid {
1261- &__name {
1262- @media (max-width: $breakpoint-medium) {
1263- width: 50%;
1264- }
1265- @media (min-width: $breakpoint-medium) {
1266- width: 30%;
1267- }
1268- }
1269- &__size {
1270- width: 10%;
1271- }
1272- &__type {
1273- width: 20%;
1274- }
1275- &__active {
1276- width: 10%;
1277- }
1278- &__spare {
1279- width: 10%;
1280- }
1281+ .p-double-row__muted-header {
1282+ @extend %ellipse-single-line;
1283+ width: 100%;
1284 }
1285
1286- .p-table--create-volume-group {
1287- &__name {
1288- @media (max-width: $breakpoint-medium) {
1289- width: 50%;
1290- }
1291- @media (min-width: $breakpoint-medium) {
1292- width: 30%;
1293- }
1294- }
1295- &__size {
1296- width: 30%;
1297- }
1298- &__type {
1299- width: 20%;
1300- }
1301- &__empty {
1302- width: 10%;
1303- }
1304- }
1305- .p-table--bcache {
1306- &__name {
1307- @media (max-width: $breakpoint-medium) {
1308- width: 50%;
1309- }
1310- @media (min-width: $breakpoint-medium) {
1311- width: 30%;
1312- }
1313- }
1314- &__size {
1315- width: 30%;
1316- }
1317- &__type {
1318- width: 20%;
1319- }
1320- &__empty {
1321- width: 10%;
1322- }
1323+ .p-double-row__muted-row {
1324+ @extend %small-text;
1325+ @extend %ellipse-single-line;
1326+ color: $color-mid-dark;
1327+ margin-bottom: map-get($line-heights, default-text) -
1328+ map-get($line-heights, small) - map-get($nudges, nudge--small);
1329+ width: 100%;
1330 }
1331
1332- $checkbox-space: 1rem + $sph-inner;
1333- $icon-space: map-get($icon-sizes, default) + $sph-inner--small;
1334+ .p-double-row__muted-row-text {
1335+ @extend %ellipse-single-line;
1336
1337- .p-double-row {
1338- overflow: visible;
1339+ $ip-count-width: 2rem;
1340
1341- %p-double-row__icon-container {
1342- display: block;
1343- float: left;
1344- width: map-get($icon-sizes, default);
1345+ &--ip-count {
1346+ @extend %ellipse-single-line;
1347+ width: $ip-count-width;
1348 }
1349
1350- %p-double-row__row {
1351- align-items: center;
1352- display: flex;
1353- white-space: nowrap;
1354- width: 100%;
1355- }
1356-
1357- .p-double-row__checkbox {
1358- @extend %p-double-row__icon-container;
1359- margin-right: $sph-inner;
1360- }
1361-
1362- .p-double-row__icon-container {
1363- @extend %p-double-row__icon-container;
1364- margin-right: $sph-inner--small;
1365- }
1366-
1367- .p-double-row__rows-container--icon {
1368- float: left;
1369- width: calc(100% - #{$icon-space});
1370- }
1371-
1372- .p-double-row__rows-container--checkbox {
1373- float: left;
1374- width: calc(100% - #{$checkbox-space});
1375- }
1376-
1377- .p-double-row__main-row {
1378- @extend %p-double-row__row;
1379- }
1380-
1381- .p-double-row__muted-row {
1382- @extend %small-text;
1383- @extend %p-double-row__row;
1384- color: $color-mid-dark;
1385- margin-bottom: map-get($line-heights, default-text) -
1386- map-get($line-heights, small) - map-get($nudges, nudge--small);
1387+ &--ip {
1388+ @extend %ellipse-single-line;
1389+ width: calc(100% - #{$ip-count-width});
1390 }
1391 }
1392
1393@@ -819,136 +194,132 @@ $breakpoint-fourth: 1360px;
1394
1395 .p-table-menu {
1396 @extend .p-contextual-menu;
1397- margin-bottom: -$sp-unit;
1398+ display: flex;
1399 width: 100%;
1400
1401- %table-menu-link {
1402- @extend .p-contextual-menu__link;
1403- padding: $spv-inner--small $sph-inner;
1404- position: relative;
1405- transition: 0s;
1406-
1407- &::before {
1408- background-position: center;
1409- background-repeat: no-repeat;
1410- background-size: map-get($icon-sizes, default);
1411- content: "";
1412- height: 17px;
1413- left: $sph-inner;
1414- position: absolute;
1415- top: $spv-inner--medium;
1416- width: map-get($icon-sizes, default);
1417- }
1418+ .p-double-row__icon-container {
1419+ cursor: pointer;
1420 }
1421+ }
1422
1423- %table-menu-title {
1424- border-bottom: 1px solid $color-light-new;
1425- color: $color-mid-dark;
1426- font-size: 0.75rem;
1427- font-weight: 400;
1428- padding: $spv-inner--x-small $sph-inner;
1429- text-transform: uppercase;
1430- }
1431+ .p-table-menu__title {
1432+ @extend %table-menu-title;
1433+ }
1434
1435- .p-table-menu__title {
1436- @extend %table-menu-title;
1437- }
1438+ .p-table-menu__footer {
1439+ border-top: 1px solid $color-light-new;
1440+ color: $color-mid-dark;
1441+ padding: $spv-inner--x-small $sp-xx-large;
1442+ }
1443
1444- .p-table-menu__title--icon {
1445- @extend %table-menu-title;
1446- padding-left: $sp-xx-large;
1447- }
1448+ .p-table-menu__toggle {
1449+ @include vf-icon-chevron;
1450+ background-color: transparentize($color-x-light, 0.25);
1451+ background-position: 0 60%;
1452+ background-repeat: no-repeat;
1453+ border: 0;
1454+ cursor: pointer;
1455+ height: map-get($line-heights, default-text);
1456+ display: none;
1457+ flex: 0 0 auto;
1458+ left: $sp-x-small;
1459+ margin-left: $sph-inner--small;
1460+ opacity: 0.25;
1461+ overflow: hidden;
1462+ padding: $spv-inner--small $sph-inner--small;
1463+ top: 1px;
1464+ width: map-get($icon-sizes, default);
1465
1466- .p-table-menu__footer {
1467- border-top: 1px solid $color-light-new;
1468- color: $color-mid-dark;
1469- padding: $spv-inner--x-small $sp-xx-large;
1470+ td:hover & {
1471+ opacity: 1;
1472 }
1473+ }
1474
1475- .p-table-menu__toggle {
1476- background-color: transparentize($color-x-light, 0.25);
1477- border: 0;
1478- cursor: pointer;
1479- display: none;
1480- left: $sp-x-small;
1481- opacity: 0.25;
1482- top: 1px;
1483-
1484- td:hover & {
1485- opacity: 1;
1486- }
1487- }
1488+ .p-table-menu__dropdown {
1489+ @extend .p-contextual-menu__dropdown;
1490+ left: -#{$sph-inner};
1491+ max-width: none;
1492+ min-width: 100%;
1493+ top: $sp-x-large;
1494+ width: -moz-max-content;
1495+ width: max-content;
1496
1497- .p-table-menu__dropdown {
1498- @extend .p-contextual-menu__dropdown;
1499- left: -#{$sph-inner};
1500- max-width: none;
1501- min-width: 100%;
1502- top: $sp-x-large;
1503- width: -moz-max-content;
1504- width: max-content;
1505-
1506- .p-contextual-menu__group {
1507- border-color: $color-light-new;
1508- }
1509+ .p-contextual-menu__group {
1510+ border-color: $color-light-new;
1511 }
1512+ }
1513
1514- .p-table-menu__link {
1515- @extend %table-menu-link;
1516- }
1517+ .p-contextual-menu__group {
1518+ border-color: $color-light-new;
1519+ }
1520
1521- .p-table-menu__check-power {
1522- @extend %table-menu-link;
1523- padding-left: $sp-xx-large;
1524- padding-right: $sp-xx-large;
1525- }
1526+ %table-menu-title {
1527+ @extend %bold;
1528+ border-bottom: 1px solid $color-light-new;
1529+ color: $color-mid-dark;
1530+ display: flex;
1531+ flex: 0 0 auto;
1532+ font-size: #{pow($ms-ratio, -2)}rem;
1533+ padding: $spv-inner--x-small $sph-inner;
1534+ text-transform: uppercase;
1535+ width: 100%;
1536+ }
1537
1538- .p-table-menu__power-on {
1539- @extend %table-menu-link;
1540- padding-left: $sp-xx-large;
1541- padding-right: $sp-xx-large;
1542+ %table-menu-link {
1543+ @extend .p-contextual-menu__link;
1544+ display: flex;
1545+ padding: $spv-inner--x-small $sph-inner;
1546+ position: relative;
1547+ transition: 0s;
1548+ }
1549
1550- &::before {
1551- @include maas-icon-power-on($color-positive);
1552- }
1553+ %p-table-menu__icon-placeholder {
1554+ &::before {
1555+ background-position: center;
1556+ background-repeat: no-repeat;
1557+ background-size: 100%;
1558+ content: "";
1559+ display: block;
1560+ height: map-get($line-heights, default-text);
1561+ margin-right: $icon-margin-right;
1562+ position: relative;
1563+ width: map-get($icon-sizes, default);
1564 }
1565+ }
1566
1567- .p-table-menu__power-off {
1568- @extend %table-menu-link;
1569- padding-left: $sp-xx-large;
1570- padding-right: $sp-xx-large;
1571-
1572- &::before {
1573- @include maas-icon-power-on($color-mid-light);
1574- }
1575- }
1576+ %p-table-menu__icon-offset {
1577+ margin-left: map-get($icon-sizes, default) + $sph-inner--small;
1578+ }
1579
1580- .p-double-row__icon-container {
1581- cursor: pointer;
1582+ .p-table-menu__title,
1583+ .p-table-menu__link {
1584+ .p-table__col--power & {
1585+ @extend %p-table-menu__icon-placeholder;
1586 }
1587 }
1588
1589- .u-hide--br1 {
1590- @media (max-width: $breakpoint-first - 1px) {
1591- display: none !important;
1592+ .p-table-menu__dropdown {
1593+ .p-table__col--status & {
1594+ @extend %p-table-menu__icon-offset;
1595 }
1596 }
1597
1598- .u-hide--br2 {
1599- @media (max-width: $breakpoint-second - 1px) {
1600- display: none !important;
1601- }
1602+ .p-table-menu__link,
1603+ .p-table-menu__check-power,
1604+ .p-table-menu__power-on,
1605+ .p-table-menu__power-off {
1606+ @extend %table-menu-link;
1607 }
1608
1609- .u-hide--br3 {
1610- @media (max-width: $breakpoint-third - 1px) {
1611- display: none !important;
1612+ .p-table-menu__power-on {
1613+ &::before {
1614+ @include maas-icon-power-on($color-positive);
1615 }
1616 }
1617
1618- .u-hide--br4 {
1619- @media (max-width: $breakpoint-fourth - 1px) {
1620- display: none !important;
1621+ .p-table-menu__power-off {
1622+ &::before {
1623+ @include maas-icon-power-on($color-mid-light);
1624 }
1625 }
1626 }
1627diff --git a/src/maasserver/static/scss/_utilities_breakpoints.scss b/src/maasserver/static/scss/_utilities_breakpoints.scss
1628new file mode 100644
1629index 0000000..cb466f4
1630--- /dev/null
1631+++ b/src/maasserver/static/scss/_utilities_breakpoints.scss
1632@@ -0,0 +1,47 @@
1633+@mixin breakpoint-widths(
1634+ $width-one,
1635+ $width-two: $width-one,
1636+ $width-three: $width-two,
1637+ $width-four: $width-three,
1638+ $width-five: $width-four
1639+) {
1640+ @media (max-width: $breakpoint-first - 1px) {
1641+ @if $width-one == 0 {
1642+ display: none !important;
1643+ } @else {
1644+ width: $width-one;
1645+ }
1646+ }
1647+
1648+ @media (min-width: $breakpoint-first) and (max-width: $breakpoint-second - 1px) {
1649+ @if $width-two == 0 {
1650+ display: none !important;
1651+ } @else {
1652+ width: $width-two;
1653+ }
1654+ }
1655+
1656+ @media (min-width: $breakpoint-second) and (max-width: $breakpoint-third - 1px) {
1657+ @if $width-three == 0 {
1658+ display: none !important;
1659+ } @else {
1660+ width: $width-three;
1661+ }
1662+ }
1663+
1664+ @media (min-width: $breakpoint-third) and (max-width: $breakpoint-fourth - 1px) {
1665+ @if $width-four == 0 {
1666+ display: none !important;
1667+ } @else {
1668+ width: $width-four;
1669+ }
1670+ }
1671+
1672+ @media (min-width: $breakpoint-fourth) {
1673+ @if $width-five == 0 {
1674+ display: none !important;
1675+ } @else {
1676+ width: $width-five;
1677+ }
1678+ }
1679+}
1680diff --git a/src/maasserver/static/scss/_utilities_hide.scss b/src/maasserver/static/scss/_utilities_hide.scss
1681new file mode 100644
1682index 0000000..dd512a7
1683--- /dev/null
1684+++ b/src/maasserver/static/scss/_utilities_hide.scss
1685@@ -0,0 +1,25 @@
1686+@mixin maas-util-hide {
1687+ .u-hide--br1 {
1688+ @media (max-width: $breakpoint-first - 1px) {
1689+ display: none !important;
1690+ }
1691+ }
1692+
1693+ .u-hide--br2 {
1694+ @media (max-width: $breakpoint-second - 1px) {
1695+ display: none !important;
1696+ }
1697+ }
1698+
1699+ .u-hide--br3 {
1700+ @media (max-width: $breakpoint-third - 1px) {
1701+ display: none !important;
1702+ }
1703+ }
1704+
1705+ .u-hide--br4 {
1706+ @media (max-width: $breakpoint-fourth - 1px) {
1707+ display: none !important;
1708+ }
1709+ }
1710+}
1711diff --git a/src/maasserver/static/scss/_utils.scss b/src/maasserver/static/scss/_utils.scss
1712index ae54295..876b4bf 100644
1713--- a/src/maasserver/static/scss/_utils.scss
1714+++ b/src/maasserver/static/scss/_utils.scss
1715@@ -1,4 +1,9 @@
1716 //does not work with colors containing alpha
1717+@import "utilities_hide";
1718+@import "utilities_breakpoints";
1719+
1720+@include maas-util-hide;
1721+
1722 @function encodecolor($string) {
1723 @if type-of($string) == "color" {
1724 $hex: str-slice(ie-hex-str($string), 4);
1725diff --git a/src/maasserver/static/scss/build.scss b/src/maasserver/static/scss/build.scss
1726index c3ae410..8105e13 100644
1727--- a/src/maasserver/static/scss/build.scss
1728+++ b/src/maasserver/static/scss/build.scss
1729@@ -50,7 +50,6 @@
1730 @include maas-inline-lists;
1731 @include maas-divided-lists;
1732 @include maas-tables;
1733-
1734 @include maas-b-forms;
1735 @include maas-b-links;
1736 @include maas-action-button;
1737diff --git a/src/maasserver/static/scss/tables/_bcache.scss b/src/maasserver/static/scss/tables/_bcache.scss
1738new file mode 100644
1739index 0000000..76be3c7
1740--- /dev/null
1741+++ b/src/maasserver/static/scss/tables/_bcache.scss
1742@@ -0,0 +1,21 @@
1743+@mixin maas-table--bcache {
1744+ .p-table--bcache {
1745+ &__name {
1746+ @media (max-width: $breakpoint-medium) {
1747+ width: 50%;
1748+ }
1749+ @media (min-width: $breakpoint-medium) {
1750+ width: 30%;
1751+ }
1752+ }
1753+ &__size {
1754+ width: 30%;
1755+ }
1756+ &__type {
1757+ width: 20%;
1758+ }
1759+ &__empty {
1760+ width: 10%;
1761+ }
1762+ }
1763+}
1764diff --git a/src/maasserver/static/scss/tables/_controller-interfaces.scss b/src/maasserver/static/scss/tables/_controller-interfaces.scss
1765new file mode 100644
1766index 0000000..50a3e1f
1767--- /dev/null
1768+++ b/src/maasserver/static/scss/tables/_controller-interfaces.scss
1769@@ -0,0 +1,48 @@
1770+@mixin maas-table--controller-interfaces {
1771+ .p-table--controller-interfaces {
1772+ .p-table--is-device {
1773+ th,
1774+ td {
1775+ &:nth-child(1) {
1776+ width: 30%;
1777+ }
1778+ &:nth-child(2) {
1779+ width: 25%;
1780+ }
1781+ &:nth-child(3) {
1782+ width: 25%;
1783+ }
1784+ &:nth-child(4) {
1785+ width: 15%;
1786+ }
1787+ }
1788+ }
1789+
1790+ .p-table--is-not-device {
1791+ th,
1792+ td {
1793+ &:nth-child(1) {
1794+ width: 20%;
1795+ }
1796+ &:nth-child(2) {
1797+ width: 6%;
1798+ }
1799+ &:nth-child(3) {
1800+ width: 10%;
1801+ }
1802+ &:nth-child(4) {
1803+ width: 14%;
1804+ }
1805+ &:nth-child(5) {
1806+ width: 16%;
1807+ }
1808+ &:nth-child(6) {
1809+ width: 28%;
1810+ }
1811+ &:nth-child(7) {
1812+ width: 6%;
1813+ }
1814+ }
1815+ }
1816+ }
1817+}
1818diff --git a/src/maasserver/static/scss/tables/_controller-vlans.scss b/src/maasserver/static/scss/tables/_controller-vlans.scss
1819new file mode 100644
1820index 0000000..f5e0bbe
1821--- /dev/null
1822+++ b/src/maasserver/static/scss/tables/_controller-vlans.scss
1823@@ -0,0 +1,29 @@
1824+@mixin maas-table--controller-vlans {
1825+ .p-table--controller-vlans {
1826+ .p-table__row {
1827+ @media (min-width: $breakpoint-small) {
1828+ th,
1829+ td {
1830+ &:nth-child(1) {
1831+ width: 15%;
1832+ }
1833+ &:nth-child(2) {
1834+ width: 15%;
1835+ }
1836+ &:nth-child(3) {
1837+ width: 10%;
1838+ }
1839+ &:nth-child(4) {
1840+ width: 20%;
1841+ }
1842+ &:nth-child(5) {
1843+ width: 20%;
1844+ }
1845+ &:nth-child(6) {
1846+ width: 20%;
1847+ }
1848+ }
1849+ }
1850+ }
1851+ }
1852+}
1853diff --git a/src/maasserver/static/scss/tables/_controllers-commissioning.scss b/src/maasserver/static/scss/tables/_controllers-commissioning.scss
1854new file mode 100644
1855index 0000000..32ee360
1856--- /dev/null
1857+++ b/src/maasserver/static/scss/tables/_controllers-commissioning.scss
1858@@ -0,0 +1,27 @@
1859+@mixin maas-table--controllers-commissioning {
1860+ .p-table--controllers-commissioning {
1861+ .p-table__row {
1862+ th,
1863+ td {
1864+ &:nth-child(1) {
1865+ width: 15%;
1866+ }
1867+ &:nth-child(2) {
1868+ width: 15%;
1869+ }
1870+ &:nth-child(3) {
1871+ width: 20%;
1872+ }
1873+ &:nth-child(4) {
1874+ width: 20%;
1875+ }
1876+ &:nth-child(5) {
1877+ width: 25%;
1878+ }
1879+ &:nth-child(6) {
1880+ width: 5%;
1881+ }
1882+ }
1883+ }
1884+ }
1885+}
1886diff --git a/src/maasserver/static/scss/tables/_controllers.scss b/src/maasserver/static/scss/tables/_controllers.scss
1887new file mode 100644
1888index 0000000..713fc35
1889--- /dev/null
1890+++ b/src/maasserver/static/scss/tables/_controllers.scss
1891@@ -0,0 +1,31 @@
1892+@mixin maas-table--controllers {
1893+ .p-table--controllers {
1894+ .p-table__row {
1895+ .p-table__cell {
1896+ &:nth-child(1) {
1897+ width: 30%;
1898+ }
1899+
1900+ &:nth-child(2) {
1901+ width: 10%;
1902+ }
1903+
1904+ &:nth-child(3) {
1905+ width: 20%;
1906+ }
1907+
1908+ &:nth-child(4) {
1909+ width: 15%;
1910+ }
1911+
1912+ &:nth-child(5) {
1913+ width: 20%;
1914+ }
1915+
1916+ &:nth-child(6) {
1917+ width: 15%;
1918+ }
1919+ }
1920+ }
1921+ }
1922+}
1923diff --git a/src/maasserver/static/scss/tables/_create-raid.scss b/src/maasserver/static/scss/tables/_create-raid.scss
1924new file mode 100644
1925index 0000000..5ad5726
1926--- /dev/null
1927+++ b/src/maasserver/static/scss/tables/_create-raid.scss
1928@@ -0,0 +1,24 @@
1929+@mixin maas-table--create-raid {
1930+ .p-table--create-raid {
1931+ &__name {
1932+ @media (max-width: $breakpoint-medium) {
1933+ width: 50%;
1934+ }
1935+ @media (min-width: $breakpoint-medium) {
1936+ width: 30%;
1937+ }
1938+ }
1939+ &__size {
1940+ width: 10%;
1941+ }
1942+ &__type {
1943+ width: 20%;
1944+ }
1945+ &__active {
1946+ width: 10%;
1947+ }
1948+ &__spare {
1949+ width: 10%;
1950+ }
1951+ }
1952+}
1953diff --git a/src/maasserver/static/scss/tables/_create-volume-group.scss b/src/maasserver/static/scss/tables/_create-volume-group.scss
1954new file mode 100644
1955index 0000000..66e851f
1956--- /dev/null
1957+++ b/src/maasserver/static/scss/tables/_create-volume-group.scss
1958@@ -0,0 +1,21 @@
1959+@mixin maas-table--create-volume-group {
1960+ .p-table--create-volume-group {
1961+ &__name {
1962+ @media (max-width: $breakpoint-medium) {
1963+ width: 50%;
1964+ }
1965+ @media (min-width: $breakpoint-medium) {
1966+ width: 30%;
1967+ }
1968+ }
1969+ &__size {
1970+ width: 30%;
1971+ }
1972+ &__type {
1973+ width: 20%;
1974+ }
1975+ &__empty {
1976+ width: 10%;
1977+ }
1978+ }
1979+}
1980diff --git a/src/maasserver/static/scss/tables/_devices.scss b/src/maasserver/static/scss/tables/_devices.scss
1981new file mode 100644
1982index 0000000..5be49c0
1983--- /dev/null
1984+++ b/src/maasserver/static/scss/tables/_devices.scss
1985@@ -0,0 +1,31 @@
1986+@mixin maas-table--devices {
1987+ .p-table--devices {
1988+ .p-table__row {
1989+ .p-table__cell {
1990+ &:nth-child(1) {
1991+ width: 33%;
1992+ }
1993+
1994+ &:nth-child(2) {
1995+ width: 17%;
1996+ }
1997+
1998+ &:nth-child(3) {
1999+ width: 15%;
2000+
2001+ @media (max-width: 1000px) {
2002+ display: none !important;
2003+ }
2004+ }
2005+
2006+ &:nth-child(4) {
2007+ width: 20%;
2008+ }
2009+
2010+ &:nth-child(5) {
2011+ width: 15%;
2012+ }
2013+ }
2014+ }
2015+ }
2016+}
2017diff --git a/src/maasserver/static/scss/tables/_disk-partitions.scss b/src/maasserver/static/scss/tables/_disk-partitions.scss
2018new file mode 100644
2019index 0000000..95ffaff
2020--- /dev/null
2021+++ b/src/maasserver/static/scss/tables/_disk-partitions.scss
2022@@ -0,0 +1,43 @@
2023+@mixin maas-table--disk-partitions {
2024+ .p-table--disks-partitions {
2025+ .p-table__row {
2026+ .p-table__cell {
2027+ &:nth-child(1) {
2028+ width: 15%;
2029+ }
2030+
2031+ &:nth-child(2) {
2032+ width: 15%;
2033+ }
2034+
2035+ &:nth-child(3) {
2036+ width: 7%;
2037+ }
2038+
2039+ &:nth-child(4) {
2040+ width: 9%;
2041+ }
2042+
2043+ &:nth-child(5) {
2044+ width: 12%;
2045+ }
2046+
2047+ &:nth-child(6) {
2048+ width: 10%;
2049+ }
2050+
2051+ &:nth-child(7) {
2052+ width: 12%;
2053+ }
2054+
2055+ &:nth-child(8) {
2056+ width: 10%;
2057+ }
2058+
2059+ &:nth-child(9) {
2060+ width: 10%;
2061+ }
2062+ }
2063+ }
2064+ }
2065+}
2066diff --git a/src/maasserver/static/scss/tables/_images.scss b/src/maasserver/static/scss/tables/_images.scss
2067new file mode 100644
2068index 0000000..6b0eb98
2069--- /dev/null
2070+++ b/src/maasserver/static/scss/tables/_images.scss
2071@@ -0,0 +1,27 @@
2072+@mixin maas-table--images {
2073+ .p-table--images {
2074+ .p-table__row {
2075+ .p-table__cell {
2076+ &:nth-child(1) {
2077+ width: 20%;
2078+ }
2079+
2080+ &:nth-child(2) {
2081+ width: 15%;
2082+ }
2083+
2084+ &:nth-child(3) {
2085+ width: 15%;
2086+ }
2087+
2088+ &:nth-child(4) {
2089+ width: 35%;
2090+ }
2091+
2092+ &:nth-child(5) {
2093+ width: 15%;
2094+ }
2095+ }
2096+ }
2097+ }
2098+}
2099diff --git a/src/maasserver/static/scss/tables/_machines.scss b/src/maasserver/static/scss/tables/_machines.scss
2100new file mode 100644
2101index 0000000..737acd1
2102--- /dev/null
2103+++ b/src/maasserver/static/scss/tables/_machines.scss
2104@@ -0,0 +1,153 @@
2105+@mixin maas-table--machines {
2106+ .p-table--machines {
2107+ $group-padding-left: 2.5rem;
2108+ @extend %vf-pseudo-border--bottom;
2109+ margin: 0;
2110+ position: relative;
2111+
2112+ .p-table__header {
2113+ border-bottom: 1px solid $color-mid-light;
2114+ }
2115+
2116+ .p-table__group {
2117+ border: 0;
2118+ position: relative;
2119+
2120+ .p-table__group-label {
2121+ color: $color-dark;
2122+ font-size: 1rem;
2123+ padding: $spv-inner--small 0 $spv-inner--small $sph-inner--small;
2124+ text-transform: none;
2125+ }
2126+
2127+ .p-table__group-toggle {
2128+ padding: 0 $sp-x-small;
2129+ position: absolute;
2130+ right: $spv-inner--medium;
2131+ top: $spv-outer--medium;
2132+ }
2133+
2134+ &.is-open {
2135+ @include vf-icon-minus($color-mid-dark);
2136+ }
2137+ }
2138+
2139+ & tbody .p-table__row:hover {
2140+ background-color: $color-x-light;
2141+
2142+ .p-table-menu__toggle {
2143+ display: inline-block;
2144+ }
2145+ }
2146+
2147+ .p-table__row {
2148+ position: relative;
2149+
2150+ &::after {
2151+ content: "";
2152+ }
2153+
2154+ &.is-grouped {
2155+ border: 0;
2156+
2157+ &::after {
2158+ position: absolute;
2159+ left: $group-padding-left;
2160+ right: 0;
2161+ height: $px;
2162+ background-color: $color-light-new;
2163+ }
2164+
2165+ & td:first-child {
2166+ padding-left: $group-padding-left;
2167+ }
2168+ }
2169+
2170+ td {
2171+ vertical-align: top;
2172+ }
2173+
2174+ .p-table__col--name {
2175+ @include breakpoint-widths(46%, 30%, 22%, 20%, 17%);
2176+ position: relative;
2177+
2178+ .p-tooltip {
2179+ position: static;
2180+ width: 100%;
2181+ }
2182+ }
2183+
2184+ .p-table__col--power {
2185+ @include breakpoint-widths(8%, 8%, 4%, 10%, 9%);
2186+ }
2187+
2188+ .p-table__col--status {
2189+ @include breakpoint-widths(46%, 44%, 22%, 22%, 18%);
2190+ position: relative;
2191+
2192+ .p-tooltip {
2193+ position: static;
2194+ width: 100%;
2195+ }
2196+ }
2197+
2198+ .p-table__col--owner {
2199+ @include breakpoint-widths(0, 18%, 8%, 10%, 9%);
2200+ }
2201+
2202+ .p-table__col--pool {
2203+ @include breakpoint-widths(0, 0, 0, 0, 7%);
2204+ overflow: visible;
2205+ }
2206+
2207+ .p-table__col--zone {
2208+ @include breakpoint-widths(0, 0, 0, 10%, 9%);
2209+ }
2210+
2211+ .p-table__col--fabric {
2212+ @include breakpoint-widths(0, 0, 0, 0, 8%);
2213+ }
2214+
2215+ .p-table__col--cores {
2216+ @include breakpoint-widths(0, 0, 10%, 6%, 5%);
2217+ }
2218+
2219+ .p-table__col--ram {
2220+ @include breakpoint-widths(0, 0, 12%, 8%, 7%);
2221+ }
2222+
2223+ .p-table__col--disks {
2224+ @include breakpoint-widths(0, 0, 10%, 6%, 5%);
2225+ }
2226+
2227+ .p-table__col--storage {
2228+ @include breakpoint-widths(0, 0, 10%, 8%, 6%);
2229+ }
2230+ }
2231+
2232+ // Needed to keep widths of machine table correct when no grouping selected
2233+ .p-table__placeholder {
2234+ * {
2235+ height: 0 !important;
2236+ padding: 0 !important;
2237+ visibility: hidden;
2238+ }
2239+ }
2240+
2241+ .p-icon--placeholder {
2242+ @extend %icon;
2243+ height: map-get($icon-sizes, default);
2244+ margin-right: $sph-inner--small;
2245+ width: map-get($icon-sizes, default);
2246+ }
2247+
2248+ .p-tooltip__message--latest-event {
2249+ max-width: 500px;
2250+ white-space: inherit;
2251+ }
2252+
2253+ &:last-of-type::after {
2254+ display: none;
2255+ }
2256+ }
2257+}
2258diff --git a/src/maasserver/static/scss/tables/_network-discovery.scss b/src/maasserver/static/scss/tables/_network-discovery.scss
2259new file mode 100644
2260index 0000000..bde66c4
2261--- /dev/null
2262+++ b/src/maasserver/static/scss/tables/_network-discovery.scss
2263@@ -0,0 +1,37 @@
2264+@mixin maas-table--network-discovery {
2265+ .p-table--network-discovery {
2266+ tr {
2267+ justify-content: space-between;
2268+ }
2269+
2270+ th,
2271+ td {
2272+ flex: 0 0 auto;
2273+ }
2274+
2275+ &__name {
2276+ width: 15%;
2277+ }
2278+
2279+ &__mac {
2280+ width: 20%;
2281+ }
2282+
2283+ &__ip {
2284+ width: 25%;
2285+ }
2286+
2287+ &__rack {
2288+ width: 15%;
2289+ }
2290+
2291+ &__last-seen {
2292+ width: calc(25% - #{$chevron-cell-width});
2293+ }
2294+
2295+ &__chevron {
2296+ flex: 0 0 auto;
2297+ width: $chevron-cell-width; // chevron needs a static width
2298+ }
2299+ }
2300+}
2301diff --git a/src/maasserver/static/scss/tables/_pod-networking-config.scss b/src/maasserver/static/scss/tables/_pod-networking-config.scss
2302new file mode 100644
2303index 0000000..76a5b7c
2304--- /dev/null
2305+++ b/src/maasserver/static/scss/tables/_pod-networking-config.scss
2306@@ -0,0 +1,58 @@
2307+@mixin maas-table--pod-networking-config {
2308+ .p-table--pod-networking-config {
2309+ input {
2310+ // overriding min-width to make inputs fit within container
2311+ min-width: auto;
2312+ @extend %u-input-min-margin--bottom;
2313+ }
2314+
2315+ select {
2316+ @extend %u-input-min-margin--bottom;
2317+ }
2318+
2319+ @media (min-width: $breakpoint-small) {
2320+ margin-bottom: 0;
2321+
2322+ .p-table__row {
2323+ th,
2324+ td {
2325+ &:nth-child(1) {
2326+ width: calc(#{$icon-button-width} - 2px);
2327+ }
2328+
2329+ &:nth-child(2) {
2330+ width: 10%;
2331+ }
2332+
2333+ &:nth-child(3) {
2334+ width: 25%;
2335+ }
2336+
2337+ &:nth-child(4) {
2338+ width: 15%;
2339+ }
2340+
2341+ &:nth-child(5) {
2342+ width: 23%;
2343+ }
2344+
2345+ &:nth-child(6) {
2346+ width: 10%;
2347+ }
2348+
2349+ &:nth-child(7) {
2350+ width: 12%;
2351+ }
2352+
2353+ &:nth-child(8) {
2354+ width: 5%;
2355+ }
2356+ }
2357+ }
2358+ }
2359+ }
2360+
2361+ .p-table--pod-networking-config--message {
2362+ margin-left: 35%;
2363+ }
2364+}
2365diff --git a/src/maasserver/static/scss/tables/_pod-storage-config.scss b/src/maasserver/static/scss/tables/_pod-storage-config.scss
2366new file mode 100644
2367index 0000000..40c8f79
2368--- /dev/null
2369+++ b/src/maasserver/static/scss/tables/_pod-storage-config.scss
2370@@ -0,0 +1,38 @@
2371+@mixin maas-table--pod-storage-config {
2372+ .p-table--pod-storage-config {
2373+ input {
2374+ // overriding min-width to make inputs fit within container
2375+ min-width: auto;
2376+ @extend %u-input-min-margin--bottom;
2377+ }
2378+
2379+ @media (min-width: $breakpoint-small) {
2380+ margin-bottom: 0;
2381+
2382+ .p-table__row {
2383+ th,
2384+ td {
2385+ &:nth-child(1) {
2386+ width: calc(#{$icon-button-width} - 2px);
2387+ }
2388+
2389+ &:nth-child(2) {
2390+ width: 10%;
2391+ }
2392+
2393+ &:nth-child(3) {
2394+ width: 40%;
2395+ }
2396+
2397+ &:nth-child(4) {
2398+ width: 40%;
2399+ }
2400+
2401+ &:nth-child(5) {
2402+ width: 10%;
2403+ }
2404+ }
2405+ }
2406+ }
2407+ }
2408+}
2409diff --git a/src/maasserver/static/scss/tables/_pods.scss b/src/maasserver/static/scss/tables/_pods.scss
2410new file mode 100644
2411index 0000000..a0273e8
2412--- /dev/null
2413+++ b/src/maasserver/static/scss/tables/_pods.scss
2414@@ -0,0 +1,39 @@
2415+@mixin maas-table--pods {
2416+ .p-table--pods {
2417+ .p-table__row {
2418+ .p-table__cell {
2419+ &:nth-child(1) {
2420+ width: 10%;
2421+ }
2422+
2423+ &:nth-child(2) {
2424+ width: 10%;
2425+ }
2426+
2427+ &:nth-child(3) {
2428+ width: 10%;
2429+ }
2430+
2431+ &:nth-child(4) {
2432+ width: 10%;
2433+ }
2434+
2435+ &:nth-child(5) {
2436+ width: 10%;
2437+ }
2438+
2439+ &:nth-child(6) {
2440+ width: 10%;
2441+ }
2442+
2443+ &:nth-child(7) {
2444+ width: 10%;
2445+ }
2446+
2447+ &:nth-child(8) {
2448+ width: 10%;
2449+ }
2450+ }
2451+ }
2452+ }
2453+}

Subscribers

People subscribed via source and target branches