Skip to content
This repository has been archived by the owner on Apr 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request #3 from nodes-vapor/feature/prepare-first-release
Browse files Browse the repository at this point in the history
WIP: Finalize first release
  • Loading branch information
steffendsommer authored Sep 29, 2017
2 parents 5346f01 + 0b7c120 commit e5e144a
Show file tree
Hide file tree
Showing 71 changed files with 796 additions and 5,216 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ Config/secrets/
node_modules/
bower_components/
.swift-version
CMakeLists.txt
CMakeLists.txt
Package.pins
Package.resolved
22 changes: 22 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
os:
- osx

language: swift
sudo: required
osx_image: xcode8.3

before_install:
brew tap vapor/tap;
brew update;
brew install vapor;
brew install cmysql;
gem install xcpretty;

script:
- swift build
- swift build -c release
- swift package generate-xcodeproj --enable-code-coverage
- xcodebuild -scheme AdminPanelProvider -enableCodeCoverage YES test | xcpretty && exit ${PIPESTATUS[0]}

after_success:
- bash <(curl -s https://codecov.io/bash)
6 changes: 2 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ let package = Package(
// Nodes
.Package(url: "https://github.com/nodes-vapor/flash.git", majorVersion: 1),
.Package(url: "https://github.com/nodes-vapor/slugify.git", majorVersion: 1),
.Package(url: "https://github.com/nodes-vapor/storage", majorVersion: 0, minor: 4),
.Package(url: "https://github.com/nodes-vapor/storage.git", majorVersion: 0, minor: 4),
.Package(url: "https://github.com/nodes-vapor/paginator.git", majorVersion: 1),

// Brett
.Package(url: "https://github.com/BrettRToomey/stencil-provider.git", majorVersion: 0),
.Package(url: "https://github.com/nodes-vapor/audit-provider.git", majorVersion: 0, minor: 1),
]
)
69 changes: 69 additions & 0 deletions Public/dist/js/admin-panel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
var AdminPanel = (function() {
return {
confirmDelete: function(element) {
// Confirm modal title
var modalTitle = $(element).data('header');
modalTitle = !modalTitle ? 'Please confirm' : modalTitle;

// Confirm modal text
var modalText = $(element).data('text');
modalText = !modalText ? 'Are you sure you want to delete?' : modalText;

var closure = function(e) {
// Prevent default action
e.preventDefault();

// Generate bootbox dialog
bootbox.dialog({
title: modalTitle,
message: '<span class="fa fa-warning"></span> ' + modalText,
className: 'modal modal-danger',
buttons: {
cancel: {
label: 'Cancel',
className: 'btn-outline'
},
success: {
label: 'Delete',
className: 'btn-outline',
callback: function () {
if ($(element).is('form')) {
$(element).trigger('submit');
} else {
// Since we're posting data, we need to add our CSRF token
// to our form so Laravel will accept our form
// var csrfToken = $(element).data('token');
// if (!csrfToken) {
// alert('Missing CSRF token');
// console.log('Missing CSRF token');
// return;
// }

// Since <form>'s can't send a DELETE request
// we need to use `POST`
$('<form/>', {
'method': 'POST',
'action': $(element).attr('href')
}).appendTo('body').submit();
}
}
}
},
onEscape: true
});
};

if ($(element).is('form')) {
$(element).find(':submit').click(closure);
} else {
$(element).click(closure);
}
}
}
})();

$( document ).ready(function() {
$('[data-delete="true"]').each(function() {
AdminPanel.confirmDelete($(this));
});
})
Binary file removed Public/images/it-works.png
Binary file not shown.
127 changes: 126 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,126 @@
# Admin Panel Provider
# Admin Panel ✍️
[![Swift Version](https://img.shields.io/badge/Swift-3.1-brightgreen.svg)](http://swift.org)
[![Vapor Version](https://img.shields.io/badge/Vapor-2-F6CBCA.svg)](http://vapor.codes)
[![Linux Build Status](https://img.shields.io/circleci/project/github/nodes-vapor/admin-panel-provider.svg?label=Linux)](https://circleci.com/gh/nodes-vapor/admin-panel-provider)
[![macOS Build Status](https://img.shields.io/travis/nodes-vapor/admin-panel-provider.svg?label=macOS)](https://travis-ci.org/nodes-vapor/admin-panel-provider)
[![codebeat badge](https://codebeat.co/badges/52c2f960-625c-4a63-ae63-52a24d747da1)](https://codebeat.co/projects/github-com-nodes-vapor-admin-panel-provider)
[![codecov](https://codecov.io/gh/nodes-vapor/admin-panel-provider/branch/master/graph/badge.svg)](https://codecov.io/gh/nodes-vapor/admin-panel-provider)
[![Readme Score](http://readme-score-api.herokuapp.com/score.svg?url=https://github.com/nodes-vapor/admin-panel-provider)](http://clayallsopp.github.io/readme-score?url=https://github.com/nodes-vapor/admin-panel-provider)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nodes-vapor/admin-panel-provider/master/LICENSE)

Admin Panel makes it easy to setup and maintain admin features for your Vapor project. Here's a list of some of the top feautures that comes out of the box with this package:

- **UI Components:** Admin Panel is built using [AdminLTE](https://adminlte.io/), a highly battle-tested and maintained Control Panel Template. This means that you'll have access to features from AdminLTE through [Leaf](https://docs.vapor.codes/2.0/leaf/leaf/#leaf) tags.
- **User System:** This package come with a (admin panel) user system with roles built-in. The package also handles welcome emails and reset-password flows.
- **SSO Support:** Built-in support for adding your own custom SSO provider.
- **Activities**: Need to broadcast certain updates to the admin panel users? No problem, Admin Panel gives you some convenient functionality to manage an activity log.

## 📦 Installation

### Install package using SPM

Update your `Package.swift` file:

```swift
.Package(url: "https://github.com/nodes-vapor/admin-panel-provider.git", majorVersion: 0, minorVersion: 1)
```

Next time you run e.g. `vapor update` Admin Panel will be installed.

### Install resources

Move the `Resources`and `Public` folders from this repo into your project. Unfortunately there's no convenient to this at the moment, but one option is to download this repo as a zip and then move the folders into the root of your project. Remember to check that you're not overwriting any files in your project.


## 🚀 Getting started

### Add provider

In your `Config+Setup.swift` (or wherever you setup your providers), make sure to add the Admin Panel provider:

```swift
import AdminPanelProvider

// ...

private func setupProviders() throws {
// ...
try addProvider(AdminPanelProvider.Provider.self)
}
```

### Setup view renderer

This package relies heavily on the [Leaf](https://docs.vapor.codes/2.0/leaf/package/) view renderer. For Admin Panel to work, please make sure that you have added the `LeafProvider`:

```swift
import LeafProvider

// ...

private func setupProviders() throws {
// ...
try addProvider(LeafProvider.Provider.self)
}
```

After adding the provider, please make sure that your project is using Leaf as the view renderer. To do that, please ensure that the `view` key is set correctly in `droplet.json`:

```json
"//": "Choose which view renderer to use",
"//": "leaf: Vapor's Leaf renderer",
"view": "leaf"
```

### Seed a user

If you haven't added a SSO provider, the next thing you need to do is to seed a user in order to be able to login into your new admin panel. To do this, first add the seeder command to your `commands` array in your `droplet.json`:

```json
"//": "Choose which commands this application can run",
"//": "prepare: Supplied by the Fluent provider. Prepares the database (configure in fluent.json)",
"commands": [
"prepare",
"admin-panel:seeder"
],
```

Next run the seeder by doing:

```
vapor build; vapor run admin-panel:seeder
```

The user that will be created using the seeder will have the following credentials:

- Email: **admin@admin.com**
- Password: **admin**

## 🔧 Configurations

Admin Panel can be configured by (adding or) modifying the `adminpanel.json` config file. Below is a breakdown of the available keys.

| Key | Example value | Required | Description |
| --------- | ----------------------- | -------- | ---------------------------------------- |
| `name` | `My Tech Blog` | No | This will be the title inside of the admin panel. |
| `baseUrl` | `http://mytechblog.com` | No | This will be used to generate urls for the admin panel (e.g. when resetting a password). |
| `skin` | `green-light` | No | The skin to use for the admin panel. The options will correspond to the [available skins](https://adminlte.io/themes/AdminLTE/documentation/index.html#layout) supported by AdminLTE. Please omit the `skin-` prefix when specifying the skin. |

### Mailgun

To support sending password reset emails, configure Mailgun using `mailgun.json`. In addition to the values for `key` and `domain`, AdminPanelProvider requires a value for the key `fromAddress` and `fromName` which will be used as the sender for password reset emails.

## 🔐 SSO

Single sign-on can be a convenient way to offer users of your project to login into your admin panel.


## 🏆 Credits

This package is developed and maintained by the Vapor team at [Nodes](https://www.nodesagency.com).
The package owner for this project is [Steffen](https://github.com/steffendsommer).


## 📄 License

This package is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#extend("Layout/page")
#extend("AdminPanel/Layout/page")

#export("title") { Backend Users | #if(user) { Edit } ##else() { Create }}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#extend("Layout/page")
#extend("AdminPanel/Layout/page")

#export("title") { Backend Users }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#extend("Layout/page")
#extend("AdminPanel/Layout/page")

#export("nav-top") {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@
<ul class="menu">
#loop(request.storage.actions, "action") {
<li><a href="#()">
<div class="pull-left"><img src="/dist/img/user3-128x128.jpg" class="img-circle"></div>
<h4>#(action.name) <small><i class="fa fa-clock-o"></i> 2 hours</small></h4> <p>#(action.message)</p>
<div class="pull-left"><img src="#(action.author.avatarUrl)" class="img-circle"></div>
<h4>#(action.author.name) <small><i class="fa fa-clock-o"></i> #timeSince(action.createdAt)</small></h4> <p>#(action.message)</p>
</a></li>
}
</ul>

#menu:footer("See all activities", "/admin/activities")
}
}
#embed("Layout/Partials/user-menu")
#embed("AdminPanel/Layout/Partials/user-menu")
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="sidebar">
<!-- Sidebar Menu -->
<ul class="sidebar-menu">
#embed("Dashboard/shared-sidebar")
#embed("AdminPanel/Dashboard/shared-sidebar")
</ul><!-- /.sidebar-menu -->
</div><!-- /.sidebar -->
</div><!-- /.main-sidebar -->
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@
<!-- FastClick -->
<script src="/plugins/fastclick/fastclick.js"></script>
<!-- AdminLTE App -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"></script>
<script src="/dist/js/app.js"></script>

<script src="/dist/js/admin-panel.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#extend("Layout/base")
#extend("AdminPanel/Layout/base")

#export("page") {
<div class="content-wrapper">
<section class="content container-fluid">
#embed("Layout/Partials/alerts")
#embed("AdminPanel/Layout/Partials/alerts")
#import("content")
</section>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#extend("Layout/base")
#extend("AdminPanel/Layout/base")

#export("page") {
#embed("Layout/Partials/header")
#embed("AdminPanel/Layout/Partials/header")
#import("nav-top")
#embed("Dashboard/shared-menu")
#embed("Layout/Partials/header-post")
#embed("Layout/Partials/sidebar")
#embed("AdminPanel/Dashboard/shared-menu")
#embed("AdminPanel/Layout/Partials/header-post")
#embed("AdminPanel/Layout/Partials/sidebar")
<div class="content-wrapper">
<section class="content-header">
#import("content-header")
Expand All @@ -15,7 +15,7 @@
</ol>
</section>
<section class="content container-fluid">
#embed("Layout/Partials/alerts")
#embed("AdminPanel/Layout/Partials/alerts")
#import("content")
</section>
</div>
Expand Down
Loading

0 comments on commit e5e144a

Please sign in to comment.