Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replacing the external applications table with bootstrap grid rows and columns #151

Merged
merged 4 commits into from
Sep 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 118 additions & 98 deletions imports/ui/components/externalApplications/component.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,110 +24,130 @@ <h4 class="card-header text-muted">External applications

<div class="card-body">
<form id="app-table" class="needs-validation" novalidate>
<div class="table-responsive">
<table class="table table-sm table-hover">
<thead>
<tr>
<th class="pl-2">Name</th>
<th>URL</th>
<th>Name Match (regex)</th>
<th>Kind Match (regex)</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{{#unless externalApps}}
<tr class="app-item">
<td class="align-middle pl-2"><span>No applications have been defined</span></td>
<td class="align-middle"><span class="text-muted">https://company.example.com/{{|kind}}/{{|metadata.labels.app}}</span></td>
<td class="align-middle"><span class="text-muted">my-resource</span></td>
<td class="align-middle"><span class="text-muted">Deployment</span></td>
<td></td>
</tr>

<div class="container-fluid">
<!-- on small screens this header row will be hidden -->
<div class="d-none d-lg-block row-header">
<div class="row">
<div class="col-lg-2">Name</div>
<div class="col-lg-4">URL</div>
<div class="col-lg-2">Name Match(regex)</div>
<div class="col-lg-2">Kind Match(regex)</div>
<div class="col-lg-2">Action</div>
</div>
</div>
{{#unless externalApps}}
{{#unless showNewAppRow}}
<div class="row">
<div class="col">No applications have been defined</div>
</div>
{{/unless}}
{{#each app in externalApps}}
{{#if editMode app.name }}
<tr class="app-item-edit" data-name="{{app.name}}" data-id="{{app._id}}">
<td class="cursor-pointer pl-2">
<input type="text" name="appName" value="{{app.name}}" class="form-control" required autofocus/>
<div class="invalid-feedback"> Please enter a unique name </div>
</td>
<td class="cursor-pointer">
<input type="text" name="appLink" value="{{app.url}}" class="form-control" required/>
<div class="invalid-feedback"> Please enter a url </div>
</td>
<td class="cursor-pointer">
<input type="text" name="nameMatch" value="{{app.nameMatch}}" class="form-control"/>
</td>
<td class="cursor-pointer">
<input type="text" name="kindMatch" value="{{app.kindMatch}}" class="form-control"/>
</td>
<td>
<button class="btn btn-primary rounded-0 js-update-app" type="submit">Save</button>
<button class="btn btn-warning rounded-0 js-cancel-edit">Cancel</button>
</td>
</tr>
{{else}}
<tr class="app-item" data-name={{app.name}}>
<td tabindex="0" class="cursor-pointer app-edit align-middle pl-2"><span>{{app.name}}</span></td>
<td tabindex="0" class="cursor-pointer app-edit align-middle"><span>{{app.url}}</span></td>
<td tabindex="0" class="cursor-pointer app-edit align-middle"><span>{{app.nameMatch}}</span></td>
<td tabindex="0" class="cursor-pointer app-edit align-middle"><span>{{app.kindMatch}}</span></td>
<td>
<button class="btn btn-danger rounded-0 js-app-remove {{buttonStatus}}" data-name="{{app.name}}" alt="remove this app from RazeeDash"> Remove </button>
<div class="modal js-delete-app-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Remove "{{app.name}}"</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure you want to remove the application link for <strong>"{{app.name}}"</strong>?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary js-delete-app-confirm">Delete</button>
</div>
</div>
</div>
</div>
</td>
</tr>
{{/if}}
{{/each}}
<!-- New app -->
{{#if showNewAppRow }}
<tr class="app-item-new">
<td class="cursor-pointer pl-2">
<input type="text" name="appName" class="form-control" required autofocus/>
{{/unless}}
{{#each app in externalApps}}
{{#if editMode app.name }}
<div class="row app-item-edit" data-name="{{app.name}}" data-id="{{app._id}}">
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Name</div>
<input type="text" name="appName" value="{{app.name}}" class="form-control" required autofocus/>
<div class="invalid-feedback"> Please enter a unique name </div>
</td>
<td class="cursor-pointer">
<input type="text" name="appLink" placeholder="https://company.site.com/{{|kind}}/{{|metadata.labels.app}}" class="form-control " required/>
</div>
<div class="col-lg-4">
<div class="d-block d-lg-none row-header-sm">URL</div>
<input type="text" name="appLink" value="{{app.url}}" class="form-control" required/>
<div class="invalid-feedback"> Please enter a url </div>
</td>
<td class="cursor-pointer">
<input type="text" name="nameMatch" placeholder="my-resource" class="form-control"/>
</td>
<td class="cursor-pointer">
<input type="text" name="kindMatch" placeholder="Deployment" class="form-control"/>
</td>
<td>
<button class="btn btn-primary rounded-0 js-add-app">Save</button>
<button class="btn btn-warning rounded-0 js-cancel-add">Cancel</button>
</td>
</tr>
</div>
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Name Match(regex)</div>
<input type="text" name="nameMatch" value="{{app.nameMatch}}" class="form-control"/>
</div>
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Kind Match(regex)</div>
<input type="text" name="kindMatch" value="{{app.kindMatch}}" class="form-control"/>
</div>
<div class="col-lg-2 action-col">
<div class="d-block d-lg-none row-header-sm">Action</div>
<button class="btn btn-primary rounded-0 js-update-app" type="submit">Save</button>
<button class="btn btn-warning rounded-0 js-cancel-edit">Cancel</button>
</div>
</div>
{{else}}
<div class="row app-item" data-name={{app.name}}>
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Name</div>
<div class="app-edit">{{app.name}}</div>
</div>
<div class="col-lg-4">
<div class="d-block d-lg-none row-header-sm">URL</div>
<div class="app-edit">{{app.url}}</div>
</div>
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Name Match(regex)</div>
<div class="app-edit">{{app.nameMatch}}</div>
</div>
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Kind Match(regex)</div>
<div class="app-edit">{{app.kindMatch}}</div>
</div>
<div class="col-lg-2 action-col">
<div class="d-block d-lg-none row-header-sm">Action</div>
<button class="btn btn-danger rounded-0 js-app-remove {{buttonStatus}}" data-name="{{app.name}}" alt="remove this app from RazeeDash"> Remove </button>
<div class="modal js-delete-app-modal action-col" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Remove "{{app.name}}"</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure you want to remove the application link for <strong>"{{app.name}}"</strong>?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary js-delete-app-confirm">Delete</button>
</div>
</div>
</div>
</div>
</div>
</div>
{{/if}}
</tbody>
</table>
{{/each}}
{{#if showNewAppRow }}
<div class="row app-item-new">
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Name</div>
<input type="text" name="appName" class="form-control" required autofocus/>
<div class="invalid-feedback"> Please enter a unique name </div>
</div>
<div class="col-lg-4">
<div class="d-block d-lg-none row-header-sm">URL</div>
<input type="text" name="appLink" placeholder="https://company.site.com/{{|kind}}/{{|metadata.labels.app}}" class="form-control" required/>
<div class="invalid-feedback"> Please enter a url </div>
</div>
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Name Match(regex)</div>
<input type="text" name="nameMatch" placeholder="my-resource" class="form-control"/>
</div>
<div class="col-lg-2">
<div class="d-block d-lg-none row-header-sm">Kind Match(regex)</div>
<input type="text" name="kindMatch" placeholder="Deployment" class="form-control"/>
</div>
<div class="col-lg-2 action-col">
<div class="d-block d-lg-none row-header-sm">Action</div>
<button class="btn btn-primary rounded-0 js-add-app">Save</button>
<button class="btn btn-warning rounded-0 js-cancel-add">Cancel</button>
</div>
</div>
{{/if}}
</div>
</form>
<div>
<button class="ml-1 mt-2 btn btn-primary js-create-app" type="submit">Add</button>
</div>
{{#unless showNewAppRow}}
<div>
<button class="mt-2 btn btn-primary js-create-app" type="submit">Add</button>
</div>
{{/unless}}
</div>
</div>
</template>
65 changes: 61 additions & 4 deletions imports/ui/components/externalApplications/component.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,65 @@
.cursor-pointer {

$grey:#ced4da;

.app-edit {
min-height: 37px;
cursor: pointer;
overflow-x: scroll;
}
#app-table .container-fluid {
padding-left: 0px;
}
.app-item {
line-height: 2.5;
margin-bottom: 2px;
&:hover {
background-color: rgba(0,0,0,.075);
}
}
.app-item-edit {
margin-bottom: 2px;
}
.row-header {
line-height: 2.1;
border-bottom: solid 1px $grey;
border-top: solid 1px $grey;
font-weight: 600;
margin-bottom: 8px;
}
.row-header-sm {
border: none;
font-weight: 600;
}

// prevents the left border from being cut off when the input field is focused
td.app-edit:focus {
outline-offset: -5px;
@media (max-width: 991px) {
.app-item {
line-height: 3.5;
&:hover {
background-color: inherit;
}
}
.app-item-new {
line-height: 3.5;
}
.action-col {
border-bottom: solid 1px $grey;
padding-bottom: 10px;
}
.app-item-edit {
line-height: 3.5;
}
.form-control {
height: 39px;
}
.app-edit {
display: block;
width: 100%;
height: 39px;
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
font-weight: 400;
line-height: 1.9;
border: 1px solid $grey;
border-radius: 0px;
}
}
6 changes: 3 additions & 3 deletions imports/ui/components/externalApplications/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Template.ManageExternalApps.events({
},
'click .js-update-app'(e) {
e.preventDefault();
const appId = $(e.target).closest('tr').data('id');
const appId = $(e.target).closest('.app-item-edit').data('id');
const updatedName = $(e.target).closest('.app-item-edit').find('input[name="appName"]').val();
const updatedLink = $(e.target).closest('.app-item-edit').find('input[name="appLink"]').val();
const updatedNameMatch = $(e.target).closest('.app-item-edit').find('input[name="nameMatch"]').val();
Expand Down Expand Up @@ -176,9 +176,9 @@ Template.ManageExternalApps.events({
clickedItem.set(null);
editMode.set(false);
},
'click td.app-edit, keypress td.app-edit'(e) {
'click .app-edit, keypress .app-edit'(e) {
e.preventDefault();
const clickedRow = $(e.target).closest('tr').data('name');
const clickedRow = $(e.target).closest('.app-item').data('name');
clickedItem.set(clickedRow);
editMode.set(true);
return false;
Expand Down
7 changes: 5 additions & 2 deletions imports/ui/pages/resources/resourcesSingle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,13 @@ export class ResourcesSingle_default extends React.Component{
KindResourceTagName = resourceKinds[kind];
}

const apps = this.props.externalApplications;

return (
<div>
<ExternalApps {...this.props} />
{ apps && apps.length > 0 &&
<ExternalApps {...this.props} />
}
<ResourceKindAttrTable {...this.props} />

{KindResourceTagName &&
Expand All @@ -215,7 +219,6 @@ export class ResourcesSingle_default extends React.Component{
class ExternalApps extends React.Component{
renderLinks(applications) {

console.log(JSON.parse(this.props.resource.data));
const resourceName = _.get(this.props.resource, 'searchableData.name', this.props.selfLink);
const resourceKind = this.props.resource.searchableData.kind;

Expand Down