Initial Spark Install
This commit is contained in:
151
spark/resources/assets/js/settings/teams/create-team.js
vendored
Normal file
151
spark/resources/assets/js/settings/teams/create-team.js
vendored
Normal 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
85
spark/resources/assets/js/settings/teams/current-teams.js
vendored
Normal file
85
spark/resources/assets/js/settings/teams/current-teams.js
vendored
Normal 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}`;
|
||||
}
|
||||
}
|
||||
};
|
16
spark/resources/assets/js/settings/teams/mailed-invitations.js
vendored
Normal file
16
spark/resources/assets/js/settings/teams/mailed-invitations.js
vendored
Normal 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');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
67
spark/resources/assets/js/settings/teams/pending-invitations.js
vendored
Normal file
67
spark/resources/assets/js/settings/teams/pending-invitations.js
vendored
Normal 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);
|
||||
}
|
||||
}
|
||||
};
|
116
spark/resources/assets/js/settings/teams/send-invitation.js
vendored
Normal file
116
spark/resources/assets/js/settings/teams/send-invitation.js
vendored
Normal 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
144
spark/resources/assets/js/settings/teams/team-members.js
vendored
Normal file
144
spark/resources/assets/js/settings/teams/team-members.js
vendored
Normal 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}`;
|
||||
}
|
||||
}
|
||||
};
|
39
spark/resources/assets/js/settings/teams/team-membership.js
vendored
Normal file
39
spark/resources/assets/js/settings/teams/team-membership.js
vendored
Normal 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
3
spark/resources/assets/js/settings/teams/team-profile.js
vendored
Normal file
3
spark/resources/assets/js/settings/teams/team-profile.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
props: ['user', 'team']
|
||||
};
|
55
spark/resources/assets/js/settings/teams/team-settings.js
vendored
Normal file
55
spark/resources/assets/js/settings/teams/team-settings.js
vendored
Normal 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
36
spark/resources/assets/js/settings/teams/update-team-name.js
vendored
Normal file
36
spark/resources/assets/js/settings/teams/update-team-name.js
vendored
Normal 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');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
76
spark/resources/assets/js/settings/teams/update-team-photo.js
vendored
Normal file
76
spark/resources/assets/js/settings/teams/update-team-photo.js
vendored
Normal 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})`;
|
||||
}
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user