mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-06 01:08:21 +01:00
welcome tour + save completed tours in database
This commit is contained in:
parent
11a2dde776
commit
5b46edd748
@ -329,10 +329,10 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retreive once the notifications from the server and display a message popup for each new one.
|
* Retrieve once the notifications from the server and display a message popup for each new one.
|
||||||
* Then, periodically check for new notifications.
|
* Then, periodically check for new notifications.
|
||||||
*/
|
*/
|
||||||
var getNotifications = function () {
|
const getNotifications = function () {
|
||||||
$rootScope.toCheckNotifications = true;
|
$rootScope.toCheckNotifications = true;
|
||||||
if (!$rootScope.checkNotificationsIsInit && !!$rootScope.currentUser) {
|
if (!$rootScope.checkNotificationsIsInit && !!$rootScope.currentUser) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
@ -373,7 +373,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
|||||||
/**
|
/**
|
||||||
* Open the modal window allowing the user to log in.
|
* Open the modal window allowing the user to log in.
|
||||||
*/
|
*/
|
||||||
var openLoginModal = function (toState, toParams, callback) {
|
const openLoginModal = function (toState, toParams, callback) {
|
||||||
<% active_provider = AuthProvider.active %>
|
<% active_provider = AuthProvider.active %>
|
||||||
<% if active_provider.providable_type != DatabaseProvider.name %>
|
<% if active_provider.providable_type != DatabaseProvider.name %>
|
||||||
$window.location.href = '/sso-redirect';
|
$window.location.href = '/sso-redirect';
|
||||||
@ -480,7 +480,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
|||||||
* When the status changes, the callback is triggered with the new status as parameter
|
* When the status changes, the callback is triggered with the new status as parameter
|
||||||
* Inspired by http://stackoverflow.com/questions/1060008/is-there-a-way-to-detect-if-a-browser-window-is-not-currently-active#answer-1060034
|
* Inspired by http://stackoverflow.com/questions/1060008/is-there-a-way-to-detect-if-a-browser-window-is-not-currently-active#answer-1060034
|
||||||
*/
|
*/
|
||||||
var onPageVisible = function (callback) {
|
const onPageVisible = function (callback) {
|
||||||
let hidden = 'hidden';
|
let hidden = 'hidden';
|
||||||
|
|
||||||
const onchange = function (evt) {
|
const onchange = function (evt) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Application.Controllers.controller('HomeController', ['$scope', '$stateParams', 'homeContentPromise', 'uiTourService', '_t',
|
Application.Controllers.controller('HomeController', ['$scope', '$stateParams', 'homeContentPromise', 'Member', 'uiTourService', '_t',
|
||||||
function ($scope, $stateParams, homeContentPromise, uiTourService, _t) {
|
function ($scope, $stateParams, homeContentPromise, Member, uiTourService, _t) {
|
||||||
/* PUBLIC SCOPE */
|
/* PUBLIC SCOPE */
|
||||||
|
|
||||||
// Home page HTML content
|
// Home page HTML content
|
||||||
@ -22,8 +22,48 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
|
|||||||
// We set the home page content, with the directives replacing the placeholders
|
// We set the home page content, with the directives replacing the placeholders
|
||||||
$scope.homeContent = insertDirectives(homeContentPromise.setting.value);
|
$scope.homeContent = insertDirectives(homeContentPromise.setting.value);
|
||||||
|
|
||||||
// setup the tour
|
// setup the tour for admins
|
||||||
|
if ($scope.currentUser && $scope.currentUser.role === 'admin') {
|
||||||
|
setupWelcomeTour();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const insertDirectives = function (html) {
|
||||||
|
const node = document.createElement('div');
|
||||||
|
node.innerHTML = html.trim();
|
||||||
|
|
||||||
|
node.querySelectorAll('div#news').forEach((newsNode) => {
|
||||||
|
const news = document.createElement('news');
|
||||||
|
newsNode.parentNode.replaceChild(news, newsNode);
|
||||||
|
});
|
||||||
|
|
||||||
|
node.querySelectorAll('div#projects').forEach((projectsNode) => {
|
||||||
|
const projects = document.createElement('projects');
|
||||||
|
projectsNode.parentNode.replaceChild(projects, projectsNode);
|
||||||
|
});
|
||||||
|
|
||||||
|
node.querySelectorAll('div#twitter').forEach((twitterNode) => {
|
||||||
|
const twitter = document.createElement('twitter');
|
||||||
|
twitterNode.parentNode.replaceChild(twitter, twitterNode);
|
||||||
|
});
|
||||||
|
|
||||||
|
node.querySelectorAll('div#members').forEach((membersNode) => {
|
||||||
|
const members = document.createElement('members');
|
||||||
|
membersNode.parentNode.replaceChild(members, membersNode);
|
||||||
|
});
|
||||||
|
|
||||||
|
node.querySelectorAll('div#events').forEach((eventsNode) => {
|
||||||
|
const events = document.createElement('events');
|
||||||
|
eventsNode.parentNode.replaceChild(events, eventsNode);
|
||||||
|
});
|
||||||
|
|
||||||
|
return node.outerHTML;
|
||||||
|
};
|
||||||
|
|
||||||
|
const setupWelcomeTour = function () {
|
||||||
|
// get the tour defined by the ui-tour directive
|
||||||
const uitour = uiTourService.getTour();
|
const uitour = uiTourService.getTour();
|
||||||
|
// add the steps
|
||||||
uitour.createStep({
|
uitour.createStep({
|
||||||
selector: 'body',
|
selector: 'body',
|
||||||
stepId: 'welcome',
|
stepId: 'welcome',
|
||||||
@ -97,10 +137,18 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
|
|||||||
content: _t('app.public.tour.plans.content'),
|
content: _t('app.public.tour.plans.content'),
|
||||||
placement: 'right'
|
placement: 'right'
|
||||||
});
|
});
|
||||||
|
uitour.createStep({
|
||||||
|
selector: '.nav-primary .admin-section',
|
||||||
|
stepId: 'admin',
|
||||||
|
order: 9,
|
||||||
|
title: _t('app.public.tour.admin.title'),
|
||||||
|
content: _t('app.public.tour.admin.content'),
|
||||||
|
placement: 'right'
|
||||||
|
});
|
||||||
uitour.createStep({
|
uitour.createStep({
|
||||||
selector: '.navbar.header li.about-page-link',
|
selector: '.navbar.header li.about-page-link',
|
||||||
stepId: 'about',
|
stepId: 'about',
|
||||||
order: 9,
|
order: 10,
|
||||||
title: _t('app.public.tour.about.title'),
|
title: _t('app.public.tour.about.title'),
|
||||||
content: _t('app.public.tour.about.content'),
|
content: _t('app.public.tour.about.content'),
|
||||||
placement: 'bottom'
|
placement: 'bottom'
|
||||||
@ -108,7 +156,7 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
|
|||||||
uitour.createStep({
|
uitour.createStep({
|
||||||
selector: '.navbar.header li.notification-center-link',
|
selector: '.navbar.header li.notification-center-link',
|
||||||
stepId: 'notifications',
|
stepId: 'notifications',
|
||||||
order: 10,
|
order: 11,
|
||||||
title: _t('app.public.tour.notifications.title'),
|
title: _t('app.public.tour.notifications.title'),
|
||||||
content: _t('app.public.tour.notifications.content'),
|
content: _t('app.public.tour.notifications.content'),
|
||||||
placement: 'bottom'
|
placement: 'bottom'
|
||||||
@ -116,44 +164,47 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
|
|||||||
uitour.createStep({
|
uitour.createStep({
|
||||||
selector: '.navbar.header li.user-menu-dropdown',
|
selector: '.navbar.header li.user-menu-dropdown',
|
||||||
stepId: 'profile',
|
stepId: 'profile',
|
||||||
order: 11,
|
order: 12,
|
||||||
title: _t('app.public.tour.profile.title'),
|
title: _t('app.public.tour.profile.title'),
|
||||||
content: _t('app.public.tour.profile.content'),
|
content: _t('app.public.tour.profile.content'),
|
||||||
placement: 'bottom'
|
placement: 'bottom'
|
||||||
});
|
});
|
||||||
uitour.start();
|
uitour.createStep({
|
||||||
};
|
selector: '.app-generator .app-version',
|
||||||
|
stepId: 'version',
|
||||||
const insertDirectives = function (html) {
|
order: 13,
|
||||||
const node = document.createElement('div');
|
title: _t('app.public.tour.version.title'),
|
||||||
node.innerHTML = html.trim();
|
content: _t('app.public.tour.version.content'),
|
||||||
|
placement: 'top'
|
||||||
node.querySelectorAll('div#news').forEach((newsNode) => {
|
|
||||||
const news = document.createElement('news');
|
|
||||||
newsNode.parentNode.replaceChild(news, newsNode);
|
|
||||||
});
|
});
|
||||||
|
uitour.createStep({
|
||||||
node.querySelectorAll('div#projects').forEach((projectsNode) => {
|
selector: 'body',
|
||||||
const projects = document.createElement('projects');
|
stepId: 'conclusion',
|
||||||
projectsNode.parentNode.replaceChild(projects, projectsNode);
|
order: 14,
|
||||||
|
title: _t('app.public.tour.conclusion.title'),
|
||||||
|
content: _t('app.public.tour.conclusion.content'),
|
||||||
|
placement: 'bottom',
|
||||||
|
orphan: true
|
||||||
});
|
});
|
||||||
|
// on tour end, save the status in database
|
||||||
node.querySelectorAll('div#twitter').forEach((twitterNode) => {
|
uitour.on('ended', function () {
|
||||||
const twitter = document.createElement('twitter');
|
if (uitour.getStatus() === uitour.Status.ON && $scope.currentUser.profile.tours.indexOf('welcome') < 0) {
|
||||||
twitterNode.parentNode.replaceChild(twitter, twitterNode);
|
Member.completeTour({ id: $scope.currentUser.id }, { tour: 'welcome' }, function (res) {
|
||||||
|
$scope.currentUser.profile.tours = res.tours;
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
// if the user has never seen the tour, show him now
|
||||||
node.querySelectorAll('div#members').forEach((membersNode) => {
|
if ($scope.currentUser.profile.tours.indexOf('welcome') < 0) {
|
||||||
const members = document.createElement('members');
|
uitour.start();
|
||||||
membersNode.parentNode.replaceChild(members, membersNode);
|
}
|
||||||
|
// start this tour when an user press F1 - this is contextual help
|
||||||
|
window.addEventListener('keydown', function (e) {
|
||||||
|
if (e.key === 'F1') {
|
||||||
|
e.preventDefault();
|
||||||
|
uitour.start();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
node.querySelectorAll('div#events').forEach((eventsNode) => {
|
|
||||||
const events = document.createElement('events');
|
|
||||||
eventsNode.parentNode.replaceChild(events, eventsNode);
|
|
||||||
});
|
|
||||||
|
|
||||||
return node.outerHTML;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// !!! MUST BE CALLED AT THE END of the controller
|
// !!! MUST BE CALLED AT THE END of the controller
|
||||||
|
@ -30,6 +30,11 @@ Application.Services.factory('Member', ['$resource', function ($resource) {
|
|||||||
mapping: {
|
mapping: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/members/mapping'
|
url: '/api/members/mapping'
|
||||||
|
},
|
||||||
|
completeTour: {
|
||||||
|
method: 'PATCH',
|
||||||
|
url: '/api/members/:id/complete_tour',
|
||||||
|
params: { id: '@id' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
<!-- Admin entries -->
|
<!-- Admin entries -->
|
||||||
<div class="line-s bg-red-dark dk " ng-if="isAuthorized('admin')"></div>
|
<div class="line-s bg-red-dark dk " ng-if="isAuthorized('admin')"></div>
|
||||||
<div class="text-xs font-bold text-bordeau hidden-nav-xs padder m-t-lg m-b-sm" ng-if="isAuthorized('admin')" translate>{{ 'app.public.common.admin' }}</div>
|
<div class="text-xs font-bold text-bordeau hidden-nav-xs padder m-t-lg m-b-sm admin-section" ng-if="isAuthorized('admin')" translate>{{ 'app.public.common.admin' }}</div>
|
||||||
<ul class="nav" ng-if="isAuthorized('admin')">
|
<ul class="nav" ng-if="isAuthorized('admin')">
|
||||||
<li class="" ng-repeat="navLink in adminNavLinks">
|
<li class="" ng-repeat="navLink in adminNavLinks">
|
||||||
<a ng-click="toggleNavSize($event)" ga ui-sref="{{navLink.state}}" ui-sref-active="active" class="auto" data-toggle="class:nav-off-screen" data-target="#nav">
|
<a ng-click="toggleNavSize($event)" ga ui-sref="{{navLink.state}}" ui-sref-active="active" class="auto" data-toggle="class:nav-off-screen" data-target="#nav">
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-sm btn-default" ng-if="tourStep.isPrev()" ng-click="tour.prev()" translate>{{ 'app.public.tour.previous' }}</button>
|
<button type="button" class="btn btn-sm btn-default" ng-if="tourStep.isPrev()" ng-click="tour.prev()" translate>{{ 'app.public.tour.previous' }}</button>
|
||||||
<button type="button" class="btn btn-sm btn-default" ng-if="tourStep.isNext()" ng-click="tour.next()" translate>{{ 'app.public.tour.next' }}</button>
|
<button type="button" class="btn btn-sm btn-default" ng-if="tourStep.isNext()" ng-click="tour.next()" translate>{{ 'app.public.tour.next' }}</button>
|
||||||
<button type="button" class="btn btn-sm btn-default" ng-click="tour.pause()" translate>{{ 'app.public.tour.pause' }}</button>
|
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-sm btn-default" ng-click="tour.end()" translate>{{ 'app.public.tour.end' }}</button>
|
<button type="button" class="btn btn-sm btn-default" ng-click="tour.end()" translate>{{ 'app.public.tour.end' }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# API Controller for resources of type User with role 'member'
|
# API Controller for resources of type User with role 'member'
|
||||||
class API::MembersController < API::ApiController
|
class API::MembersController < API::ApiController
|
||||||
before_action :authenticate_user!, except: [:last_subscribed]
|
before_action :authenticate_user!, except: [:last_subscribed]
|
||||||
before_action :set_member, only: %i[update destroy merge]
|
before_action :set_member, only: %i[update destroy merge complete_tour]
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@ -189,6 +189,15 @@ class API::MembersController < API::ApiController
|
|||||||
@members = User.includes(:profile)
|
@members = User.includes(:profile)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def complete_tour
|
||||||
|
authorize @member
|
||||||
|
|
||||||
|
tours = "#{@member.profile.tours} #{params[:tour]}"
|
||||||
|
@member.profile.update_attributes(tours: tours.strip)
|
||||||
|
|
||||||
|
render json: { tours: @member.profile.tours }
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_member
|
def set_member
|
||||||
|
@ -31,6 +31,10 @@ class UserPolicy < ApplicationPolicy
|
|||||||
user.id == record.id
|
user.id == record.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def complete_tour?
|
||||||
|
user.id == record.id
|
||||||
|
end
|
||||||
|
|
||||||
%w[list create mapping].each do |action|
|
%w[list create mapping].each do |action|
|
||||||
define_method "#{action}?" do
|
define_method "#{action}?" do
|
||||||
user.admin?
|
user.admin?
|
||||||
|
@ -21,6 +21,7 @@ json.profile do
|
|||||||
json.website member.profile.website
|
json.website member.profile.website
|
||||||
json.job member.profile.job
|
json.job member.profile.job
|
||||||
json.extract! member.profile, :facebook, :twitter, :google_plus, :viadeo, :linkedin, :instagram, :youtube, :vimeo, :dailymotion, :github, :echosciences, :pinterest, :lastfm, :flickr
|
json.extract! member.profile, :facebook, :twitter, :google_plus, :viadeo, :linkedin, :instagram, :youtube, :vimeo, :dailymotion, :github, :echosciences, :pinterest, :lastfm, :flickr
|
||||||
|
json.tours member.profile.tours&.split || []
|
||||||
end
|
end
|
||||||
|
|
||||||
json.invoicing_profile do
|
json.invoicing_profile do
|
||||||
|
@ -89,7 +89,14 @@
|
|||||||
<![endif]-->
|
<![endif]-->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body ng-controller="ApplicationController" ng-init="setCurrentUser(<%= current_user ? current_user.to_json : 'null' %>)" ng-cloak ui-tour ui-tour-backdrop="true" ui-tour-template-url="'<%= asset_path "shared/tour-step-template.html" %>'" ui-tour-scroll-offset="0">
|
<body ng-controller="ApplicationController"
|
||||||
|
ng-init="setCurrentUser(<%= current_user ? current_user.to_json : 'null' %>)"
|
||||||
|
ng-cloak
|
||||||
|
ui-tour
|
||||||
|
ui-tour-backdrop="true"
|
||||||
|
ui-tour-template-url="'<%= asset_path "shared/tour-step-template.html" %>'"
|
||||||
|
ui-tour-use-hotkeys="true"
|
||||||
|
>
|
||||||
<div growl></div>
|
<div growl></div>
|
||||||
|
|
||||||
<%= flash_messages %>
|
<%= flash_messages %>
|
||||||
|
@ -381,7 +381,6 @@ fr:
|
|||||||
tour:
|
tour:
|
||||||
previous: "Précédent"
|
previous: "Précédent"
|
||||||
next: "Suivant"
|
next: "Suivant"
|
||||||
pause: "Pause"
|
|
||||||
end: "Terminer la visite"
|
end: "Terminer la visite"
|
||||||
welcome:
|
welcome:
|
||||||
title: "Bienvenue dans Fab-Manager"
|
title: "Bienvenue dans Fab-Manager"
|
||||||
@ -403,20 +402,29 @@ fr:
|
|||||||
content: "Une soirée porte ouverte ou un stage pour fabriquer sa lampe de bureau ? C'est par ici !"
|
content: "Une soirée porte ouverte ou un stage pour fabriquer sa lampe de bureau ? C'est par ici !"
|
||||||
calendar:
|
calendar:
|
||||||
title: "Le calendrier publique"
|
title: "Le calendrier publique"
|
||||||
content: "Visualisez en un clin d'oeil tout ce qui est prévu au programme des prochaines semaines"
|
content: "Visualisez en un clin d'oeil tout ce qui est prévu au programme des prochaines semaines."
|
||||||
projects:
|
projects:
|
||||||
title: "Les projets"
|
title: "Les projets"
|
||||||
content: "Documentez et partagez avec la communauté toutes vos réalisations"
|
content: "Documentez et partagez avec la communauté toutes vos réalisations."
|
||||||
plans:
|
plans:
|
||||||
title: "Les abonnements"
|
title: "Les abonnements"
|
||||||
content: "Les abonnements offrent un moyen de segmenter vos tarifs et d'accorder des avantages aux utilisateurs réguliers"
|
content: "Les abonnements offrent un moyen de segmenter vos tarifs et d'accorder des avantages aux utilisateurs réguliers."
|
||||||
|
admin:
|
||||||
|
title: "Section administrateur"
|
||||||
|
content: "L'ensemble des éléments ci-dessous ne sont accessibles qu'aux administrateurs. Ils permettent de gérer et de configurer Fab-Manager. À la fin de cette visite, cliquez sur l'un d'entre eux pour en savoir plus."
|
||||||
about:
|
about:
|
||||||
title: "À propos"
|
title: "À propos"
|
||||||
content: "Une page que vous pouvez entièrement personnaliser, pour y présenter votre activité"
|
content: "Une page que vous pouvez entièrement personnaliser, pour y présenter votre activité."
|
||||||
notifications:
|
notifications:
|
||||||
title: "Centre de notifications"
|
title: "Centre de notifications"
|
||||||
content: "Chaque fois qu'il se passe quelque chose d'important, vous serez notifié ici"
|
content: "Chaque fois qu'il se passe quelque chose d'important, vous serez notifié ici."
|
||||||
profile:
|
profile:
|
||||||
title: "Menu utilisateur"
|
title: "Menu utilisateur"
|
||||||
content: "Retrouvez ici vos informations personnelles ainsi que toute votre activité sur Fab-Manager"
|
content: "Retrouvez ici vos informations personnelles ainsi que toute votre activité sur Fab-Manager."
|
||||||
|
version:
|
||||||
|
title: "Version de l'application"
|
||||||
|
content: "Passez votre curseur sur cette icône pour connaître la version de Fab-Manager. Si vous n'êtes pas à jour, cela vous sera signalé ici et vous pourrez alors obtenir des détails en cliquant dessus."
|
||||||
|
conclusion:
|
||||||
|
title: "Merci de votre attention"
|
||||||
|
content: "Affichez de l'aide en appuyant sur <strong>F1</strong> à n'importe quel moment.<br> Bonne continuation avec Fab-Manager."
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ Rails.application.routes.draw do
|
|||||||
post 'list', action: 'list', on: :collection
|
post 'list', action: 'list', on: :collection
|
||||||
get 'search/:query', action: 'search', on: :collection
|
get 'search/:query', action: 'search', on: :collection
|
||||||
get 'mapping', action: 'mapping', on: :collection
|
get 'mapping', action: 'mapping', on: :collection
|
||||||
|
patch ':id/complete_tour', action: 'complete_tour', on: :collection
|
||||||
end
|
end
|
||||||
resources :reservations, only: %i[show create index update]
|
resources :reservations, only: %i[show create index update]
|
||||||
resources :notifications, only: %i[index show update] do
|
resources :notifications, only: %i[index show update] do
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# From this migration, we distinct multiple stylesheets by their name (previously there was one only one for the main theme override)
|
||||||
class AddNameToStylesheet < ActiveRecord::Migration
|
class AddNameToStylesheet < ActiveRecord::Migration
|
||||||
def change
|
def change
|
||||||
add_column :stylesheets, :name, :string
|
add_column :stylesheets, :name, :string
|
||||||
|
8
db/migrate/20200218092221_add_tours_to_profile.rb
Normal file
8
db/migrate/20200218092221_add_tours_to_profile.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# From this migration, we save in database the "feature tours" viewed by each users to prevent displaying them many times
|
||||||
|
class AddToursToProfile < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :profiles, :tours, :string
|
||||||
|
end
|
||||||
|
end
|
11
db/schema.rb
11
db/schema.rb
@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20200127111404) do
|
ActiveRecord::Schema.define(version: 20200218092221) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@ -465,6 +465,14 @@ ActiveRecord::Schema.define(version: 20200127111404) do
|
|||||||
|
|
||||||
add_index "plans", ["group_id"], name: "index_plans_on_group_id", using: :btree
|
add_index "plans", ["group_id"], name: "index_plans_on_group_id", using: :btree
|
||||||
|
|
||||||
|
create_table "plans_availabilities", force: :cascade do |t|
|
||||||
|
t.integer "plan_id"
|
||||||
|
t.integer "availability_id"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "plans_availabilities", ["availability_id"], name: "index_plans_availabilities_on_availability_id", using: :btree
|
||||||
|
add_index "plans_availabilities", ["plan_id"], name: "index_plans_availabilities_on_plan_id", using: :btree
|
||||||
|
|
||||||
create_table "price_categories", force: :cascade do |t|
|
create_table "price_categories", force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.text "conditions"
|
t.text "conditions"
|
||||||
@ -511,6 +519,7 @@ ActiveRecord::Schema.define(version: 20200127111404) do
|
|||||||
t.string "lastfm"
|
t.string "lastfm"
|
||||||
t.string "flickr"
|
t.string "flickr"
|
||||||
t.string "job"
|
t.string "job"
|
||||||
|
t.string "tours"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "profiles", ["user_id"], name: "index_profiles_on_user_id", using: :btree
|
add_index "profiles", ["user_id"], name: "index_profiles_on_user_id", using: :btree
|
||||||
|
Loading…
x
Reference in New Issue
Block a user