Initial Spark Install

This commit is contained in:
Deon George
2017-11-03 16:26:07 +11:00
commit b1a5807eb3
766 changed files with 128896 additions and 0 deletions

View File

@@ -0,0 +1,151 @@
module.exports = {
/**
* The component's data.
*/
data() {
return {
plans: [],
form: new SparkForm({
name: '',
slug: ''
})
};
},
computed: {
/**
* Get the active subscription instance.
*/
activeSubscription() {
if ( ! this.$parent.billable) {
return;
}
const subscription = _.find(
this.$parent.billable.subscriptions,
subscription => subscription.name == 'default'
);
if (typeof subscription !== 'undefined') {
return subscription;
}
},
/**
* Get the active plan instance.
*/
activePlan() {
if (this.activeSubscription) {
return _.find(this.plans, (plan) => {
return plan.id == this.activeSubscription.provider_plan;
});
}
},
/**
* Check if there's a limit for the number of teams.
*/
hasTeamLimit() {
if (! this.activePlan) {
return false;
}
return !! this.activePlan.attributes.teams;
},
/**
*
* Get the remaining teams in the active plan.
*/
remainingTeams() {
var ownedTeams = _.filter(this.$parent.teams, {owner_id: this.$parent.billable.id});
return this.activePlan
? this.activePlan.attributes.teams - ownedTeams.length
: 0;
},
/**
* Check if the user can create more teams.
*/
canCreateMoreTeams() {
if (! this.hasTeamLimit) {
return true;
}
return this.remainingTeams > 0;
}
},
/**
* The component has been created by Vue.
*/
created() {
this.getPlans();
},
events: {
/**
* Handle the "activatedTab" event.
*/
activatedTab(tab) {
if (tab === Spark.pluralTeamString) {
Vue.nextTick(() => {
$('#create-team-name').focus();
});
}
return true;
}
},
watch: {
/**
* Watch the team name for changes.
*/
'form.name': function (val, oldVal) {
if (this.form.slug == '' ||
this.form.slug == oldVal.toLowerCase().replace(/[\s\W-]+/g, '-')
) {
this.form.slug = val.toLowerCase().replace(/[\s\W-]+/g, '-');
}
}
},
methods: {
/**
* Create a new team.
*/
create() {
Spark.post('/settings/'+Spark.pluralTeamString, this.form)
.then(() => {
this.form.name = '';
this.form.slug = '';
Bus.$emit('updateUser');
Bus.$emit('updateTeams');
});
},
/**
* Get all the plans defined in the application.
*/
getPlans() {
axios.get('/spark/plans')
.then(response => {
this.plans = response.data;
});
}
}
};

View File

@@ -0,0 +1,85 @@
module.exports = {
props: ['user', 'teams'],
/**
* The component's data.
*/
data() {
return {
leavingTeam: null,
deletingTeam: null,
leaveTeamForm: new SparkForm({}),
deleteTeamForm: new SparkForm({})
};
},
/**
* Prepare the component.
*/
mounted() {
$('[data-toggle="tooltip"]').tooltip();
},
methods: {
/**
* Approve leaving the given team.
*/
approveLeavingTeam(team) {
this.leavingTeam = team;
$('#modal-leave-team').modal('show');
},
/**
* Leave the given team.
*/
leaveTeam() {
Spark.delete(this.urlForLeaving, this.leaveTeamForm)
.then(() => {
Bus.$emit('updateUser');
Bus.$emit('updateTeams');
$('#modal-leave-team').modal('hide');
});
},
/**
* Approve the deletion of the given team.
*/
approveTeamDelete(team) {
this.deletingTeam = team;
$('#modal-delete-team').modal('show');
},
/**
* Delete the given team.
*/
deleteTeam() {
Spark.delete(`/settings/${Spark.pluralTeamString}/${this.deletingTeam.id}`, this.deleteTeamForm)
.then(() => {
Bus.$emit('updateUser');
Bus.$emit('updateTeams');
$('#modal-delete-team').modal('hide');
});
}
},
computed: {
/**
* Get the URL for leaving a team.
*/
urlForLeaving() {
return `/settings/${Spark.pluralTeamString}/${this.leavingTeam.id}/members/${this.user.id}`;
}
}
};

View File

@@ -0,0 +1,16 @@
module.exports = {
props: ['team', 'invitations'],
methods: {
/**
* Cancel the sent invitation.
*/
cancel(invitation) {
axios.delete(`/settings/invitations/${invitation.id}`)
.then(() => {
this.$parent.$emit('updateInvitations');
});
}
}
};

View File

@@ -0,0 +1,67 @@
module.exports = {
/**
* The component's data.
*/
data() {
return {
invitations: []
};
},
/**
* The component has been created by Vue.
*/
created() {
this.getPendingInvitations();
},
methods: {
/**
* Get the pending invitations for the user.
*/
getPendingInvitations() {
axios.get('/settings/invitations/pending')
.then(response => {
this.invitations = response.data;
});
},
/**
* Accept the given invitation.
*/
accept(invitation) {
axios.post(`/settings/invitations/${invitation.id}/accept`)
.then(() => {
Bus.$emit('updateTeams');
this.getPendingInvitations();
});
this.removeInvitation(invitation);
},
/**
* Reject the given invitation.
*/
reject(invitation) {
axios.post(`/settings/invitations/${invitation.id}/reject`)
.then(() => {
this.getPendingInvitations();
});
this.removeInvitation(invitation);
},
/**
* Remove the given invitation from the list.
*/
removeInvitation(invitation) {
this.invitations = _.reject(this.invitations, i => i.id === invitation.id);
}
}
};

View File

@@ -0,0 +1,116 @@
module.exports = {
props: ['user', 'team', 'billableType'],
/**
* The component's data.
*/
data() {
return {
plans: [],
form: new SparkForm({
email: ''
})
};
},
computed: {
/**
* Get the active subscription instance.
*/
activeSubscription() {
if ( ! this.billable) {
return;
}
const subscription = _.find(
this.billable.subscriptions,
subscription => subscription.name == 'default'
);
if (typeof subscription !== 'undefined') {
return subscription;
}
},
/**
* Get the active plan instance.
*/
activePlan() {
if (this.activeSubscription) {
return _.find(this.plans, (plan) => {
return plan.id == this.activeSubscription.provider_plan;
});
}
},
/**
* Check if there's a limit for the number of team members.
*/
hasTeamMembersLimit() {
if (! this.activePlan) {
return false;
}
return !! this.activePlan.attributes.teamMembers;
},
/**
*
* Get the remaining team members in the active plan.
*/
remainingTeamMembers() {
return this.activePlan
? this.activePlan.attributes.teamMembers - this.$parent.team.users.length
: 0;
},
/**
* Check if the user can invite more team members.
*/
canInviteMoreTeamMembers() {
if (! this.hasTeamMembersLimit) {
return true;
}
return this.remainingTeamMembers > 0;
}
},
/**
* The component has been created by Vue.
*/
created() {
this.getPlans();
},
methods: {
/**
* Send a team invitation.
*/
send() {
Spark.post(`/settings/${Spark.pluralTeamString}/${this.team.id}/invitations`, this.form)
.then(() => {
this.form.email = '';
this.$parent.$emit('updateInvitations');
});
},
/**
* Get all the plans defined in the application.
*/
getPlans() {
axios.get('/spark/plans')
.then(response => {
this.plans = response.data;
});
}
}
};

View File

@@ -0,0 +1,144 @@
module.exports = {
props: ['user', 'team'],
/**
* The component's data.
*/
data() {
return {
roles: [],
updatingTeamMember: null,
deletingTeamMember: null,
updateTeamMemberForm: $.extend(true, new SparkForm({
role: ''
}), Spark.forms.updateTeamMember),
deleteTeamMemberForm: new SparkForm({})
}
},
/**
* The component has been created by Vue.
*/
created() {
this.getRoles();
},
methods: {
/**
* Get the available team member roles.
*/
getRoles() {
axios.get(`/settings/${Spark.pluralTeamString}/roles`)
.then(response => {
this.roles = response.data;
});
},
/**
* Edit the given team member.
*/
editTeamMember(member) {
this.updatingTeamMember = member;
this.updateTeamMemberForm.role = member.pivot.role;
$('#modal-update-team-member').modal('show');
},
/**
* Update the team member.
*/
update() {
Spark.put(this.urlForUpdating, this.updateTeamMemberForm)
.then(() => {
Bus.$emit('updateTeam');
$('#modal-update-team-member').modal('hide');
});
},
/**
* Display the approval modal for the deletion of a team member.
*/
approveTeamMemberDelete(member) {
this.deletingTeamMember = member;
$('#modal-delete-member').modal('show');
},
/**
* Delete the given team member.
*/
deleteMember() {
Spark.delete(this.urlForDeleting, this.deleteTeamMemberForm)
.then(() => {
Bus.$emit('updateTeam');
$('#modal-delete-member').modal('hide');
});
},
/**
* Determine if the current user can edit a team member.
*/
canEditTeamMember(member) {
return this.user.id === this.team.owner_id && this.user.id !== member.id
},
/**
* Determine if the current user can delete a team member.
*/
canDeleteTeamMember(member) {
return this.user.id === this.team.owner_id && this.user.id !== member.id
},
/**
* Get the displayable role for the given team member.
*/
teamMemberRole(member) {
if (this.roles.length == 0) {
return '';
}
if (member.pivot.role == 'owner') {
return 'Owner';
}
const role = _.find(this.roles, role => role.value == member.pivot.role);
if (typeof role !== 'undefined') {
return role.text;
}
}
},
computed: {
/**
* Get the URL for updating a team member.
*/
urlForUpdating: function () {
return `/settings/${Spark.pluralTeamString}/${this.team.id}/members/${this.updatingTeamMember.id}`;
},
/**
* Get the URL for deleting a team member.
*/
urlForDeleting() {
return `/settings/${Spark.pluralTeamString}/${this.team.id}/members/${this.deletingTeamMember.id}`;
}
}
};

View File

@@ -0,0 +1,39 @@
module.exports = {
props: ['user', 'team', 'billableType'],
/**
* The component's data.
*/
data() {
return {
invitations: []
};
},
/**
* The component has been created by Vue.
*/
created() {
var self = this;
this.getInvitations();
this.$on('updateInvitations', function () {
self.getInvitations();
});
},
methods: {
/**
* Get all of the invitations for the team.
*/
getInvitations() {
axios.get(`/settings/${Spark.pluralTeamString}/${this.team.id}/invitations`)
.then(response => {
this.invitations = response.data;
});
}
}
};

View File

@@ -0,0 +1,3 @@
module.exports = {
props: ['user', 'team']
};

View File

@@ -0,0 +1,55 @@
module.exports = {
props: ['user', 'teamId'],
/**
* Load mixins for the component.
*/
mixins: [require('./../../mixins/tab-state')],
/**
* The component's data.
*/
data() {
return {
billableType: 'team',
team: null
};
},
/**
* The component has been created by Vue.
*/
created() {
var self = this;
this.getTeam();
Bus.$on('updateTeam', function () {
self.getTeam();
});
},
/**
* Prepare the component.
*/
mounted() {
this.usePushStateForTabs('.spark-settings-tabs');
},
methods: {
/**
* Get the team being managed.
*/
getTeam() {
axios.get(`/${Spark.pluralTeamString}/${this.teamId}`)
.then(response => {
this.team = response.data;
});
}
}
};

View File

@@ -0,0 +1,36 @@
module.exports = {
props: ['user', 'team'],
/**
* The component's data.
*/
data() {
return {
form: new SparkForm({
name: ''
})
};
},
/**
* Prepare the component.
*/
mounted() {
this.form.name = this.team.name;
},
methods: {
/**
* Update the team name.
*/
update() {
Spark.put(`/settings/${Spark.pluralTeamString}/${this.team.id}/name`, this.form)
.then(() => {
Bus.$emit('updateTeam');
Bus.$emit('updateTeams');
});
}
}
};

View File

@@ -0,0 +1,76 @@
module.exports = {
props: ['user', 'team'],
/**
* The component's data.
*/
data() {
return {
form: new SparkForm({})
};
},
methods: {
/**
* Update the team's photo.
*/
update(e) {
e.preventDefault();
if ( ! this.$refs.photo.files.length) {
return;
}
var self = this;
this.form.startProcessing();
// We need to gather a fresh FormData instance with the profile photo appended to
// the data so we can POST it up to the server. This will allow us to do async
// uploads of the profile photos. We will update the user after this action.
axios.post(this.urlForUpdate, this.gatherFormData())
.then(
() => {
Bus.$emit('updateTeam');
Bus.$emit('updateTeams');
self.form.finishProcessing();
},
(error) => {
self.form.setErrors(error.response.data.errors);
}
);
},
/**
* Gather the form data for the photo upload.
*/
gatherFormData() {
const data = new FormData();
data.append('photo', this.$refs.photo.files[0]);
return data;
}
},
computed: {
/**
* Get the URL for updating the team photo.
*/
urlForUpdate() {
return `/settings/${Spark.pluralTeamString}/${this.team.id}/photo`;
},
/**
* Calculate the style attribute for the photo preview.
*/
previewStyle() {
return `background-image: url(${this.team.photo_url})`;
}
}
};