fixed PlatformVersionTable.vue

remove vuetable-2 (unneeded)
added prettier config (if people like double quotes better, feel free to change it)
This commit is contained in:
Jake Potrebic 2020-09-24 18:56:18 -07:00 committed by MiniDigger
parent dc277ad8ac
commit 0b2e3f2a2e
53 changed files with 1168 additions and 1542 deletions

View File

@ -3,13 +3,13 @@ module.exports = {
env: {
node: true
},
extends: ["plugin:vue/vue3-essential", "eslint:recommended", "@vue/prettier"],
extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/prettier'],
parserOptions: {
parser: "babel-eslint"
parser: 'babel-eslint'
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
"vue/no-v-for-template-key-on-child": "off"
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
"no-unused-vars": "warn"
}
};

View File

@ -0,0 +1,6 @@
{
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"printWidth": 120
}

View File

@ -1,3 +1,3 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"]
presets: ['@vue/cli-plugin-babel/preset']
};

View File

@ -25,7 +25,6 @@
"popper.js": "^1.16.1",
"query-string": "6.13.1",
"vue": "^3.0.0",
"vuetable-2": "^2.0.0-beta.4",
"webpack-jquery-ui": "^2.0.1"
},
"devDependencies": {

View File

@ -2,13 +2,7 @@
<div class="row">
<div class="col-md-9">
<div class="project-search" :class="{ 'input-group': q.length > 0 }">
<input
type="text"
class="form-control"
v-model="q"
@keydown="resetPage"
:placeholder="queryPlaceholder"
/>
<input type="text" class="form-control" v-model="q" @keydown="resetPage" :placeholder="queryPlaceholder" />
<span class="input-group-btn" v-if="q.length > 0">
<button class="btn btn-default" type="button" @click="q = ''">
<i class="fas fa-times"></i>
@ -17,8 +11,7 @@
</div>
<div v-if="!isDefault" class="clearSelection">
<a @click="reset"
><i class="fa fa-window-close"></i> Clear current search query,
categories, platform, and sort</a
><i class="fa fa-window-close"></i> Clear current search query, categories, platform, and sort</a
>
</div>
<project-list
@ -31,17 +24,10 @@
></project-list>
</div>
<div class="col-md-3">
<select
class="form-control select-sort"
v-model="sort"
@change="resetPage"
>
<option
v-for="(option, index) in availableOptions.sort"
:key="index"
:value="option.id"
>{{ option.name }}</option
>
<select class="form-control select-sort" v-model="sort" @change="resetPage">
<option v-for="(option, index) in availableOptions.sort" :key="index" :value="option.id">{{
option.name
}}</option>
</select>
<div>
@ -50,11 +36,7 @@
<div class="card">
<div class="card-header">
<h3 class="card-title">Categories</h3>
<a
class="category-reset"
@click="categories = []"
v-if="categories.length > 0"
>
<a class="category-reset" @click="categories = []" v-if="categories.length > 0">
<i class="fas fa-times white"></i>
</a>
</div>
@ -92,9 +74,7 @@
@click="tags = [platform.id]"
v-bind:class="{ active: tags.includes(platform.id) }"
>
<span :class="{ parent: platform.parent }">{{
platform.name
}}</span>
<span :class="{ parent: platform.parent }">{{ platform.name }}</span>
</a>
</div>
</div>
@ -104,16 +84,16 @@
</template>
<script>
import ProjectList from "./components/ProjectList";
import queryString from "query-string";
import {clearFromDefaults} from "./utils";
import {Category, Platform, SortOptions} from "./enums";
import debounce from "lodash/debounce";
import ProjectList from './components/ProjectList';
import queryString from 'query-string';
import { clearFromDefaults } from './utils';
import { Category, Platform, SortOptions } from './enums';
import debounce from 'lodash/debounce';
function defaultData() {
return {
q: "",
sort: "updated",
q: '',
sort: 'updated',
relevance: true,
categories: [],
tags: [],
@ -136,10 +116,7 @@ export default {
data: defaultData,
computed: {
isDefault: function() {
return (
Object.keys(clearFromDefaults(this.baseBinding, defaultData()))
.length === 0
);
return Object.keys(clearFromDefaults(this.baseBinding, defaultData())).length === 0;
},
baseBinding: function() {
return {
@ -160,26 +137,19 @@ export default {
);
},
urlBinding: function() {
return clearFromDefaults(
Object.assign({}, this.baseBinding, { page: this.page }),
defaultData()
);
return clearFromDefaults(Object.assign({}, this.baseBinding, { page: this.page }), defaultData());
},
queryPlaceholder: function() {
return (
`Search in ${
this.projectCount === null ? "all" : this.projectCount
} projects` +
`${!this.isDefault ? " matching your filters" : ""}` +
", proudly made by the community..."
`Search in ${this.projectCount === null ? 'all' : this.projectCount} projects` +
`${!this.isDefault ? ' matching your filters' : ''}` +
', proudly made by the community...'
);
}
},
methods: {
reset: function() {
Object.entries(defaultData()).forEach(
([key, value]) => (this.$data[key] = value)
);
Object.entries(defaultData()).forEach(([key, value]) => (this.$data[key] = value));
},
resetPage: function() {
this.page = 1;
@ -194,36 +164,29 @@ export default {
}
},
updateQuery(newQuery) {
window.history.pushState(
null,
null,
newQuery !== "" ? "?" + newQuery : "/"
);
window.history.pushState(null, null, newQuery !== '' ? '?' + newQuery : '/');
},
updateData() {
Object.entries(
queryString.parse(location.search, {
arrayFormat: "bracket",
arrayFormat: 'bracket',
parseBooleans: true
})
)
.filter(([key]) =>
Object.prototype.hasOwnProperty.call(defaultData(), key)
)
.filter(([key]) => Object.prototype.hasOwnProperty.call(defaultData(), key))
.forEach(([key, value]) => (this.$data[key] = value));
}
},
created() {
this.updateData();
window.addEventListener("popstate", this.updateData);
window.addEventListener('popstate', this.updateData);
this.debouncedUpdateProps = debounce(this.updateQuery, 500);
this.$watch(
() =>
[this.q, this.sort, this.relevance, this.categories, this.tags, this.page].join(),
() => [this.q, this.sort, this.relevance, this.categories, this.tags, this.page].join(),
() => {
const query = queryString.stringify(this.urlBinding, {
arrayFormat: "bracket"
arrayFormat: 'bracket'
});
this.debouncedUpdateProps(query);
}
@ -244,7 +207,7 @@ export default {
</script>
<style lang="scss" scoped>
@import "./scss/variables";
@import './scss/variables';
.select-sort {
margin-bottom: 10px;

View File

@ -5,12 +5,7 @@
<span>Loading platforms for you...</span>
</div>
<div v-show="!loading && selectedPlatform == null">
<span
v-for="platform in platforms"
@click="select(platform)"
style="cursor: pointer;"
:key="platform.name"
>
<span v-for="platform in platforms" @click="select(platform)" style="cursor: pointer;" :key="platform.name">
<Tag :name="platform.name" :color="platform.tag" />
</span>
</div>
@ -18,37 +13,25 @@
<span @click="unselect">
<i class="fas fa-times-circle"></i>
</span>
<input
type="hidden"
name="platform"
:value="selectedPlatform.id"
form="form-publish"
/>
<input type="hidden" name="platform" :value="selectedPlatform.id" form="form-publish" />
<Tag :name="selectedPlatform.name" :color="selectedPlatform.tag" />
<div>
<template v-for="(v, index) in selectedPlatform.possibleVersions">
<label :for="'version-' + v" style="margin-left: 10px;" :key="index">
<template v-for="(v, index) in selectedPlatform.possibleVersions" :key="index">
<label :for="'version-' + v" style="margin-left: 10px;">
{{ v }}
</label>
<input
form="form-publish"
:id="'version-' + v"
type="checkbox"
name="versions"
:value="v"
:key="index"
/>
<input form="form-publish" :id="'version-' + v" type="checkbox" name="versions" :value="v" />
</template>
</div>
</div>
</div>
</template>
<script>
import $ from "jquery";
import Tag from "./components/Tag";
import $ from 'jquery';
import Tag from './components/Tag';
export default {
name: "platform-choice",
name: 'platform-choice',
components: {
Tag
},
@ -70,8 +53,8 @@ export default {
created() {
const self = this;
$.ajax({
url: "/api/v1/platforms",
dataType: "json",
url: '/api/v1/platforms',
dataType: 'json',
complete: function() {
self.loading = false;

View File

@ -1,59 +1,47 @@
<template>
<div>
<vuetable
ref="platform-table"
:api-mode="false"
:data="data"
:fields="fields"
class="platform-versions"
>
<template v-slot:versions-slot="props">
<div
class="platform-version"
v-for="(v, index) in props.rowData.versions"
:key="index"
>
<span
@click="removeVersion(props.rowData.platform, v)"
style="cursor:pointer;"
>
<i class="fas fa-times" style="color: #bb0400"></i>
</span>
{{ v }}
</div>
</template>
<template v-slot:actions-slot="props">
<div class="input-group float-left">
<div class="input-group-prepend">
<span class="input-group-text">Version Identifier</span>
</div>
<label for="add-version-input" class="sr-only">Add Version</label>
<input
type="text"
id="add-version-input"
class="form-control"
v-model="inputs[props.rowData.platform]"
/>
<div class="input-group-append">
<button
type="button"
class="btn btn-primary"
@click="addVersion(props.rowData.platform)"
:disabled="!inputs[props.rowData.platform]"
>
<i class="fas fa-plus"></i>
</button>
</div>
</div>
</template>
</vuetable>
<button
v-if="!loading"
type="button"
class="btn btn-success"
@click="save"
:disabled="!changesMade"
>
<table class="table table-bordered">
<thead class="thead-dark">
<tr>
<th scope="col">Platform</th>
<th scope="col"><i class="fas fa-tags"></i>Versions</th>
<th scope="col"><i class="fas fa-plus"></i>Add Version</th>
</tr>
</thead>
<tbody>
<tr v-for="{ platform, versions } in data" :key="`${platform}-row`">
<td>{{ platform }}</td>
<td>
<div class="platform-version" v-for="(v, index) in versions" :key="index">
<span @click="removeVersion(versions, v)" style="cursor:pointer;">
<i class="fas fa-times" style="color: #bb0400"></i>
</span>
{{ v }}
</div>
</td>
<td>
<div class="input-group float-left">
<div class="input-group-prepend">
<span class="input-group-text">Version Identifier</span>
</div>
<label for="add-version-input" class="sr-only">Add Version</label>
<input type="text" id="add-version-input" class="form-control" v-model="inputs[platform]" />
<div class="input-group-append">
<button
type="button"
class="btn btn-primary"
@click="addVersion(platform)"
:disabled="!inputs[platform]"
>
<i class="fas fa-plus"></i>
</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<button v-if="!loading" type="button" class="btn btn-success" @click="save" :disabled="!changesMade">
<span class="glyphicon glyphicon-floppy-disk"></span>
Save Changes
</button>
@ -64,15 +52,11 @@
</div>
</template>
<script>
import _ from "lodash";
import axios from "axios";
import Vuetable from "vuetable-2";
import _ from 'lodash';
import axios from 'axios';
export default {
name: "PlatformVersionTable",
components: {
Vuetable
},
name: 'PlatformVersionTable',
props: {
platforms: {
type: Object,
@ -84,24 +68,7 @@ export default {
loading: false,
changesMade: false,
data: [],
inputs: {},
fields: [
{
name: "platform",
width: "40px",
formatter(value) {
return value.charAt(0).toUpperCase() + value.slice(1);
}
},
{
name: "versions-slot",
title: '<i class="fas fa-tags"></i> Versions'
},
{
name: "actions-slot",
title: '<i class="fas fa-plus"></i> Add Version'
}
]
inputs: {}
};
},
methods: {
@ -111,20 +78,17 @@ export default {
versions.push(this.inputs[platform]);
this.changesMade = true;
}
this.inputs[platform] = "";
this.inputs[platform] = '';
},
removeVersion(platform, version) {
const versions = this.data.find(o => o.platform === platform).versions;
this.$delete(versions, versions.indexOf(version));
removeVersion(versions, version) {
_.remove(versions, v => v === version);
this.changesMade = true;
},
save() {
const additions = {};
const removals = {};
for (const platform in this.platforms) {
const versions = this.data.find(
o => o.platform === platform.toLowerCase()
).versions;
const versions = this.data.find(o => o.platform === platform.toLowerCase()).versions;
additions[platform] = _.difference(versions, this.platforms[platform]);
removals[platform] = _.difference(this.platforms[platform], versions);
}
@ -141,7 +105,7 @@ export default {
}
this.loading = true;
axios
.post("/admin/versions/", {
.post('/admin/versions/', {
additions,
removals
})
@ -155,25 +119,33 @@ export default {
},
created() {
for (const platform in this.platforms) {
this.inputs[platform] = "";
this.inputs[platform] = '';
this.data.push({
platform: platform.toLowerCase(),
versions: [...this.platforms[platform]]
});
platform: platform.toLowerCase(),
versions: [...this.platforms[platform]]
}
);
}
}
};
</script>
<style lang="scss">
.platform-versions {
display: inherit;
}
<style lang="scss" scoped>
.table {
th svg {
margin-right: 4px;
}
.platform-version {
display: inline-block;
padding: 1px 4px 0 4px;
margin-right: 5px;
background-color: #cdcdcd;
border-radius: 2px;
tr th:first-child,
tr td:first-child {
width: 40px;
}
.platform-version {
display: inline-block;
padding: 1px 4px 0 4px;
margin-right: 5px;
background-color: #cdcdcd;
border-radius: 2px;
}
}
</style>

View File

@ -10,7 +10,7 @@
</template>
<script>
import ProjectList from "./components/ProjectList";
import ProjectList from './components/ProjectList';
export default {
components: {

View File

@ -5,12 +5,7 @@
<a
v-if="canUpload"
class="btn yellow"
:href="
routes.Versions.showCreator(
htmlDecode(projectOwner),
htmlDecode(projectSlug)
).absoluteURL()
"
:href="routes.Versions.showCreator(htmlDecode(projectOwner), htmlDecode(projectSlug)).absoluteURL()"
>Upload a New Version</a
>
</div>
@ -23,13 +18,7 @@
<div class="list-group">
<a
v-for="(version, index) in versions"
:href="
routes.Versions.show(
htmlDecode(projectOwner),
htmlDecode(projectSlug),
version.name
).absoluteURL()
"
:href="routes.Versions.show(htmlDecode(projectOwner), htmlDecode(projectSlug), version.name).absoluteURL()"
class="list-group-item list-group-item-action"
:class="[classForVisibility(version.visibility)]"
:key="index"
@ -38,31 +27,22 @@
<div class="row">
<div
class="col-6 col-sm-3"
:set="
(channel = version.tags.find(
filterTag => filterTag.name === 'Channel'
))
"
:set="(channel = version.tags.find(filterTag => filterTag.name === 'Channel'))"
>
<div class="row">
<div class="col-12">
<span class="text-bold">{{ version.name }}</span>
</div>
<div class="col-12">
<span
v-if="channel"
class="channel"
v-bind:style="{ background: channel.color.background }"
>{{ channel.data }}</span
>
<span v-if="channel" class="channel" v-bind:style="{ background: channel.color.background }">{{
channel.data
}}</span>
</div>
</div>
</div>
<div class="col-6 col-sm-3">
<Tag
v-for="tag in version.tags.filter(
filterTag => filterTag.name !== 'Channel'
)"
v-for="tag in version.tags.filter(filterTag => filterTag.name !== 'Channel')"
v-bind:key="tag.name + ':' + tag.data"
v-bind="tag"
></Tag>
@ -100,24 +80,18 @@
</div>
</a>
</div>
<Pagination
:current="current"
:total="total"
@prev="page--"
@next="page++"
@jumpTo="page = $event"
></Pagination>
<Pagination :current="current" :total="total" @prev="page--" @next="page++" @jumpTo="page = $event"></Pagination>
</div>
</div>
</template>
<script>
import fileSize from "filesize";
import fileSize from 'filesize';
import Tag from "./components/Tag";
import Pagination from "./components/Pagination";
import {Visibility} from "./enums";
import {apiV2Request} from "@/js/apiRequests";
import Tag from './components/Tag';
import Pagination from './components/Pagination';
import { Visibility } from './enums';
import { apiV2Request } from '@/js/apiRequests';
export default {
components: {
@ -139,11 +113,9 @@ export default {
},
created() {
this.update();
apiV2Request("permissions", "GET", { pluginId: window.PLUGIN_ID }).then(
response => {
this.canUpload = response.permissions.includes("create_version");
}
);
apiV2Request('permissions', 'GET', { pluginId: window.PLUGIN_ID }).then(response => {
this.canUpload = response.permissions.includes('create_version');
});
this.$watch(
() => this.page,
() => {
@ -154,7 +126,7 @@ export default {
},
methods: {
update() {
apiV2Request("projects/" + this.pluginId + "/versions", "GET", {
apiV2Request('projects/' + this.pluginId + '/versions', 'GET', {
limit: this.limit,
offset: this.offset
}).then(response => {
@ -167,17 +139,14 @@ export default {
return fileSize(size);
},
formatDate(date) {
return window.moment(date).format("MMM D, YYYY");
return window.moment(date).format('MMM D, YYYY');
},
classForVisibility(visibility) {
return Visibility.fromName(visibility).class;
},
htmlDecode(htmlEncoded) {
const parser = new DOMParser();
const dom = parser.parseFromString(
"<!doctype html><body>" + htmlEncoded,
"text/html"
);
const dom = parser.parseFromString('<!doctype html><body>' + htmlEncoded, 'text/html');
return dom.body.textContent;
}
},

View File

@ -1,21 +1,20 @@
import $ from "jquery";
import { parseJsonOrNull } from "./utils";
import $ from 'jquery';
import { parseJsonOrNull } from './utils';
$.ajaxSettings.traditional = true;
export class API {
static request(url, method = "GET", data = {}) {
static request(url, method = 'GET', data = {}) {
return this.getSession().then(session => {
return new Promise((resolve, reject) => {
const isFormData = data instanceof FormData;
const isBodyRequest =
method === "POST" || method === "PUT" || method === "PATCH";
const isBodyRequest = method === 'POST' || method === 'PUT' || method === 'PATCH';
$.ajax({
url: "/api/v2/" + url,
url: '/api/v2/' + url,
method: method,
dataType: "json",
contentType: isFormData ? false : "application/json",
dataType: 'json',
contentType: isFormData ? false : 'application/json',
data: isBodyRequest && !isFormData ? JSON.stringify(data) : data,
processData: !(isFormData || isBodyRequest),
headers: { Authorization: 'HangarApi session="' + session + '"' }
@ -26,8 +25,7 @@ export class API {
.fail(xhr => {
if (
xhr.responseJSON &&
(xhr.responseJSON.error === "Api session expired" ||
xhr.responseJSON.error === "Invalid session")
(xhr.responseJSON.error === 'Api session expired' || xhr.responseJSON.error === 'Invalid session')
) {
// This should never happen but just in case we catch it and invalidate the session to definitely get a new one
API.invalidateSession();
@ -53,23 +51,19 @@ export class API {
date.setTime(date.getTime() + 60000);
if (window.isLoggedIn) {
session = parseJsonOrNull(localStorage.getItem("api_session"));
if (
session === null ||
(!isNaN(new Date(session.expires).getTime()) &&
new Date(session.expires) < date)
) {
session = parseJsonOrNull(localStorage.getItem('api_session'));
if (session === null || (!isNaN(new Date(session.expires).getTime()) && new Date(session.expires) < date)) {
return $.ajax({
url: "/api/v2/authenticate/user",
method: "POST",
dataType: "json",
contentType: "application/json"
url: '/api/v2/authenticate/user',
method: 'POST',
dataType: 'json',
contentType: 'application/json'
})
.done(data => {
if (data.type !== "user") {
reject("Expected user session from user authentication");
if (data.type !== 'user') {
reject('Expected user session from user authentication');
} else {
localStorage.setItem("api_session", JSON.stringify(data));
localStorage.setItem('api_session', JSON.stringify(data));
resolve(data.session);
}
})
@ -80,26 +74,19 @@ export class API {
resolve(session.session);
}
} else {
session = parseJsonOrNull(localStorage.getItem("public_api_session"));
if (
session === null ||
(!isNaN(new Date(session.expires).getTime()) &&
new Date(session.expires) < date)
) {
session = parseJsonOrNull(localStorage.getItem('public_api_session'));
if (session === null || (!isNaN(new Date(session.expires).getTime()) && new Date(session.expires) < date)) {
$.ajax({
url: "/api/v2/authenticate",
method: "POST",
dataType: "json",
contentType: "application/json"
url: '/api/v2/authenticate',
method: 'POST',
dataType: 'json',
contentType: 'application/json'
})
.done(data => {
if (data.type !== "public") {
reject("Expected public session from public authentication");
if (data.type !== 'public') {
reject('Expected public session from public authentication');
} else {
localStorage.setItem(
"public_api_session",
JSON.stringify(data)
);
localStorage.setItem('public_api_session', JSON.stringify(data));
resolve(data.session);
}
})
@ -115,9 +102,9 @@ export class API {
static invalidateSession() {
if (window.isLoggedIn) {
localStorage.removeItem("api_session");
localStorage.removeItem('api_session');
} else {
localStorage.removeItem("public_api_session");
localStorage.removeItem('public_api_session');
}
}
}

View File

@ -20,12 +20,9 @@ export default {
if (this.href != null) {
return this.href;
} else if (this.name != null) {
return window.jsRoutes.controllers.Users.showProjects(
this.name,
null
).absoluteURL();
return window.jsRoutes.controllers.Users.showProjects(this.name, null).absoluteURL();
} else {
return "#";
return '#';
}
}
}

View File

@ -38,7 +38,7 @@
<script>
export default {
emits: ["prev", "next", "jump-to"],
emits: ['prev', 'next', 'jump-to'],
props: {
current: {
type: Number,
@ -60,17 +60,17 @@ export default {
methods: {
previous: function() {
if (this.hasPrevious) {
this.$emit("prev");
this.$emit('prev');
}
},
next: function() {
if (this.hasNext) {
this.$emit("next");
this.$emit('next');
}
},
jump: function(page) {
if (page > 0 <= this.total) {
this.$emit("jump-to", page);
this.$emit('jump-to', page);
}
}
}
@ -78,7 +78,7 @@ export default {
</script>
<style lang="scss">
@import "./../scss/variables";
@import './../scss/variables';
.pagination {
display: flex;

View File

@ -16,22 +16,13 @@
<div class="container-fluid">
<div class="row">
<div class="col-12 col-sm-1">
<Icon
:name="project.namespace.owner"
:src="project.icon_url"
extra-classes="user-avatar-sm"
></Icon>
<Icon :name="project.namespace.owner" :src="project.icon_url" extra-classes="user-avatar-sm"></Icon>
</div>
<div class="col-12 col-sm-11">
<div class="row">
<div class="col-sm-6">
<a
:href="
routes.Projects.show(
project.namespace.owner,
project.namespace.slug
).absoluteURL()
"
:href="routes.Projects.show(project.namespace.owner, project.namespace.slug).absoluteURL()"
class="title"
>
{{ project.name }}
@ -59,28 +50,17 @@
</span>
<span class="stat" title="Views"
><i class="fas fa-eye"></i>
{{ formatStats(project.stats.views) }}</span
><i class="fas fa-eye"></i> {{ formatStats(project.stats.views) }}</span
>
<span class="stat" title="Download"
><i class="fas fa-download"></i>
{{ formatStats(project.stats.downloads) }}</span
><i class="fas fa-download"></i> {{ formatStats(project.stats.downloads) }}</span
>
<span class="stat" title="Stars"
><i class="fas fa-star"></i>
{{ formatStats(project.stats.stars) }}</span
><i class="fas fa-star"></i> {{ formatStats(project.stats.stars) }}</span
>
<span
:title="categoryFromId(project.category).name"
class="stat"
>
<i
:class="
'fa-' + categoryFromId(project.category).icon
"
class="fas"
></i>
<span :title="categoryFromId(project.category).name" class="stat">
<i :class="'fa-' + categoryFromId(project.category).icon" class="fas"></i>
</span>
</div>
</div>
@ -89,18 +69,13 @@
<div class="col-sm-7 description-column">
<div class="description">{{ project.description }}</div>
</div>
<div
class="col-12 col-sm-5 tags-line"
v-if="project.promoted_versions"
>
<div class="col-12 col-sm-5 tags-line" v-if="project.promoted_versions">
<Tag
v-bind:name="tag.name"
v-bind:data="tag.versions.join(' | ')"
v-bind:color="tag.color"
v-bind:key="project.name + '-' + tag.name"
v-for="tag in tagsFromPromoted(
project.promoted_versions
)"
v-for="tag in tagsFromPromoted(project.promoted_versions)"
></Tag>
</div>
</div>
@ -126,13 +101,13 @@
</template>
<script>
import Tag from "./Tag";
import {clearFromEmpty, numberWithCommas} from "./../utils";
import {Category, Platform, Visibility} from "../enums";
import Pagination from "./Pagination";
import Icon from "./Icon";
import debounce from "lodash/debounce";
import {API} from "../api";
import Tag from './Tag';
import { clearFromEmpty, numberWithCommas } from './../utils';
import { Category, Platform, Visibility } from '../enums';
import Pagination from './Pagination';
import Icon from './Icon';
import debounce from 'lodash/debounce';
import { API } from '../api';
export default {
components: {
@ -140,7 +115,7 @@ export default {
Pagination,
Icon
},
emits: ["jump-to-page", "next-page", "prev-page", "update:projectCount"],
emits: ['jump-to-page', 'next-page', 'prev-page', 'update:projectCount'],
props: {
q: String,
categories: {
@ -184,17 +159,7 @@ export default {
this.update();
this.debouncedUpdateProps = debounce(this.update, 500);
this.$watch(
() =>
[
this.q,
this.categories,
this.tags,
this.owner,
this.sort,
this.relevance,
this.limit,
this.offset
].join(),
() => [this.q, this.categories, this.tags, this.owner, this.sort, this.relevance, this.limit, this.offset].join(),
() => {
this.debouncedUpdateProps();
}
@ -202,14 +167,12 @@ export default {
},
methods: {
update() {
API.request("projects", "GET", clearFromEmpty(this.$props)).then(
response => {
this.projects = response.result;
this.totalProjects = response.pagination.count;
this.loading = false;
this.$emit("update:projectCount", this.totalProjects);
}
);
API.request('projects', 'GET', clearFromEmpty(this.$props)).then(response => {
this.projects = response.result;
this.totalProjects = response.pagination.count;
this.loading = false;
this.$emit('update:projectCount', this.totalProjects);
});
},
categoryFromId(id) {
return Category.fromId(id);
@ -221,12 +184,7 @@ export default {
let tagsArray = [];
promotedVersions
.map(version => version.tags)
.forEach(
tags =>
(tagsArray = tags
.filter(tag => Platform.isPlatformTag(tag))
.concat(tagsArray))
);
.forEach(tags => (tagsArray = tags.filter(tag => Platform.isPlatformTag(tag)).concat(tagsArray)));
const reducedTags = [];
@ -258,7 +216,7 @@ export default {
</script>
<style lang="scss">
@import "./../scss/variables";
@import './../scss/variables';
.empty-project-list {
display: flex;

View File

@ -1,5 +1,5 @@
import {config, dom, library} from "@fortawesome/fontawesome-svg-core";
import "@fortawesome/fontawesome-svg-core/styles.css";
import { config, dom, library } from '@fortawesome/fontawesome-svg-core';
import '@fortawesome/fontawesome-svg-core/styles.css';
import {
faArrowLeft,
faArrowRight,
@ -70,7 +70,7 @@ import {
faUserTie,
faWindowClose,
faWrench
} from "@fortawesome/free-solid-svg-icons";
} from '@fortawesome/free-solid-svg-icons';
import {
faCheckCircle as farCheckCircle,
@ -83,7 +83,7 @@ import {
faSadTear,
faStar as farStar,
faThumbsUp as farThumbsUp
} from "@fortawesome/free-regular-svg-icons";
} from '@fortawesome/free-regular-svg-icons';
config.autoAddCss = false;

View File

@ -1,7 +1,7 @@
import {createApp} from "vue";
import $ from "jquery";
import Home from "../Home"
import { createApp } from 'vue';
import $ from 'jquery';
import Home from '../Home';
$.ajaxSetup(window.ajaxSettings);
createApp(Home).mount("#home")
createApp(Home).mount('#home');

View File

@ -1,4 +1,4 @@
import {createApp} from "vue";
import PlatformChoice from "@/PlatformChoice";
import { createApp } from 'vue';
import PlatformChoice from '@/PlatformChoice';
createApp(PlatformChoice).mount("#platform-choice");
createApp(PlatformChoice).mount('#platform-choice');

View File

@ -1,9 +1,9 @@
import {createApp} from "vue";
import axios from "axios";
import PlatformVersionTable from "@/PlatformVersionTable";
import { createApp } from 'vue';
import axios from 'axios';
import PlatformVersionTable from '@/PlatformVersionTable';
axios.defaults.headers.post[window.csrfInfo.headerName] = window.csrfInfo.token;
createApp(PlatformVersionTable, {
platforms: window.PLATFORMS
}).mount("#platform-version-table");
platforms: window.PLATFORMS
}).mount('#platform-version-table');

View File

@ -1,4 +1,4 @@
import {createApp} from "vue";
import UserProfile from "@/UserProfile";
import { createApp } from 'vue';
import UserProfile from '@/UserProfile';
createApp(UserProfile).mount("#user-profile");
createApp(UserProfile).mount('#user-profile');

View File

@ -1,4 +1,4 @@
import {createApp} from "vue";
import VersionList from "@/VersionList";
import { createApp } from 'vue';
import VersionList from '@/VersionList';
createApp(VersionList).mount("#version-list");
createApp(VersionList).mount('#version-list');

View File

@ -1,16 +1,16 @@
export class Category {
static get values() {
return [
{ id: "admin_tools", name: "Admin Tools", icon: "server" },
{ id: "chat", name: "Chat", icon: "comment" },
{ id: "dev_tools", name: "Developer Tools", icon: "wrench" },
{ id: "economy", name: "Economy", icon: "money-bill-alt" },
{ id: "gameplay", name: "Gameplay", icon: "puzzle-piece" },
{ id: "games", name: "Games", icon: "gamepad" },
{ id: "protection", name: "Protection", icon: "lock" },
{ id: "role_playing", name: "Role Playing", icon: "magic" },
{ id: "world_management", name: "World Management", icon: "globe" },
{ id: "misc", name: "Miscellaneous", icon: "asterisk" }
{ id: 'admin_tools', name: 'Admin Tools', icon: 'server' },
{ id: 'chat', name: 'Chat', icon: 'comment' },
{ id: 'dev_tools', name: 'Developer Tools', icon: 'wrench' },
{ id: 'economy', name: 'Economy', icon: 'money-bill-alt' },
{ id: 'gameplay', name: 'Gameplay', icon: 'puzzle-piece' },
{ id: 'games', name: 'Games', icon: 'gamepad' },
{ id: 'protection', name: 'Protection', icon: 'lock' },
{ id: 'role_playing', name: 'Role Playing', icon: 'magic' },
{ id: 'world_management', name: 'World Management', icon: 'globe' },
{ id: 'misc', name: 'Miscellaneous', icon: 'asterisk' }
];
}
@ -23,22 +23,22 @@ export class Platform {
static get values() {
return [
{
id: "Paper",
name: "Paper Plugins",
id: 'Paper',
name: 'Paper Plugins',
parent: true,
color: { background: "#F7Cf0D", foreground: "#333333" }
color: { background: '#F7Cf0D', foreground: '#333333' }
},
{
id: "Waterfall",
name: "Waterfall Plugins",
id: 'Waterfall',
name: 'Waterfall Plugins',
parent: true,
color: { background: "#F7Cf0D", foreground: "#333333" }
color: { background: '#F7Cf0D', foreground: '#333333' }
},
{
id: "Velocity",
name: "Velocity Plugins",
id: 'Velocity',
name: 'Velocity Plugins',
parent: true,
color: { background: "#039be5", foreground: "#333333" }
color: { background: '#039be5', foreground: '#333333' }
}
];
}
@ -53,24 +53,24 @@ export class Platform {
}
export const SortOptions = [
{ id: "stars", name: "Most Stars" },
{ id: "downloads", name: "Most Downloads" },
{ id: "views", name: "Most Views" },
{ id: "newest", name: "Newest" },
{ id: "updated", name: "Recently updated" },
{ id: "only_relevance", name: "Only relevance" },
{ id: "recent_views", name: "Recent Views" },
{ id: "recent_downloads", name: "Recent Downloads" }
{ id: 'stars', name: 'Most Stars' },
{ id: 'downloads', name: 'Most Downloads' },
{ id: 'views', name: 'Most Views' },
{ id: 'newest', name: 'Newest' },
{ id: 'updated', name: 'Recently updated' },
{ id: 'only_relevance', name: 'Only relevance' },
{ id: 'recent_views', name: 'Recent Views' },
{ id: 'recent_downloads', name: 'Recent Downloads' }
];
export class Visibility {
static get values() {
return [
{ name: "public", class: "" },
{ name: "new", class: "project-new" },
{ name: "needsChanges", class: "striped project-needsChanges" },
{ name: "needsApproval", class: "striped project-needsChanges" },
{ name: "softDelete", class: "striped project-hidden" }
{ name: 'public', class: '' },
{ name: 'new', class: 'project-new' },
{ name: 'needsChanges', class: 'striped project-needsChanges' },
{ name: 'needsApproval', class: 'striped project-needsChanges' },
{ name: 'softDelete', class: 'striped project-hidden' }
];
}

View File

@ -1,12 +1,12 @@
import $ from "jquery";
import "bootstrap/js/dist/modal";
import diff_match_patch from "diff-match-patch";
import $ from 'jquery';
import 'bootstrap/js/dist/modal';
import diff_match_patch from 'diff-match-patch';
//=====> DOCUMENT READY
$("body")
.on("click", ".data-diff", function() {
var idToDiff = $(this).attr("data-diff");
$('body')
.on('click', '.data-diff', function() {
var idToDiff = $(this).attr('data-diff');
var diff = new diff_match_patch();
var textDiff = diff.diff_main(
@ -15,28 +15,26 @@ $("body")
);
diff.diff_cleanupSemantic(textDiff);
$("#modal-view-body").html(
diff.diff_prettyHtml(textDiff).replace(/&para;/g, "")
);
$("#modal-view").modal("show");
$('#modal-view-body').html(diff.diff_prettyHtml(textDiff).replace(/&para;/g, ''));
$('#modal-view').modal('show');
})
.on("click", ".data-view-old", function() {
var idToShow = $(this).attr("data-view");
.on('click', '.data-view-old', function() {
var idToShow = $(this).attr('data-view');
$("#modal-view-body").html(
$('#modal-view-body').html(
'<textarea disabled style="width: 100%; height: 35vh">' +
$('textarea[data-oldstate="' + idToShow + '"]').val() +
"</textarea>"
'</textarea>'
);
$("#modal-view").modal("show");
$('#modal-view').modal('show');
})
.on("click", ".data-view-new", function() {
var idToShow = $(this).attr("data-view");
.on('click', '.data-view-new', function() {
var idToShow = $(this).attr('data-view');
$("#modal-view-body").html(
$('#modal-view-body').html(
'<textarea disabled style="width: 100%; height: 35vh">' +
$('textarea[data-newstate="' + idToShow + '"]').val() +
"</textarea>"
'</textarea>'
);
$("#modal-view").modal("show");
$('#modal-view').modal('show');
});

View File

@ -1,33 +1,33 @@
import $ from "jquery";
import {clearUnread, toggleSpinner} from "@/utils";
import $ from 'jquery';
import { clearUnread, toggleSpinner } from '@/utils';
//=====> DOCUMENT READY
$(function() {
$(".btn-resolve").click(function() {
var listItem = $(this).closest("li");
var flagId = listItem.data("flag-id");
$('.btn-resolve').click(function() {
var listItem = $(this).closest('li');
var flagId = listItem.data('flag-id');
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.removeClass("fa-check")
.find('[data-fa-i2svg]')
.removeClass('fa-check')
);
$.ajax({
url: "/admin/flags/" + flagId + "/resolve/true",
url: '/admin/flags/' + flagId + '/resolve/true',
complete: function() {
toggleSpinner(
$(".btn-resolve")
.find("[data-fa-i2svg]")
.addClass("fa-check")
$('.btn-resolve')
.find('[data-fa-i2svg]')
.addClass('fa-check')
);
},
success: function() {
$.when(listItem.fadeOut("slow")).done(function() {
$.when(listItem.fadeOut('slow')).done(function() {
listItem.remove();
if (!$(".list-flags-admin").find("li").length) {
if (!$('.list-flags-admin').find('li').length) {
resolveAll.fadeOut(); // eslint-disable-line no-undef
$(".no-flags").fadeIn();
$('.no-flags').fadeIn();
clearUnread($('a[href="/admin/flags"]'));
}
});

View File

@ -1,5 +1,5 @@
import $ from "jquery";
import { apiV2Request } from "@/js/apiRequests";
import $ from 'jquery';
import { apiV2Request } from '@/js/apiRequests';
//=====> EXTERNAL CONSTANTS
@ -13,14 +13,14 @@ var DELETE_KEY = null;
function deleteKey(name, row) {
return function() {
apiV2Request("keys?name=" + name, "DELETE").then(function() {
apiV2Request('keys?name=' + name, 'DELETE').then(function() {
row.remove();
});
};
}
function showError(error) {
var alert = $("#keyAlert");
var alert = $('#keyAlert');
alert.text(error);
alert.show();
}
@ -28,26 +28,26 @@ function showError(error) {
//=====> DOCUMENT READY
$(function() {
$(".api-key-row").each(function() {
$('.api-key-row').each(function() {
var row = $(this);
var name = row.find(".api-key-name").text();
row.find(".api-key-row-delete-button").click(deleteKey(name, row));
var name = row.find('.api-key-name').text();
row.find('.api-key-row-delete-button').click(deleteKey(name, row));
});
$("#button-create-new-key").click(function() {
$('#button-create-new-key').click(function() {
var checked = [];
$("#api-create-key-form")
.find("input[type=checkbox]")
$('#api-create-key-form')
.find('input[type=checkbox]')
.filter("input[id^='perm.']")
.filter(":checked")
.filter(':checked')
.each(function() {
checked.push(
$(this)
.attr("id")
.substr("perm.".length)
.attr('id')
.substr('perm.'.length)
);
});
var name = $("#keyName").val();
var name = $('#keyName').val();
if (checked.length === 0) {
showError(NO_PERMS_SET);
@ -62,7 +62,7 @@ $(function() {
showError(TOO_LONG_NAME);
return;
}
var nameTaken = $(".api-key-name:contains(" + name + ")").length;
var nameTaken = $('.api-key-name:contains(' + name + ')').length;
if (nameTaken !== 0) {
showError(NAMED_USED);
return;
@ -73,37 +73,37 @@ $(function() {
name: name
};
apiV2Request("keys", "POST", data).then(function(newKey) {
$("#keyAlert").hide();
var namedPerms = "";
apiV2Request('keys', 'POST', data).then(function(newKey) {
$('#keyAlert').hide();
var namedPerms = '';
for (let perm of checked) {
namedPerms += perm + ", ";
namedPerms += perm + ', ';
}
namedPerms.substr(0, namedPerms.length - 2);
var row = $("<tr>");
var row = $('<tr>');
var token = newKey.key;
row.append(
$("<th>")
.addClass("api-key-name")
$('<th>')
.addClass('api-key-name')
.text(name)
);
row.append($("<th>").text(token));
row.append($("<th>"));
row.append($("<th>").text(namedPerms));
row.append($('<th>').text(token));
row.append($('<th>'));
row.append($('<th>').text(namedPerms));
row.append(
$("<th>").append(
$("<button>")
.addClass("btn btn-danger api-key-row-delete-button")
$('<th>').append(
$('<button>')
.addClass('btn btn-danger api-key-row-delete-button')
.text(DELETE_KEY)
.click(deleteKey(name, row))
)
);
$("#api-key-rows:last-child").append(row);
$('#api-key-rows:last-child').append(row);
});
}
});

View File

@ -1,19 +1,18 @@
import $ from "jquery";
import $ from 'jquery';
//=====> HELPER FUNCTIONS
export function apiV2Request(url, method = "GET", data = {}) {
export function apiV2Request(url, method = 'GET', data = {}) {
return getApiSession().then(function(session) {
return new Promise(function(resolve, reject) {
const isFormData = data instanceof FormData;
const isBodyRequest =
method === "POST" || method === "PUT" || method === "PATCH";
const isBodyRequest = method === 'POST' || method === 'PUT' || method === 'PATCH';
$.ajax({
url: "/api/v2/" + url,
url: '/api/v2/' + url,
method: method,
dataType: "json",
contentType: isFormData ? false : "application/json",
dataType: 'json',
contentType: isFormData ? false : 'application/json',
data: isBodyRequest && !isFormData ? JSON.stringify(data) : data,
processData: !(isFormData || isBodyRequest),
headers: { Authorization: 'HangarApi session="' + session + '"' }
@ -24,8 +23,7 @@ export function apiV2Request(url, method = "GET", data = {}) {
.fail(function(xhr) {
if (
xhr.responseJSON &&
(xhr.responseJSON.error === "Api session expired" ||
xhr.responseJSON.error === "Invalid session")
(xhr.responseJSON.error === 'Api session expired' || xhr.responseJSON.error === 'Invalid session')
) {
// This should never happen but just in case we catch it and invalidate the session to definitely get a new one
invalidateApiSession();
@ -51,23 +49,19 @@ function getApiSession() {
date.setTime(date.getTime() + 60000);
if (window.isLoggedIn) {
session = parseOrNull(localStorage.getItem("api_session"));
if (
session === null ||
(!isNaN(new Date(session.expires).getTime()) &&
new Date(session.expires) < date)
) {
session = parseOrNull(localStorage.getItem('api_session'));
if (session === null || (!isNaN(new Date(session.expires).getTime()) && new Date(session.expires) < date)) {
return $.ajax({
url: "/api/v2/authenticate/user",
method: "POST",
dataType: "json",
contentType: "application/json"
url: '/api/v2/authenticate/user',
method: 'POST',
dataType: 'json',
contentType: 'application/json'
})
.done(function(data) {
if (data.type !== "user") {
reject("Expected user session from user authentication");
if (data.type !== 'user') {
reject('Expected user session from user authentication');
} else {
localStorage.setItem("api_session", JSON.stringify(data));
localStorage.setItem('api_session', JSON.stringify(data));
resolve(data.session);
}
})
@ -78,23 +72,19 @@ function getApiSession() {
resolve(session.session);
}
} else {
session = parseOrNull(localStorage.getItem("public_api_session"));
if (
session === null ||
(!isNaN(new Date(session.expires).getTime()) &&
new Date(session.expires) < date)
) {
session = parseOrNull(localStorage.getItem('public_api_session'));
if (session === null || (!isNaN(new Date(session.expires).getTime()) && new Date(session.expires) < date)) {
$.ajax({
url: "/api/v2/authenticate",
method: "POST",
dataType: "json",
contentType: "application/json"
url: '/api/v2/authenticate',
method: 'POST',
dataType: 'json',
contentType: 'application/json'
})
.done(function(data) {
if (data.type !== "public") {
reject("Expected public session from public authentication");
if (data.type !== 'public') {
reject('Expected public session from public authentication');
} else {
localStorage.setItem("public_api_session", JSON.stringify(data));
localStorage.setItem('public_api_session', JSON.stringify(data));
resolve(data.session);
}
})
@ -110,9 +100,9 @@ function getApiSession() {
function invalidateApiSession() {
if (window.isLoggedIn) {
localStorage.removeItem("api_session");
localStorage.removeItem('api_session');
} else {
localStorage.removeItem("public_api_session");
localStorage.removeItem('public_api_session');
}
}

View File

@ -1,4 +1,4 @@
import $ from "jquery";
import $ from 'jquery';
//=====> EXTERNAL CONSTANTS
@ -13,95 +13,63 @@ function rgbToHex(rgb) {
for (var i = 1; i <= 3; ++i) {
parts[i] = parseInt(parts[i]).toString(16);
if (parts[i].length === 1) {
parts[i] = "0" + parts[i];
parts[i] = '0' + parts[i];
}
}
return "#" + parts.join("");
return '#' + parts.join('');
}
function getModal() {
return $("#channel-settings");
return $('#channel-settings');
}
export function initChannelDelete(toggle, channelName, versionCount) {
$(toggle).off("click");
$(toggle).off('click');
$(toggle).click(function() {
var url =
"/" +
PROJECT_OWNER +
"/" +
PROJECT_SLUG +
"/channels/" +
channelName +
"/delete";
var modal = $("#modal-delete");
var url = '/' + PROJECT_OWNER + '/' + PROJECT_SLUG + '/channels/' + channelName + '/delete';
var modal = $('#modal-delete');
modal
.find(".modal-footer")
.find("form")
.attr("action", url);
modal.find(".version-count").text(versionCount);
.find('.modal-footer')
.find('form')
.attr('action', url);
modal.find('.version-count').text(versionCount);
});
$(".btn[data-channel-delete]").click(function(e) {
$('.btn[data-channel-delete]').click(function(e) {
e.preventDefault();
var id = $(this).data("channel-id");
$("#form-delete-" + id)[0].submit();
var id = $(this).data('channel-id');
$('#form-delete-' + id)[0].submit();
});
}
var onCustomSubmit = function(
toggle,
channelName,
channelHex,
title,
submit,
nonReviewed
) {
var onCustomSubmit = function(toggle, channelName, channelHex, title, submit, nonReviewed) {
// Called when a channel is being edited before project creation
var publishForm = $("#form-publish");
$("#channel-name")
var publishForm = $('#form-publish');
$('#channel-name')
.text(channelName)
.css("background-color", channelHex);
publishForm.find(".channel-input").val(channelName);
publishForm.find(".channel-color-input").val(channelHex);
getModal().modal("hide");
initChannelManager(
toggle,
channelName,
channelHex,
title,
null,
null,
submit,
nonReviewed
);
.css('background-color', channelHex);
publishForm.find('.channel-input').val(channelName);
publishForm.find('.channel-color-input').val(channelHex);
getModal().modal('hide');
initChannelManager(toggle, channelName, channelHex, title, null, null, submit, nonReviewed);
};
export function initChannelManager(
toggle,
channelName,
channelHex,
title,
call,
method,
submit,
nonReviewed
) {
$(toggle).off("click"); // Unbind previous click handlers
export function initChannelManager(toggle, channelName, channelHex, title, call, method, submit, nonReviewed) {
$(toggle).off('click'); // Unbind previous click handlers
$(toggle).click(function() {
var modal = getModal();
var preview = modal.find(".preview");
var preview = modal.find('.preview');
var submitInput = modal.find('input[type="submit"]');
// Update modal attributes
modal.find(".color-picker").css("color", channelHex);
modal.find(".modal-title").text(title);
modal.find(".non-reviewed").prop("checked", nonReviewed);
modal.find("input[type=submit]").attr("disabled", null);
preview.css("background-color", channelHex).text(channelName);
modal.find('.color-picker').css('color', channelHex);
modal.find('.modal-title').text(title);
modal.find('.non-reviewed').prop('checked', nonReviewed);
modal.find('input[type=submit]').attr('disabled', null);
preview.css('background-color', channelHex).text(channelName);
// Set input values
modal.find(".channel-color-input").val(channelHex);
modal.find(".channel-input").val(channelName);
modal.find('.channel-color-input').val(channelHex);
modal.find('.channel-input').val(channelName);
// Only show preview when there is input
if (channelName.length > 0) {
@ -113,20 +81,20 @@ export function initChannelManager(
submitInput.val(submit);
if (call === null && method === null) {
// Redirect form submit to client
submitInput.off("click"); // Unbind existing click handlers
submitInput.off('click'); // Unbind existing click handlers
submitInput.click(function(event) {
event.preventDefault();
submitInput.submit();
});
submitInput.off("submit"); // Unbind existing submit handlers
submitInput.off('submit'); // Unbind existing submit handlers
submitInput.submit(function(event) {
event.preventDefault();
var modal = getModal();
onCustomSubmit(
toggle,
modal.find(".channel-input").val(),
modal.find(".channel-color-input").val(),
modal.find('.channel-input').val(),
modal.find('.channel-color-input').val(),
title,
submit,
nonReviewed
@ -135,9 +103,9 @@ export function initChannelManager(
} else {
// Set form action
modal
.find("form")
.attr("action", call)
.attr("method", method);
.find('form')
.attr('action', call)
.attr('method', method);
}
});
}
@ -145,17 +113,17 @@ export function initChannelManager(
function initModal() {
var modal = getModal();
// Update the preview within the popover when the name is updated
modal.find(".channel-input").on("input", function() {
modal.find('.channel-input').on('input', function() {
var val = $(this).val();
var preview = getModal().find(".preview");
var submit = getModal().find("input[type=submit]");
var preview = getModal().find('.preview');
var submit = getModal().find('input[type=submit]');
var pattern = /^[a-zA-Z0-9]+$/;
if (val.length === 0 || !pattern.exec(val)) {
preview.hide();
submit.attr("disabled", true);
submit.attr('disabled', true);
} else {
preview.show().text(val);
submit.attr("disabled", null);
submit.attr('disabled', null);
}
});
initColorPicker();
@ -164,45 +132,45 @@ function initModal() {
function initColorPicker() {
var modal = getModal();
// Initialize popover to stay opened when hovered over
var colorPicker = modal.find(".color-picker");
var colorPicker = modal.find('.color-picker');
colorPicker
.popover({
html: true,
trigger: "manual",
container: colorPicker.attr("id"),
placement: "right",
trigger: 'manual',
container: colorPicker.attr('id'),
placement: 'right',
sanitize: false,
content: function() {
return getModal()
.find(".popover-color-picker")
.find('.popover-color-picker')
.html();
}
})
.on("mouseenter", function() {
.on('mouseenter', function() {
var _this = this;
$(this).popover("show");
$(this).popover('show');
$(this)
.siblings(".popover")
.on("mouseleave", function() {
$(_this).popover("hide");
.siblings('.popover')
.on('mouseleave', function() {
$(_this).popover('hide');
});
})
.on("mouseleave", function() {
.on('mouseleave', function() {
var _this = this;
setTimeout(function() {
if (!$(".popover:hover").length) {
$(_this).popover("hide");
if (!$('.popover:hover').length) {
$(_this).popover('hide');
}
}, 100);
});
// Update colors when new color is selected
$(document).on("click", ".channel-id", function() {
var color = $(this).css("color");
$(document).on('click', '.channel-id', function() {
var color = $(this).css('color');
var modal = getModal();
modal.find(".channel-color-input").val(rgbToHex(color));
modal.find(".color-picker").css("color", color);
modal.find(".preview").css("background-color", color);
modal.find('.channel-color-input').val(rgbToHex(color));
modal.find('.color-picker').css('color', color);
modal.find('.preview').css('background-color', color);
});
}

View File

@ -1,72 +1,62 @@
import $ from "jquery";
import "bootstrap/js/dist/modal";
import {toggleSpinner} from "@/utils";
import $ from 'jquery';
import 'bootstrap/js/dist/modal';
import { toggleSpinner } from '@/utils';
//=====> CONSTANTS
var ICON = "fa-eye";
var ICON = 'fa-eye';
//=====> DOCUMENT READY
$(function() {
$(".btn-visibility-change").click(function() {
var project = $(this).data("project");
var visibilityLevel = $(this).data("level");
var needsModal = $(this).data("modal");
var spinner = $('button[data-project="' + project + '"]').find(
"[data-fa-i2svg]"
);
$('.btn-visibility-change').click(function() {
var project = $(this).data('project');
var visibilityLevel = $(this).data('level');
var needsModal = $(this).data('modal');
var spinner = $('button[data-project="' + project + '"]').find('[data-fa-i2svg]');
toggleSpinner(spinner.toggleClass(ICON));
console.log(needsModal);
if (needsModal) {
$(".modal-title").html(
$('.modal-title').html(
$(this)
.text()
.trim() + ": comment"
.trim() + ': comment'
);
$("#modal-visibility-comment").modal("show");
$(".btn-visibility-comment-submit").data("project", project);
$(".btn-visibility-comment-submit").data("level", visibilityLevel);
$('#modal-visibility-comment').modal('show');
$('.btn-visibility-comment-submit').data('project', project);
$('.btn-visibility-comment-submit').data('level', visibilityLevel);
toggleSpinner(spinner.toggleClass(ICON));
} else {
sendVisibilityRequest(project, visibilityLevel, "", spinner);
sendVisibilityRequest(project, visibilityLevel, '', spinner);
}
});
$(".btn-visibility-comment-submit").click(function() {
var project = $(this).data("project");
var visibilityLevel = $(this).data("level");
var spinner = $(this).find("i");
$('.btn-visibility-comment-submit').click(function() {
var project = $(this).data('project');
var visibilityLevel = $(this).data('level');
var spinner = $(this).find('i');
toggleSpinner(spinner.toggleClass(ICON));
sendVisibilityRequest(
project,
visibilityLevel,
$(".textarea-visibility-comment").val(),
spinner
);
sendVisibilityRequest(project, visibilityLevel, $('.textarea-visibility-comment').val(), spinner);
});
// eslint-disable-next-line no-unused-vars
function sendVisibilityRequest(project, level, comment, spinner) {
var _url =
"/" +
project +
(level == -99 ? "/manage/hardDelete" : "/visible/" + level);
var _url = '/' + project + (level == -99 ? '/manage/hardDelete' : '/visible/' + level);
$.ajax({
type: "post",
type: 'post',
url: _url,
data: { comment: comment },
fail: function() {
toggleSpinner(
$('button[data-project="' + project + '"]')
.find("[data-fa-i2svg]")
.find('[data-fa-i2svg]')
.toggleClass(ICON)
);
},
success: function() {
toggleSpinner(
$('button[data-project="' + project + '"]')
.find("[data-fa-i2svg]")
.find('[data-fa-i2svg]')
.toggleClass(ICON)
);
location.reload();

View File

@ -1,5 +1,5 @@
import $ from "jquery";
import {sanitize, toggleSpinner} from "@/utils";
import $ from 'jquery';
import { sanitize, toggleSpinner } from '@/utils';
//=====> EXTERNAL CONSTANTS
@ -9,17 +9,17 @@ var PROJECT_SLUG = null;
//=====> DOCUMENT READY
$(function() {
var form = $("#form-icon");
var btn = form.find(".btn-upload");
var url = sanitize("/" + PROJECT_OWNER + "/" + PROJECT_SLUG + "/icon");
var preview = form.find(".user-avatar");
var form = $('#form-icon');
var btn = form.find('.btn-upload');
var url = sanitize('/' + PROJECT_OWNER + '/' + PROJECT_SLUG + '/icon');
var preview = form.find('.user-avatar');
var input = form.find('input[type="file"]');
function updateButton() {
btn.prop("disabled", input[0].files.length === 0);
btn.prop('disabled', input[0].files.length === 0);
}
input.on("change", function() {
input.on('change', function() {
updateButton();
});
@ -28,53 +28,51 @@ $(function() {
e.preventDefault();
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-upload")
.find('[data-fa-i2svg]')
.toggleClass('fa-upload')
);
$.ajax({
url: url,
type: "post",
type: 'post',
data: new FormData(form[0]),
cache: false,
contentType: false,
processData: false,
success: function() {
preview.attr("src", url + "/pending?" + performance.now());
preview.attr('src', url + '/pending?' + performance.now());
toggleSpinner(
$("#form-icon .btn-upload")
.find("[data-fa-i2svg]")
.toggleClass("fa-upload")
$('#form-icon .btn-upload')
.find('[data-fa-i2svg]')
.toggleClass('fa-upload')
);
$("#update-icon").val("true");
input.val("");
$('#update-icon').val('true');
input.val('');
updateButton();
$(".setting-icon").prepend(
'<div class="alert alert-info">Don\'t forget to save changes!</div>'
);
$('.setting-icon').prepend('<div class="alert alert-info">Don\'t forget to save changes!</div>');
}
});
});
// Reset button
var reset = form.find(".btn-reset");
var reset = form.find('.btn-reset');
reset.click(function(e) {
e.preventDefault();
$(this)
.text("")
.text('')
.append('<i class="fas fa-spinner fa-spin"></i>');
$.ajax({
url: url + "/reset",
type: "post",
url: url + '/reset',
type: 'post',
cache: false,
contentType: "application/json",
contentType: 'application/json',
complete: function() {
reset.empty().text("Reset");
reset.empty().text('Reset');
},
success: function() {
preview.attr("src", url);
input.val("");
preview.attr('src', url);
input.val('');
updateButton();
$(".setting-icon .alert").detach();
$('.setting-icon .alert').detach();
}
});
});

View File

@ -1,4 +1,4 @@
import $ from "jquery";
import $ from 'jquery';
//=====> EXTERNAL CONSTANTS
@ -13,28 +13,28 @@ var KEY_TYPE_DEPLOYMENT = 0;
function bindKeyGen(e) {
e.click(function() {
$(this)
.find(".spinner")
.find('.spinner')
.toggle();
var $this = $(this);
$.ajax({
url: "/api/v1/projects/" + pluginId + "/keys/new",
method: "post",
data: { "key-type": KEY_TYPE_DEPLOYMENT },
dataType: "json",
url: '/api/v1/projects/' + pluginId + '/keys/new',
method: 'post',
data: { 'key-type': KEY_TYPE_DEPLOYMENT },
dataType: 'json',
success: function(key) {
console.log(key);
$(".input-key").val(key.value);
$('.input-key').val(key.value);
$this
.removeClass("btn-key-gen btn-info")
.addClass("btn-key-revoke btn-danger")
.data("key-id", key.id)
.off("click");
$this.find(".text").text(keyRevokeText);
.removeClass('btn-key-gen btn-info')
.addClass('btn-key-revoke btn-danger')
.data('key-id', key.id)
.off('click');
$this.find('.text').text(keyRevokeText);
bindKeyRevoke($this);
},
complete: function() {
e.find(".spinner").toggle();
e.find('.spinner').toggle();
}
});
});
@ -43,24 +43,24 @@ function bindKeyGen(e) {
function bindKeyRevoke(e) {
e.click(function() {
$(this)
.find(".spinner")
.find('.spinner')
.toggle();
var $this = $(this);
$.ajax({
url: "/api/v1/projects/" + pluginId + "/keys/revoke",
method: "post",
data: { id: $(this).data("key-id") },
url: '/api/v1/projects/' + pluginId + '/keys/revoke',
method: 'post',
data: { id: $(this).data('key-id') },
success: function() {
$(".input-key").val("");
$('.input-key').val('');
$this
.removeClass("btn-key-revoke btn-danger")
.addClass("btn-key-gen btn-info")
.off("click");
$this.find(".text").text(keyGenText);
.removeClass('btn-key-revoke btn-danger')
.addClass('btn-key-gen btn-info')
.off('click');
$this.find('.text').text(keyGenText);
bindKeyGen($this);
},
complete: function() {
e.find(".spinner").toggle();
e.find('.spinner').toggle();
}
});
});
@ -69,6 +69,6 @@ function bindKeyRevoke(e) {
//=====> DOCUMENT READY
$(function() {
bindKeyGen($(".btn-key-gen"));
bindKeyRevoke($(".btn-key-revoke"));
bindKeyGen($('.btn-key-gen'));
bindKeyRevoke($('.btn-key-revoke'));
});

View File

@ -1,20 +1,20 @@
import $ from "jquery";
import ClipboardJS from "clipboard";
import hljs from "highlight.js";
import {initTooltips, scrollToAnchor, toggleSpinner} from "@/utils";
import "bootstrap/js/dist/tooltip";
import $ from 'jquery';
import ClipboardJS from 'clipboard';
import hljs from 'highlight.js';
import { initTooltips, scrollToAnchor, toggleSpinner } from '@/utils';
import 'bootstrap/js/dist/tooltip';
//=====> CONSTANTS
//=====> SETUP
const clipboardManager = new ClipboardJS(".copy-url");
clipboardManager.on("success", function() {
const element = $(".btn-download")
.tooltip({ title: "Copied!", placement: "bottom", trigger: "manual" })
.tooltip("show");
const clipboardManager = new ClipboardJS('.copy-url');
clipboardManager.on('success', function() {
const element = $('.btn-download')
.tooltip({ title: 'Copied!', placement: 'bottom', trigger: 'manual' })
.tooltip('show');
setTimeout(function() {
element.tooltip("dispose");
element.tooltip('dispose');
}, 2200);
});
@ -26,43 +26,36 @@ clipboardManager.on("success", function() {
hljs.initHighlightingOnLoad();
$(function() {
if (
window.navigator.userAgent.indexOf("MSIE ") > 0 ||
window.navigator.userAgent.indexOf("Trident/") > 0
) {
alert(
"Hangar doesn't support Internet Explorer! Please use a modern browser."
);
if (window.navigator.userAgent.indexOf('MSIE ') > 0 || window.navigator.userAgent.indexOf('Trident/') > 0) {
alert("Hangar doesn't support Internet Explorer! Please use a modern browser.");
}
$(".alert-fade").fadeIn("slow");
$('.alert-fade').fadeIn('slow');
initTooltips();
$(".btn-spinner").click(function() {
const iconClass = $(this).data("icon");
$('.btn-spinner').click(function() {
const iconClass = $(this).data('icon');
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.find('[data-fa-i2svg]')
.toggle(iconClass)
);
});
$(".link-go-back").click(function() {
$('.link-go-back').click(function() {
window.history.back();
});
});
// Fix page anchors which were broken by the fixed top navigation
$(window).on("load", function() {
$(window).on('load', function() {
return scrollToAnchor(window.location.hash);
});
$("a[href^='#']").click(function() {
window.location.replace(
window.location.toString().split("#")[0] + $(this).attr("href")
);
window.location.replace(window.location.toString().split('#')[0] + $(this).attr('href'));
return scrollToAnchor(this.hash);
});

View File

@ -1,78 +1,76 @@
import $ from "jquery";
import { initUserSearch } from "@/js/userSearch";
import $ from 'jquery';
import { initUserSearch } from '@/js/userSearch';
//=====> HELPER FUNCTIONS
function updateIndices() {
var memberList = $(".list-members");
memberList.find(".user-new").each(function() {
var memberList = $('.list-members');
memberList.find('.user-new').each(function() {
$(this)
.find("input")
.attr("name", "users");
.find('input')
.attr('name', 'users');
$(this)
.find("select")
.attr("name", "roles");
.find('select')
.attr('name', 'roles');
});
memberList.find(".user-changed").each(function() {
memberList.find('.user-changed').each(function() {
$(this)
.find("input")
.attr("name", "userUps");
.find('input')
.attr('name', 'userUps');
$(this)
.find("select")
.attr("name", "roleUps");
.find('select')
.attr('name', 'roleUps');
});
}
function getItemContainer(element) {
return element.closest(".list-group-item");
return element.closest('.list-group-item');
}
function initMember(memberRow) {
// Replace title with select on click
memberRow
.find(".fa-edit")
.find('.fa-edit')
.parent()
.click(function(event) {
event.preventDefault();
var currentRole = getItemContainer($(this))
.find("span.minor.float-right")
.find('span.minor.float-right')
.text()
.replace(/(\r\n|\n|\r|\s)/gm, "");
.replace(/(\r\n|\n|\r|\s)/gm, '');
var saveBtn = $(".btn-members-save");
if (!saveBtn.is(":visible")) saveBtn.fadeIn("fast");
var saveBtn = $('.btn-members-save');
if (!saveBtn.is(':visible')) saveBtn.fadeIn('fast');
// Mark user as changed
var container = getItemContainer($(this)).addClass("user-changed");
var input = $("#select-role")
var container = getItemContainer($(this)).addClass('user-changed');
var input = $('#select-role')
.clone()
.removeAttr("id")
.attr("form", "save");
.removeAttr('id')
.attr('form', 'save');
input.find("option").each(function(i, el) {
input.find('option').each(function(i, el) {
if (
$(el)
.val()
.endsWith(currentRole)
) {
$(el).attr("selected", "");
$(el).attr('selected', '');
}
});
// Add input
container.find("span").replaceWith(input.show());
container.find('span').replaceWith(input.show());
var username = container
.find(".username")
.find('.username')
.text()
.trim();
container.append(
'<input type="hidden" form="save" value="' + username + '" />'
);
container.append('<input type="hidden" form="save" value="' + username + '" />');
// Remove edit button and update input names
$(this)
.find(".fa-edit")
.find('.fa-edit')
.parent()
.remove();
updateIndices();
@ -80,15 +78,15 @@ function initMember(memberRow) {
// Set form input on modal when delete is clicked
memberRow
.find(".fa-trash")
.find('.fa-trash')
.parent()
.click(function(event) {
event.preventDefault();
$("#modal-user-delete")
.find("input[name=username]")
$('#modal-user-delete')
.find('input[name=username]')
.val(
getItemContainer($(this))
.find(".username")
.find('.username')
.text()
.trim()
);
@ -98,11 +96,11 @@ function initMember(memberRow) {
//=====> DOCUMENT READY
$(function() {
initMember($(".list-members").find(".list-group-item"));
initMember($('.list-members').find('.list-group-item'));
initUserSearch(function(result) {
var alert = $(".member-error");
var message = alert.find("span");
var alert = $('.member-error');
var message = alert.find('span');
if (!result.isSuccess) {
message.text('Could not find user with name "' + result.username + '".');
alert.fadeIn();
@ -110,45 +108,45 @@ $(function() {
}
alert.fadeOut();
var saveBtn = $(".btn-members-save");
if (!saveBtn.is(":visible")) saveBtn.fadeIn("fast");
var saveBtn = $('.btn-members-save');
if (!saveBtn.is(':visible')) saveBtn.fadeIn('fast');
// hangar: user.name was username everywhere
var user = result.user;
// Check if user is already defined
if ($(".list-members").find('a[href="/' + user.username + '"]').length) {
if ($('.list-members').find('a[href="/' + user.username + '"]').length) {
return;
}
// Build result row
var resultRow = $("#row-user")
var resultRow = $('#row-user')
.clone()
.removeAttr("id")
.addClass("user-new");
.removeAttr('id')
.addClass('user-new');
resultRow
.find(".username")
.attr("href", "/" + user.username)
.find('.username')
.attr('href', '/' + user.username)
.text(user.username);
resultRow
.find("input")
.attr("form", "save")
.find('input')
.attr('form', 'save')
.val(user.id);
resultRow.find("select").attr("form", "save");
resultRow.find("svg").click(function() {
resultRow.find('select').attr('form', 'save');
resultRow.find('svg').click(function() {
$(this)
.parent()
.remove();
updateIndices();
});
var avatarImg = resultRow.find(".user-avatar");
if (Object.prototype.hasOwnProperty.call(user, "avatarUrl")) {
var avatarUrl = user["avatarUrl"];
avatarImg.css("background-image", "url(" + avatarUrl + ")");
var avatarImg = resultRow.find('.user-avatar');
if (Object.prototype.hasOwnProperty.call(user, 'avatarUrl')) {
var avatarUrl = user['avatarUrl'];
avatarImg.css('background-image', 'url(' + avatarUrl + ')');
} else avatarImg.remove();
// Add result to list
$(".user-search")
$('.user-search')
.parent()
.before(resultRow);
updateIndices();

View File

@ -1,5 +1,5 @@
import $ from "jquery";
import { initUserSearch } from "@/js/userSearch";
import $ from 'jquery';
import { initUserSearch } from '@/js/userSearch';
//=====> HELPER FUNCTIONS
@ -7,15 +7,15 @@ function updateIndices() {
// Set the input fields to their proper indices so the server can read
// them as a list.
// hangar remove index from form attrs, spring will auto put them in lists
var rows = $(".table-members").find("tr");
var rows = $('.table-members').find('tr');
rows.each(function(i) {
if (i === 0 || i === rows.length - 1) return; // Skip owner and search rows
$(this)
.find("input")
.attr("name", "users");
.find('input')
.attr('name', 'users');
$(this)
.find("select")
.attr("name", "roles");
.find('select')
.attr('name', 'roles');
});
}
@ -23,9 +23,9 @@ function updateIndices() {
$(function() {
initUserSearch(function(result) {
var alert = $(".alert-danger");
var alert = $('.alert-danger');
if (!result.isSuccess) {
$(".error-username").text(result.username);
$('.error-username').text(result.username);
alert.fadeIn();
return;
}
@ -35,46 +35,46 @@ $(function() {
// Check if user is already defined
if (
$('input[value="' + user.id + '"]').length ||
$(".table-members")
.first("tr")
.find("strong")
$('.table-members')
.first('tr')
.find('strong')
.text() === user.username
) {
return;
}
// Build the result row from the template
var newRow = $("#result-row")
var newRow = $('#result-row')
.clone()
.removeAttr("id");
.removeAttr('id');
newRow
.find("input")
.attr("form", "form-continue")
.find('input')
.attr('form', 'form-continue')
.val(user.id);
newRow.find("select").attr("form", "form-continue");
newRow.find('select').attr('form', 'form-continue');
newRow
.find(".username")
.attr("href", "/" + user.username)
.find('.username')
.attr('href', '/' + user.username)
.text(user.username);
var avatarImg = newRow.find(".user-avatar");
if (Object.prototype.hasOwnProperty.call(user, "avatarUrl")) {
avatarImg.css("background-image", "url(" + user["avatarUrl"] + ")");
var avatarImg = newRow.find('.user-avatar');
if (Object.prototype.hasOwnProperty.call(user, 'avatarUrl')) {
avatarImg.css('background-image', 'url(' + user['avatarUrl'] + ')');
} else {
avatarImg.remove();
}
// Bind cancel button
newRow.find(".user-cancel").click(function() {
newRow.find('.user-cancel').click(function() {
$(this)
.closest("tr")
.closest('tr')
.remove();
updateIndices();
});
// Insert the new row before the search row
$(".user-search")
.closest("tr")
$('.user-search')
.closest('tr')
.before(newRow);
updateIndices();
});

View File

@ -1,34 +1,31 @@
import $ from "jquery";
import {toggleSpinner} from "@/utils";
import $ from 'jquery';
import { toggleSpinner } from '@/utils';
//=====> HELPER FUNCTIONS
function markRead(notification) {
var btn = notification.find(".btn-mark-read");
var btn = notification.find('.btn-mark-read');
toggleSpinner(btn);
$.ajax({
type: "post",
url: "/notifications/read/" + notification.data("id"),
type: 'post',
url: '/notifications/read/' + notification.data('id'),
complete: function() {
toggleSpinner(
notification.find(".btn-mark-read").addClass("btn-mark-read fa-check")
);
toggleSpinner(notification.find('.btn-mark-read').addClass('btn-mark-read fa-check'));
},
success: function() {
notification.fadeOut("slow", function() {
notification.fadeOut('slow', function() {
notification.remove();
if ($(".notification").length === 0)
$(".no-notifications").fadeIn("slow");
if ($('.notification').length === 0) $('.no-notifications').fadeIn('slow');
});
}
});
}
function replyToInvite(invite, reply, success, error) {
var url = invite.data("type") === "project" ? "" : "organizations";
url += "/invite/" + invite.data("id") + "/" + reply;
var url = invite.data('type') === 'project' ? '' : 'organizations';
url += '/invite/' + invite.data('id') + '/' + reply;
$.ajax({
type: "post",
type: 'post',
url: url,
success: success,
error: error
@ -36,72 +33,70 @@ function replyToInvite(invite, reply, success, error) {
}
function setupNotificationButtons() {
$(".btn-mark-all-read").click(function() {
$(".btn-mark-read").click();
$('.btn-mark-all-read').click(function() {
$('.btn-mark-read').click();
});
$(".btn-mark-read").click(function() {
markRead($(this).closest(".notification"));
$('.btn-mark-read').click(function() {
markRead($(this).closest('.notification'));
});
$(".notification").click(function(e) {
$('.notification').click(function(e) {
if (e.target !== this) return;
var action = $(this).data("action");
var action = $(this).data('action');
$(this)
.find(".btn-mark-read")
.find('.btn-mark-read')
.click();
if (action !== "none") window.location.href = action;
if (action !== 'none') window.location.href = action;
});
}
function setupFilters() {
$(".select-notifications").on("change", function() {
window.location = "/notifications?notificationFilter=" + $(this).val();
$('.select-notifications').on('change', function() {
window.location = '/notifications?notificationFilter=' + $(this).val();
});
$(".select-invites").on("change", function() {
window.location = "/notifications?inviteFilter=" + $(this).val();
$('.select-invites').on('change', function() {
window.location = '/notifications?inviteFilter=' + $(this).val();
});
}
function setupInvites() {
function fadeOutLoading(loading, after) {
loading.fadeOut("fast", after);
loading.fadeOut('fast', after);
}
$(".btn-invite").click(function() {
$('.btn-invite').click(function() {
var btn = $(this);
var invite = btn.closest(".invite-content");
var choice = invite.find(".invite-choice");
var invite = btn.closest('.invite-content');
var choice = invite.find('.invite-choice');
choice.animate(
{
right: "+=200"
right: '+=200'
},
200,
function() {
choice.hide();
var loading = invite.find(".invite-loading").fadeIn("fast");
var accepted = btn.hasClass("btn-accept");
var result = invite.find(
accepted ? ".invite-accepted" : ".invite-declined"
);
var loading = invite.find('.invite-loading').fadeIn('fast');
var accepted = btn.hasClass('btn-accept');
var result = invite.find(accepted ? '.invite-accepted' : '.invite-declined');
replyToInvite(
invite,
accepted ? "accept" : "decline",
accepted ? 'accept' : 'decline',
function() {
fadeOutLoading(loading, function() {
result.fadeIn("slow");
invite.find(".invite-dismiss").fadeIn("slow");
result.fadeIn('slow');
invite.find('.invite-dismiss').fadeIn('slow');
});
},
function() {
fadeOutLoading(loading, function() {
choice.show().animate(
{
right: "5%"
right: '5%'
},
200
);
@ -112,39 +107,39 @@ function setupInvites() {
);
});
$(".btn-undo").click(function() {
var invite = $(this).closest(".invite-content");
var accepted = invite.find(".invite-accepted");
invite.find(".invite-dismiss").fadeOut("slow");
accepted.fadeOut("slow", function() {
var loading = invite.find(".invite-loading").fadeIn("fast");
$('.btn-undo').click(function() {
var invite = $(this).closest('.invite-content');
var accepted = invite.find('.invite-accepted');
invite.find('.invite-dismiss').fadeOut('slow');
accepted.fadeOut('slow', function() {
var loading = invite.find('.invite-loading').fadeIn('fast');
replyToInvite(
invite,
"unaccept",
'unaccept',
function() {
fadeOutLoading(loading, function() {
var choice = invite.find(".invite-choice");
var choice = invite.find('.invite-choice');
choice
.css("right", "+=200")
.css('right', '+=200')
.show()
.animate(
{
right: "5%"
right: '5%'
},
200
);
});
},
function() {
accepted.fadeIn("slow");
accepted.fadeIn('slow');
}
);
});
});
$(".dismiss").click(function() {
var invite = $(this).closest(".invite-content");
invite.fadeOut("slow", function() {
$('.dismiss').click(function() {
var invite = $(this).closest('.invite-content');
invite.fadeOut('slow', function() {
invite.remove();
});
});
@ -153,8 +148,8 @@ function setupInvites() {
//=====> DOCUMENT READY
$(function() {
var invites = $(".invite-content");
invites.css("height", invites.width());
var invites = $('.invite-content');
invites.css('height', invites.width());
setupNotificationButtons();
setupFilters();
setupInvites();

View File

@ -1,4 +1,4 @@
import $ from "jquery";
import $ from 'jquery';
//=====> CONSTANTS
@ -8,9 +8,9 @@ var MIN_NAME_LENGTH = 3;
function resetStatus(status) {
return status
.removeClass("fa-spinner fa-spin")
.removeClass("fa-check-circle")
.removeClass("fa-times-circle");
.removeClass('fa-spinner fa-spin')
.removeClass('fa-check-circle')
.removeClass('fa-times-circle');
}
//=====> DOCUMENT READY
@ -18,27 +18,26 @@ function resetStatus(status) {
$(function() {
var events = 0;
$(".input-name").on("input", function() {
$('.input-name').on('input', function() {
var val = $(this).val();
var status = $(".status-org-name");
var continueBtn = $(".continue-btn").prop("disabled", true);
var status = $('.status-org-name');
var continueBtn = $('.continue-btn').prop('disabled', true);
if (val.length < MIN_NAME_LENGTH) status.hide();
else {
resetStatus(status).addClass("fa-spinner fa-spin");
resetStatus(status).addClass('fa-spinner fa-spin');
status.show();
var event = ++events;
$.ajax({
url: "/" + val,
url: '/' + val,
statusCode: {
404: function() {
if (event === events) {
resetStatus($(".status-org-name")).addClass("fa-check-circle");
continueBtn.prop("disabled", false);
resetStatus($('.status-org-name')).addClass('fa-check-circle');
continueBtn.prop('disabled', false);
}
},
200: function() {
if (event === events)
resetStatus($(".status-org-name")).addClass("fa-times-circle");
if (event === events) resetStatus($('.status-org-name')).addClass('fa-times-circle');
}
}
});

View File

@ -1,11 +1,11 @@
import $ from "jquery";
import $ from 'jquery';
//=====> HELPER FUNCTIONS
function replyToInvite(id, behalf, reply, success, error) {
var url = "/invite/" + id + "/" + reply + "/" + behalf;
var url = '/invite/' + id + '/' + reply + '/' + behalf;
$.ajax({
type: "post",
type: 'post',
url: url,
success: success,
error: error
@ -13,29 +13,29 @@ function replyToInvite(id, behalf, reply, success, error) {
}
function setupInvites() {
$(".btn-invite").click(function() {
$('.btn-invite').click(function() {
var btn = $(this);
var id = btn.attr("data-invite-id");
var behalf = btn.attr("data-invite-behalf");
var accepted = btn.attr("data-invite-accepted");
btn.attr("disabled", true);
var id = btn.attr('data-invite-id');
var behalf = btn.attr('data-invite-behalf');
var accepted = btn.attr('data-invite-accepted');
btn.attr('disabled', true);
replyToInvite(
id,
behalf,
accepted,
function() {
if (accepted == "decline") {
if (accepted == 'decline') {
btn
.parent()
.parent()
.hide();
} else {
btn.parent().html("<span>Joined</span>");
btn.parent().html('<span>Joined</span>');
}
},
function() {
btn.html("Failed to update");
btn.html('Failed to update');
}
);
});

View File

@ -1,4 +1,4 @@
import $ from "jquery";
import $ from 'jquery';
//=====> EXTERNAL CONSTANTS
@ -9,38 +9,32 @@ var namespace = null;
function bindExpand(e) {
e.click(function() {
var pageId = $(this).data("page-id");
var listItem = $(this).closest(".list-group-item");
var pageId = $(this).data('page-id');
var listItem = $(this).closest('.list-group-item');
var $this = $(this);
$.ajax({
method: "get",
url: "/api/v1/projects/" + pluginId + "/pages?parentId=" + pageId,
dataType: "json",
method: 'get',
url: '/api/v1/projects/' + pluginId + '/pages?parentId=' + pageId,
dataType: 'json',
success: function(childPages) {
console.log(childPages);
var div = $(
'<div class="page-children" data-page-id="' + pageId + '"></div>'
);
var div = $('<div class="page-children" data-page-id="' + pageId + '"></div>');
listItem.after(div);
for (var i = 0; i < childPages.length; i++) {
var page = childPages[i];
var childPage = $(
'<li class="list-group-item page-item-child">' +
'<a href=""></a>' +
"</li>"
);
var link = childPage.find("a");
link.attr("href", namespace + "/pages/" + page.fullSlug);
var childPage = $('<li class="list-group-item page-item-child">' + '<a href=""></a>' + '</li>');
var link = childPage.find('a');
link.attr('href', namespace + '/pages/' + page.fullSlug);
link.text(page.name); // this will sanitize the input
div.append(childPage);
}
$this
.removeClass("page-expand")
.addClass("page-collapse")
.find("[data-fa-i2svg]")
.removeClass("fa-plus-square")
.addClass("fa-minus-square");
$this.off("click");
.removeClass('page-expand')
.addClass('page-collapse')
.find('[data-fa-i2svg]')
.removeClass('fa-plus-square')
.addClass('fa-minus-square');
$this.off('click');
bindCollapse($this);
}
});
@ -49,15 +43,15 @@ function bindExpand(e) {
function bindCollapse(e) {
e.click(function() {
var pageId = $(this).data("page-id");
var pageId = $(this).data('page-id');
$('.page-children[data-page-id="' + pageId + '"]').remove();
$(this)
.removeClass("page-collapse")
.addClass("page-expand")
.find("[data-fa-i2svg]")
.removeClass("fa-minus-square")
.addClass("fa-plus-square");
$(this).off("click");
.removeClass('page-collapse')
.addClass('page-expand')
.find('[data-fa-i2svg]')
.removeClass('fa-minus-square')
.addClass('fa-plus-square');
$(this).off('click');
bindExpand($(this));
});
}
@ -65,6 +59,6 @@ function bindCollapse(e) {
//=====> DOCUMENT READY
$(function() {
bindExpand($(".page-expand"));
bindCollapse($(".page-collapse"));
bindExpand($('.page-expand'));
bindCollapse($('.page-collapse'));
});

View File

@ -1,60 +1,45 @@
/* global projectOwner, projectSlug */
import $ from "jquery";
import {go, KEY_ENTER, slugify} from "@/utils";
import $ from 'jquery';
import { go, KEY_ENTER, slugify } from '@/utils';
//=====> DOCUMENT READY
$(function() {
var modal = $("#new-page");
modal.on("shown.bs.modal", function() {
var modal = $('#new-page');
modal.on('shown.bs.modal', function() {
$(this)
.find("input")
.find('input')
.focus();
});
modal.find("input").keydown(function(event) {
modal.find('input').keydown(function(event) {
if (event.keyCode === KEY_ENTER) {
event.preventDefault();
$("#continue-page").click();
$('#continue-page').click();
}
});
$("#continue-page").click(function() {
var pageName = $("#page-name")
$('#continue-page').click(function() {
var pageName = $('#page-name')
.val()
.trim();
var url =
"/" +
projectOwner +
"/" +
projectSlug +
"/pages/" +
slugify(pageName) +
"/edit";
var parent = $(".select-parent").find(":selected");
var url = '/' + projectOwner + '/' + projectSlug + '/pages/' + slugify(pageName) + '/edit';
var parent = $('.select-parent').find(':selected');
var parentId = null;
if (parent.length) {
parentId = parent.val() === "-1" ? null : parent.val();
parentId = parent.val() === '-1' ? null : parent.val();
if (parentId !== null)
url =
"/" +
projectOwner +
"/" +
projectSlug +
"/pages/" +
parent.data("slug") +
"/" +
slugify(pageName) +
"/edit";
'/' + projectOwner + '/' + projectSlug + '/pages/' + parent.data('slug') + '/' + slugify(pageName) + '/edit';
}
$.ajax({
method: "post",
method: 'post',
url: url,
data: {
"parent-id": parentId,
content: "# " + pageName + "\n",
'parent-id': parentId,
content: '# ' + pageName + '\n',
name: pageName
},
success: function() {
@ -62,8 +47,8 @@ $(function() {
},
error: function(err) {
console.log(err);
console.log("error");
$("#new-page-label-error")
console.log('error');
$('#new-page-label-error')
.show()
.delay(2000)
.fadeOut();

View File

@ -1,6 +1,6 @@
import $ from "jquery";
import "bootstrap/js/dist/tooltip";
import filesize from "filesize";
import $ from 'jquery';
import 'bootstrap/js/dist/tooltip';
import filesize from 'filesize';
//=====> CONSTANTS
@ -9,39 +9,37 @@ var MAX_FILE_SIZE = 20971520;
//=====> HELPER FUNCTIONS
function getAlert() {
return $(".alert-file");
return $('.alert-file');
}
function clearIcon(e) {
return e
.removeClass("fa-spinner")
.removeClass("fa-spin")
.addClass("fa-pencil-alt")
.addClass("fa-upload");
.removeClass('fa-spinner')
.removeClass('fa-spin')
.addClass('fa-pencil-alt')
.addClass('fa-upload');
}
function failure(message) {
var alert = getAlert();
var bs = alert.find(".alert");
bs.removeClass("alert-info").addClass("alert-danger");
var noticeIcon = bs.find("[data-fa-i2svg]");
var bs = alert.find('.alert');
bs.removeClass('alert-info').addClass('alert-danger');
var noticeIcon = bs.find('[data-fa-i2svg]');
noticeIcon.attr("data-prefix", "fas");
noticeIcon
.toggleClass("fa-file-archive")
.toggleClass("fa-exclamation-circle");
noticeIcon.attr('data-prefix', 'fas');
noticeIcon.toggleClass('fa-file-archive').toggleClass('fa-exclamation-circle');
bs.tooltip({
placement: "left",
placement: 'left',
title: message
});
// flash
function flash(amount) {
if (amount > 0) {
bs.find("[data-fa-i2svg]").fadeOut("fast", function() {
bs.find("[data-fa-i2svg]").fadeIn("fast", flash(amount - 1));
bs.find('[data-fa-i2svg]').fadeOut('fast', function() {
bs.find('[data-fa-i2svg]').fadeIn('fast', flash(amount - 1));
});
}
}
@ -52,35 +50,35 @@ function failure(message) {
function failurePlugin(message) {
failure(message);
var alert = getAlert();
var control = alert.find(".file-upload");
var control = alert.find('.file-upload');
control
.find("button")
.removeClass("btn-success")
.addClass("btn-danger")
.prop("disabled", true);
clearIcon(control.find("[data-fa-i2svg]")).addClass("fa-times");
.find('button')
.removeClass('btn-success')
.addClass('btn-danger')
.prop('disabled', true);
clearIcon(control.find('[data-fa-i2svg]')).addClass('fa-times');
}
function reset() {
var alert = getAlert();
alert.hide();
var control = alert.find(".file-upload");
var control = alert.find('.file-upload');
control
.find("button")
.removeClass("btn-danger")
.addClass("btn-success")
.prop("disabled", false);
clearIcon(control.find("[data-fa-i2svg]")).addClass("fa-pencil-alt");
.find('button')
.removeClass('btn-danger')
.addClass('btn-success')
.prop('disabled', false);
clearIcon(control.find('[data-fa-i2svg]')).addClass('fa-pencil-alt');
var bs = alert.find(".alert");
bs.removeClass("alert-danger").addClass("alert-info");
bs.find("[data-fa-i2svg]").attr("data-prefix", "far");
if (bs.find("[data-fa-i2svg]").data("ui-tooltip")) {
bs.find("[data-fa-i2svg]")
.removeClass("fa-exclamation-circle")
.addClass("fa-file-archive")
.tooltip("dispose");
var bs = alert.find('.alert');
bs.removeClass('alert-danger').addClass('alert-info');
bs.find('[data-fa-i2svg]').attr('data-prefix', 'far');
if (bs.find('[data-fa-i2svg]').data('ui-tooltip')) {
bs.find('[data-fa-i2svg]')
.removeClass('fa-exclamation-circle')
.addClass('fa-file-archive')
.tooltip('dispose');
}
return alert;
}
@ -88,17 +86,17 @@ function reset() {
//=====> DOCUMENT READY
$(function() {
var platformTags = $("#upload-platform-tags");
var platformTags = $('#upload-platform-tags');
if (platformTags.length >= 1 && platformTags.children().length === 0) {
platformTags.html(
'<div class="tags"><span style="color: #FFF; background-color: #8b0000; border-color: #8b0000" class="tag">No Platform Detected</span></div>'
);
}
$("#pluginFile").on("change", function() {
$('#pluginFile').on('change', function() {
var alert = reset();
if (this.files.length === 0) {
$("#form-upload")[0].reset();
$('#form-upload')[0].reset();
return;
}
var fileName = $(this)
@ -112,40 +110,34 @@ $(function() {
var success = true;
if (fileSize > MAX_FILE_SIZE) {
failurePlugin(
"That file is too big. Plugins may be no larger than " +
filesize(MAX_FILE_SIZE) +
"."
);
failurePlugin('That file is too big. Plugins may be no larger than ' + filesize(MAX_FILE_SIZE) + '.');
success = false;
} else if (!fileName.endsWith(".zip") && !fileName.endsWith(".jar")) {
failurePlugin("Only JAR and ZIP files are accepted.");
} else if (!fileName.endsWith('.zip') && !fileName.endsWith('.jar')) {
failurePlugin('Only JAR and ZIP files are accepted.');
success = false;
}
fileName = fileName.substr(fileName.lastIndexOf("\\") + 1, fileName.length);
alert.find(".file-name").text(fileName);
alert.find(".file-size").text(filesize(this.files[0].size));
alert.fadeIn("slow");
fileName = fileName.substr(fileName.lastIndexOf('\\') + 1, fileName.length);
alert.find('.file-name').text(fileName);
alert.find('.file-size').text(filesize(this.files[0].size));
alert.fadeIn('slow');
$("#form-url-upload").css("display", "none");
$('#form-url-upload').css('display', 'none');
if (success) {
var alertInner = alert.find(".alert");
var button = alert.find("button");
var icon = button.find("[data-fa-i2svg]");
var alertInner = alert.find('.alert');
var button = alert.find('button');
var icon = button.find('[data-fa-i2svg]');
alertInner
.removeClass("alert-info alert-danger")
.addClass("alert-success");
button.removeClass("btn-info").addClass("btn-success");
alertInner.removeClass('alert-info alert-danger').addClass('alert-success');
button.removeClass('btn-info').addClass('btn-success');
icon.addClass("fa-upload");
icon.addClass('fa-upload');
var newTitle = "Upload plugin";
var newTitle = 'Upload plugin';
button
.tooltip("hide")
.data("original-title", newTitle)
.tooltip('hide')
.data('original-title', newTitle)
.tooltip();
}
});

View File

@ -1,11 +1,11 @@
import $ from "jquery";
import {toggleSpinner} from "@/utils";
import $ from 'jquery';
import { toggleSpinner } from '@/utils';
//=====> HELPER FUNCTIONS
function tooltip(selector, title) {
$(selector).tooltip({
placement: "right",
placement: 'right',
title: title
});
}
@ -14,29 +14,29 @@ function success(selector, then) {
// Simulate loading :P
setTimeout(function() {
toggleSpinner($(selector));
$(selector).addClass("fa-check-circle");
$(selector).addClass('fa-check-circle');
then();
}, 500);
}
function failed(selector, message) {
toggleSpinner($(selector));
$(selector).addClass("fa-times-circle");
$(selector).addClass('fa-times-circle');
tooltip(selector, message);
}
// eslint-disable-next-line no-unused-vars
function checkId(pluginId, name, owner, slug) {
$.ajax({
url: "/api/v1/projects/" + pluginId,
url: '/api/v1/projects/' + pluginId,
statusCode: {
404: function() {
success(".id-status", function() {
success('.id-status', function() {
checkName(name, true, owner, slug);
});
},
200: function() {
failed(".id-status", "That plugin ID is not available!");
failed('.id-status', 'That plugin ID is not available!');
checkName(name, false, owner, slug);
}
}
@ -45,24 +45,21 @@ function checkId(pluginId, name, owner, slug) {
function checkName(name, idSuccess, owner, slug) {
if (name.length > 25) {
failed(
".name-status",
"This name is too long. Please rename your project to something under 25 characters."
);
failed('.name-status', 'This name is too long. Please rename your project to something under 25 characters.');
updateContinueButton(idSuccess, false);
return;
}
$.ajax({
url: "/" + owner + "/" + slug,
url: '/' + owner + '/' + slug,
statusCode: {
404: function() {
success(".name-status", function() {
success('.name-status', function() {
updateContinueButton(idSuccess, true);
});
},
200: function() {
failed(".name-status", "You already have a project of this name!");
failed('.name-status', 'You already have a project of this name!');
updateContinueButton(idSuccess, false);
}
}
@ -70,16 +67,16 @@ function checkName(name, idSuccess, owner, slug) {
}
function updateContinueButton(idSuccess, nameSuccess) {
var btn = $(".continue-btn")
var btn = $('.continue-btn')
.hide()
.removeClass("btn-default");
var icon = toggleSpinner(btn.find("[data-fa-i2svg]"));
.removeClass('btn-default');
var icon = toggleSpinner(btn.find('[data-fa-i2svg]'));
if (idSuccess && nameSuccess) {
btn.addClass("btn-primary").prop("disabled", false);
icon.addClass("fa-arrow-right");
btn.addClass('btn-primary').prop('disabled', false);
icon.addClass('fa-arrow-right');
} else {
btn.addClass("btn-danger");
icon.addClass("fa-times");
btn.addClass('btn-danger');
icon.addClass('fa-times');
}
btn.fadeIn();
}

View File

@ -1,6 +1,6 @@
import $ from "jquery";
import {apiV2Request} from "@/js/apiRequests";
import {decodeHtml, numberWithCommas, toggleSpinner} from "@/utils";
import $ from 'jquery';
import { apiV2Request } from '@/js/apiRequests';
import { decodeHtml, numberWithCommas, toggleSpinner } from '@/utils';
//=====> EXTERNAL CONSTANTS
@ -12,13 +12,13 @@ var alreadyStarred = false;
//=====> HELPER FUNCTIONS
function initFlagList() {
var flagList = $(".list-flags");
var flagList = $('.list-flags');
if (!flagList.length) return;
flagList.find("li").click(function() {
flagList.find(":checked").removeAttr("checked");
flagList.find('li').click(function() {
flagList.find(':checked').removeAttr('checked');
$(this)
.find("input")
.prop("checked", true);
.find('input')
.prop('checked', true);
});
}
@ -29,106 +29,103 @@ function animateEditBtn(e, marginLeft, andThen) {
}
function showEditBtn(e, andThen) {
animateEditBtn(e, "-34px", function() {
e.css("z-index", "1000");
animateEditBtn(e, '-34px', function() {
e.css('z-index', '1000');
if (andThen) andThen();
});
}
function hideEditBtn(e, andThen) {
animateEditBtn(e, "0", andThen);
animateEditBtn(e, '0', andThen);
}
var editing = false;
var previewing = false;
function initBtnEdit() {
var btnEdit = $(".btn-edit");
var btnEdit = $('.btn-edit');
if (!btnEdit.length) return;
var pageBtns = $(".btn-page");
var otherBtns = $(".btn-edit-container");
var pageBtns = $('.btn-page');
var otherBtns = $('.btn-edit-container');
// highlight with textarea
var editText = $(".page-edit").find("textarea");
var editText = $('.page-edit').find('textarea');
editText
.focus(function() {
btnEdit
.css("border-color", "#66afe9")
.css("border-right", "1px solid white")
.css(
"box-shadow",
"inset 0 1px 1px rgba(0,0,0,.075), -3px 0 8px rgba(102, 175, 233, 0.6)"
);
otherBtns.find(".btn").css("border-right-color", "#66afe9");
.css('border-color', '#66afe9')
.css('border-right', '1px solid white')
.css('box-shadow', 'inset 0 1px 1px rgba(0,0,0,.075), -3px 0 8px rgba(102, 175, 233, 0.6)');
otherBtns.find('.btn').css('border-right-color', '#66afe9');
})
.blur(function() {
$(".btn-page")
.css("border", "1px solid #ccc")
.css("box-shadow", "none");
$("button.open").css("border-right", "white");
$('.btn-page')
.css('border', '1px solid #ccc')
.css('box-shadow', 'none');
$('button.open').css('border-right', 'white');
});
// handle button clicks
pageBtns.click(function() {
if ($(this).hasClass("open")) return;
if ($(this).hasClass('open')) return;
// toggle button
$("button.open")
.removeClass("open")
.css("border", "1px solid #ccc");
$('button.open')
.removeClass('open')
.css('border', '1px solid #ccc');
$(this)
.addClass("open")
.css("border-right-color", "white");
.addClass('open')
.css('border-right-color', 'white');
var editor = $(".page-edit");
if ($(this).hasClass("btn-edit")) {
var editor = $('.page-edit');
if ($(this).hasClass('btn-edit')) {
editing = true;
previewing = false;
$(this)
.css("position", "absolute")
.css("top", "");
.css('position', 'absolute')
.css('top', '');
$(otherBtns)
.css("position", "absolute")
.css("top", "");
.css('position', 'absolute')
.css('top', '');
// open editor
var content = $(".page-rendered");
editor.find("textarea").css("height", content.css("height"));
var content = $('.page-rendered');
editor.find('textarea').css('height', content.css('height'));
content.hide();
editor.show();
// show buttons
showEditBtn($(".btn-preview-container"), function() {
showEditBtn($(".btn-save-container"), function() {
showEditBtn($(".btn-cancel-container"), function() {
showEditBtn($(".btn-delete-container"));
showEditBtn($('.btn-preview-container'), function() {
showEditBtn($('.btn-save-container'), function() {
showEditBtn($('.btn-cancel-container'), function() {
showEditBtn($('.btn-delete-container'));
});
});
});
} else if ($(this).hasClass("btn-preview")) {
} else if ($(this).hasClass('btn-preview')) {
// render markdown
var preview = $(".page-preview");
var raw = editor.find("textarea").val();
var preview = $('.page-preview');
var raw = editor.find('textarea').val();
editor.hide();
preview.show();
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-eye")
.find('[data-fa-i2svg]')
.toggleClass('fa-eye')
);
$.ajax({
type: "post",
url: "/pages/preview",
type: 'post',
url: '/pages/preview',
data: JSON.stringify({ raw: raw }),
contentType: "application/json",
dataType: "html",
contentType: 'application/json',
dataType: 'html',
complete: function() {
toggleSpinner(
$(".btn-preview")
.find("[data-fa-i2svg]")
.toggleClass("fa-eye")
$('.btn-preview')
.find('[data-fa-i2svg]')
.toggleClass('fa-eye')
);
},
success: function(cooked) {
@ -138,37 +135,37 @@ function initBtnEdit() {
editing = false;
previewing = true;
} else if ($(this).hasClass("btn-save")) {
} else if ($(this).hasClass('btn-save')) {
// add spinner
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-save")
.find('[data-fa-i2svg]')
.toggleClass('fa-save')
);
}
});
$(".btn-cancel").click(function() {
$('.btn-cancel').click(function() {
editing = false;
previewing = false;
// hide editor; show content
$(".page-edit").hide();
$(".page-preview").hide();
$(".page-content").show();
$('.page-edit').hide();
$('.page-preview').hide();
$('.page-content').show();
// move buttons behind
$(".btn-edit-container").css("z-index", "-1000");
$('.btn-edit-container').css('z-index', '-1000');
// hide buttons
var fromSave = function() {
hideEditBtn($(".btn-save-container"), function() {
hideEditBtn($(".btn-preview-container"));
hideEditBtn($('.btn-save-container'), function() {
hideEditBtn($('.btn-preview-container'));
});
};
var btnDelete = $(".btn-delete-container");
var btnCancel = $(".btn-cancel-container");
var btnDelete = $('.btn-delete-container');
var btnCancel = $('.btn-cancel-container');
if (btnDelete.length) {
hideEditBtn(btnDelete, function() {
hideEditBtn(btnCancel, fromSave);
@ -182,24 +179,24 @@ function initBtnEdit() {
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
var editHeight = btnEdit.height();
var page = previewing ? $(".page-preview") : $(".page-content");
var page = previewing ? $('.page-preview') : $('.page-content');
var pageTop = page.position().top;
var pto = page.offset().top;
var pos = btnEdit.css("position");
var pos = btnEdit.css('position');
var bound = pto - editHeight - 30;
if (scrollTop > bound && pos === "absolute" && !editing) {
if (scrollTop > bound && pos === 'absolute' && !editing) {
var newTop = pageTop + editHeight + 20;
btnEdit.css("position", "fixed").css("top", newTop);
btnEdit.css('position', 'fixed').css('top', newTop);
otherBtns.each(function() {
newTop += 0.5;
$(this)
.css("position", "fixed")
.css("top", newTop);
.css('position', 'fixed')
.css('top', newTop);
});
} else if (scrollTop < bound && pos === "fixed") {
btnEdit.css("position", "absolute").css("top", "");
otherBtns.css("position", "absolute").css("top", "");
} else if (scrollTop < bound && pos === 'fixed') {
btnEdit.css('position', 'absolute').css('top', '');
otherBtns.css('position', 'absolute').css('top', '');
}
});
}
@ -211,7 +208,7 @@ $(function() {
initBtnEdit();
// flag button alert
var flagMsg = $(".flag-msg");
var flagMsg = $('.flag-msg');
if (flagMsg.length) {
flagMsg
.hide()
@ -221,82 +218,69 @@ $(function() {
}
// watch button
$(".btn-watch").click(function() {
var status = $(this).find(".watch-status");
var watching = $(this).hasClass("watching");
$('.btn-watch').click(function() {
var status = $(this).find('.watch-status');
var watching = $(this).hasClass('watching');
if (watching) {
status.text("Watch");
$(this).removeClass("watching");
status.text('Watch');
$(this).removeClass('watching');
} else {
status.text("Unwatch");
$(this).addClass("watching");
status.text('Unwatch');
$(this).addClass('watching');
}
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-eye")
.toggleClass("fa-eye-slash");
.find('[data-fa-i2svg]')
.toggleClass('fa-eye')
.toggleClass('fa-eye-slash');
$.ajax({
type: "post",
url:
decodeHtml("/" + projectOwner + "/" + projectSlug) +
"/watchers/" +
!watching
type: 'post',
url: decodeHtml('/' + projectOwner + '/' + projectSlug) + '/watchers/' + !watching
});
});
// setup star button
var increment = alreadyStarred ? -1 : 1;
$(".btn-star").click(function() {
var starred = $(this).find(".starred");
starred.html(" " + (parseInt(starred.text()) + increment).toString());
$('.btn-star').click(function() {
var starred = $(this).find('.starred');
starred.html(' ' + (parseInt(starred.text()) + increment).toString());
$.ajax({
type: "post",
url: decodeHtml("/" + projectOwner + "/" + projectSlug) + "/stars/toggle"
type: 'post',
url: decodeHtml('/' + projectOwner + '/' + projectSlug) + '/stars/toggle'
});
if (increment > 0) {
$(this)
.find("[data-fa-i2svg]")
.attr("data-prefix", "fas");
.find('[data-fa-i2svg]')
.attr('data-prefix', 'fas');
} else {
$(this)
.find("[data-fa-i2svg]")
.attr("data-prefix", "far");
.find('[data-fa-i2svg]')
.attr('data-prefix', 'far');
}
increment *= -1;
});
if (projectId) {
apiV2Request("projects/" + projectId).then(response => {
apiV2Request('projects/' + projectId).then(response => {
if (response.promoted_versions) {
let html = "";
let html = '';
response.promoted_versions.forEach(version => {
const href = window.jsRoutes.controllers.project.Versions.show(
projectOwner,
projectSlug,
version.version
).absoluteURL();
html =
html +
"<li class='list-group-item'><a href='" +
href +
"'>" +
version.version +
"</a></li>";
html = html + "<li class='list-group-item'><a href='" + href + "'>" + version.version + '</a></li>';
});
$(".promoted-list").html(html);
$('.promoted-list').html(html);
}
$(".stats #view-count").html(numberWithCommas(response.stats.views));
$(".stats #star-count").html(numberWithCommas(response.stats.stars));
$(".stats #watcher-count").html(
numberWithCommas(response.stats.watchers)
);
$(".stats #download-count").html(
numberWithCommas(response.stats.downloads)
);
$('.stats #view-count').html(numberWithCommas(response.stats.views));
$('.stats #star-count').html(numberWithCommas(response.stats.stars));
$('.stats #watcher-count').html(numberWithCommas(response.stats.watchers));
$('.stats #download-count').html(numberWithCommas(response.stats.downloads));
});
}
});

View File

@ -1,12 +1,9 @@
//=====> DOCUMENT READY
(function() {
var d = document.createElement("script");
d.type = "text/javascript";
var d = document.createElement('script');
d.type = 'text/javascript';
d.async = true;
d.src = window.DiscourseEmbed.discourseUrl + "build/js/embed.js"; // TODO this was ... + "javascripts/embed.js"
(
document.getElementsByTagName("head")[0] ||
document.getElementsByTagName("body")[0]
).appendChild(d);
d.src = window.DiscourseEmbed.discourseUrl + 'build/js/embed.js'; // TODO this was ... + "javascripts/embed.js"
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
})();

View File

@ -1,4 +1,4 @@
import $ from "jquery";
import $ from 'jquery';
//=====> CONSTANTS
@ -11,28 +11,28 @@ var projectName = null;
//=====> DOCUMENT READY
$(function() {
var name = $("#name");
name.on("input", function() {
var name = $('#name');
name.on('input', function() {
var val = $(this).val();
$("#btn-rename").prop("disabled", val.length === 0 || val === projectName);
$('#btn-rename').prop('disabled', val.length === 0 || val === projectName);
});
name.keydown(function(e) {
if (e.which === KEY_RETURN) {
e.preventDefault();
$("#btn-rename").click();
$('#btn-rename').click();
}
});
$(".dropdown-license")
.find("a")
$('.dropdown-license')
.find('a')
.click(function() {
var btn = $(".btn-license");
var btn = $('.btn-license');
var text = $(this).text();
btn.find(".license").text(text);
btn.find('.license').text(text);
var name = $('input[name="license-name"]');
if ($(this).hasClass("license-custom")) {
name.val("");
if ($(this).hasClass('license-custom')) {
name.val('');
name.show().focus();
} else {
name.hide();

View File

@ -1,32 +1,32 @@
import $ from "jquery";
import {clearUnread, toggleSpinner} from "@/utils";
import $ from 'jquery';
import { clearUnread, toggleSpinner } from '@/utils';
//=====> DOCUMENT READY
$(function() {
$(".btn-approve").click(function() {
var listItem = $(this).closest(".list-group-item");
var versionPath = listItem.data("version");
$('.btn-approve').click(function() {
var listItem = $(this).closest('.list-group-item');
var versionPath = listItem.data('version');
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.removeClass("fa-thumbs-up")
.find('[data-fa-i2svg]')
.removeClass('fa-thumbs-up')
);
$.ajax({
type: "post",
url: "/" + versionPath + "/approve",
type: 'post',
url: '/' + versionPath + '/approve',
complete: function() {
toggleSpinner(
$(".btn-approve")
.find("[data-fa-i2svg]")
.addClass("fa-thumbs-up")
$('.btn-approve')
.find('[data-fa-i2svg]')
.addClass('fa-thumbs-up')
);
},
success: function() {
$.when(listItem.fadeOut("slow")).done(function() {
$.when(listItem.fadeOut('slow')).done(function() {
listItem.remove();
if (!$(".list-versions").find("li").length) {
$(".no-versions").fadeIn();
if (!$('.list-versions').find('li').length) {
$('.no-versions').fadeIn();
clearUnread($('a[href="/admin/queue"]'));
}
});

View File

@ -1,23 +1,21 @@
import $ from "jquery";
import {toggleSpinner} from "@/utils";
import $ from 'jquery';
import { toggleSpinner } from '@/utils';
//=====> DOCUMENT READY
$(function() {
$(".btn-review-start").click(function() {
$('.btn-review-start').click(function() {
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-terminal")
.find('[data-fa-i2svg]')
.toggleClass('fa-terminal')
);
$(this).attr("disabled", "disabled");
$(this).attr('disabled', 'disabled');
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/init",
type: 'post',
url: '/' + window.versionPath + '/reviews/init',
complete: function() {
toggleSpinner(
$(".btn-review-start [data-fa-i2svg]").addClass("fa-terminal")
);
toggleSpinner($('.btn-review-start [data-fa-i2svg]').addClass('fa-terminal'));
},
success: function() {
location.reload();
@ -25,13 +23,13 @@ $(function() {
});
});
$(".btn-skip-review").click(function() {
$('.btn-skip-review').click(function() {
var btn = $(this);
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/reviewtoggle",
type: 'post',
url: '/' + window.versionPath + '/reviews/reviewtoggle',
complete: function() {
btn.html("Add to queue");
btn.html('Add to queue');
},
success: function() {
location.reload();
@ -39,29 +37,29 @@ $(function() {
});
});
$(".btn-review-stop").click(function() {
var modal = $("#modal-review-stop");
$('.btn-review-stop').click(function() {
var modal = $('#modal-review-stop');
modal.modal().show();
modal.on("shown.bs.modal", function() {
modal.on('shown.bs.modal', function() {
$(this)
.find("textarea")
.find('textarea')
.focus();
});
});
$(".btn-review-stop-submit").click(function() {
$('.btn-review-stop-submit').click(function() {
var icon = toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-times-circle-o")
.find('[data-fa-i2svg]')
.toggleClass('fa-times-circle-o')
);
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/stop",
type: 'post',
url: '/' + window.versionPath + '/reviews/stop',
data: { content: $(".textarea-stop").val() },
data: { content: $('.textarea-stop').val() },
complete: function() {
toggleSpinner(icon.addClass("fa-times-circle-o"));
toggleSpinner(icon.addClass('fa-times-circle-o'));
},
success: function() {
location.reload();
@ -69,101 +67,101 @@ $(function() {
});
});
$(".btn-review-approve").click(function() {
$('.btn-review-approve').click(function() {
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-thumbs-up")
.find('[data-fa-i2svg]')
.toggleClass('fa-thumbs-up')
);
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/approve"
type: 'post',
url: '/' + window.versionPath + '/reviews/approve'
});
$.ajax({
type: "post",
url: "/" + window.versionPath + "/approve",
type: 'post',
url: '/' + window.versionPath + '/approve',
success: function() {
location.reload();
}
});
});
$(".btn-review-approve-partial").click(function() {
$('.btn-review-approve-partial').click(function() {
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-thumbs-up")
.find('[data-fa-i2svg]')
.toggleClass('fa-thumbs-up')
);
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/approve"
type: 'post',
url: '/' + window.versionPath + '/reviews/approve'
});
$.ajax({
type: "post",
url: "/" + window.versionPath + "/approvePartial",
type: 'post',
url: '/' + window.versionPath + '/approvePartial',
success: function() {
location.reload();
}
});
});
$(".btn-review-takeover").click(function() {
var modal = $("#modal-review-takeover");
$('.btn-review-takeover').click(function() {
var modal = $('#modal-review-takeover');
modal.modal().show();
modal.on("shown.bs.modal", function() {
modal.on('shown.bs.modal', function() {
$(this)
.find("textarea")
.find('textarea')
.focus();
});
});
$(".btn-review-takeover-submit").click(function() {
$('.btn-review-takeover-submit').click(function() {
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-clipboard")
.find('[data-fa-i2svg]')
.toggleClass('fa-clipboard')
);
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/takeover",
data: { content: $(".textarea-takeover").val() },
type: 'post',
url: '/' + window.versionPath + '/reviews/takeover',
data: { content: $('.textarea-takeover').val() },
success: function() {
location.reload();
}
});
});
$(".btn-edit-message").click(function() {
$('.btn-edit-message').click(function() {
var panel = $(this)
.parent()
.parent()
.parent();
var text = panel.find("textarea");
text.attr("disabled", null);
var text = panel.find('textarea');
text.attr('disabled', null);
$(this).hide();
panel.find(".btn-cancel-message").show();
panel.find(".btn-save-message").show();
panel.find('.btn-cancel-message').show();
panel.find('.btn-save-message').show();
});
$(".btn-cancel-message").click(function() {
$('.btn-cancel-message').click(function() {
location.reload();
});
$(".btn-save-message").click(function() {
$('.btn-save-message').click(function() {
var panel = $(this)
.parent()
.parent()
.parent();
var textarea = panel.find("textarea");
textarea.attr("disabled", "disabled");
var textarea = panel.find('textarea');
textarea.attr('disabled', 'disabled');
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-save")
.find('[data-fa-i2svg]')
.toggleClass('fa-save')
);
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/edit/" + panel.data("review"),
type: 'post',
url: '/' + window.versionPath + '/reviews/edit/' + panel.data('review'),
data: { content: textarea.val() },
success: function() {
location.reload();
@ -171,34 +169,34 @@ $(function() {
});
});
$(".btn-review-addmessage-submit").click(function() {
$('.btn-review-addmessage-submit').click(function() {
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.removeClass("fa-clipboard")
.find('[data-fa-i2svg]')
.removeClass('fa-clipboard')
);
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/addmessage",
data: { content: $(".textarea-addmessage").val() },
type: 'post',
url: '/' + window.versionPath + '/reviews/addmessage',
data: { content: $('.textarea-addmessage').val() },
success: function() {
location.reload();
}
});
});
$(".btn-review-reopen").click(function() {
$('.btn-review-reopen').click(function() {
var icon = toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-terminal")
.find('[data-fa-i2svg]')
.toggleClass('fa-terminal')
);
$(this).attr("disabled", "disabled");
$(this).attr('disabled', 'disabled');
$.ajax({
type: "post",
url: "/" + window.versionPath + "/reviews/reopen",
type: 'post',
url: '/' + window.versionPath + '/reviews/reopen',
complete: function() {
toggleSpinner(icon.toggleClass("fa-terminal"));
toggleSpinner(icon.toggleClass('fa-terminal'));
},
success: function() {
location.reload();

View File

@ -1,24 +1,24 @@
import $ from "jquery";
import {toggleSpinner} from "@/utils";
import $ from 'jquery';
import { toggleSpinner } from '@/utils';
//=====> DOCUMENT READY
$(function() {
$(".btn-note-addmessage-submit").click(function() {
$('.btn-note-addmessage-submit').click(function() {
var panel = $(this)
.parent()
.parent()
.parent();
var textarea = panel.find("textarea");
textarea.attr("disabled", "disabled");
var textarea = panel.find('textarea');
textarea.attr('disabled', 'disabled');
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-save")
.find('[data-fa-i2svg]')
.toggleClass('fa-save')
);
$.ajax({
type: "post",
url: "/" + window.resourcePath + "/notes/addmessage",
type: 'post',
url: '/' + window.resourcePath + '/notes/addmessage',
data: { content: textarea.val() },
success: function() {
location.reload();

View File

@ -1,12 +1,12 @@
import $ from "jquery";
import {go} from "@/utils";
import $ from 'jquery';
import { go } from '@/utils';
//=====> DOCUMENT READY
$(function() {
$("#dateGoButton").click(function() {
var from = $("#fromDate").val();
var to = $("#toDate").val();
$('#dateGoButton').click(function() {
var from = $('#fromDate').val();
var to = $('#toDate').val();
function removeTime(date) {
date.setHours(0, 0, 0, 0);
@ -38,11 +38,7 @@ $(function() {
from.setDate(to.getDate() - 2);
}
var url =
"/admin/stats?from=" +
from.toISOString().substr(0, 10) +
"&to=" +
to.toISOString().substr(0, 10);
var url = '/admin/stats?from=' + from.toISOString().substr(0, 10) + '&to=' + to.toISOString().substr(0, 10);
go(url);
});
});

View File

@ -1,11 +1,11 @@
import $ from "jquery";
import $ from 'jquery';
//=====> HELPER FUNCTIONS
function update(thing, action, data) {
return $.ajax({
url: window.location.pathname + "/update",
method: "post",
url: window.location.pathname + '/update',
method: 'post',
data: {
thing: thing,
action: action,
@ -27,24 +27,22 @@ function loadingButton(button) {
//=====> DOCUMENT READY
$(function() {
var globalRoleSelect = $("#add-global-role-select");
var globalRoleList = $("#global-roles-list");
var globalRoleSelect = $('#add-global-role-select');
var globalRoleList = $('#global-roles-list');
$("#add-global-role").click(function() {
var finishLoading = loadingButton($("#add-global-role"));
$('#add-global-role').click(function() {
var finishLoading = loadingButton($('#add-global-role'));
var selected = $("option:selected", globalRoleSelect);
var selected = $('option:selected', globalRoleSelect);
update("globalRole", "add", { role: parseInt(selected.val()) })
update('globalRole', 'add', { role: parseInt(selected.val()) })
.done(function() {
// Add role to list
var newItem = $('<div class="list-group-item"></div>');
newItem.data({ role: selected.val() });
newItem.text(selected.text());
newItem.append(
$(
'<span class="float-right"><a href="#" class="global-role-delete"><i class="fa fa-trash"></i></a></span>'
)
$('<span class="float-right"><a href="#" class="global-role-delete"><i class="fa fa-trash"></i></a></span>')
);
newItem.insertBefore(globalRoleList.children().last());
// Remove from select
@ -53,18 +51,18 @@ $(function() {
.always(finishLoading);
});
globalRoleList.on("click", ".global-role-delete", function(event) {
globalRoleList.on('click', '.global-role-delete', function(event) {
event.preventDefault();
var item = $(event.target).closest(".list-group-item");
var item = $(event.target).closest('.list-group-item');
var finishLoading = loadingButton($(event.target).parent());
var role = parseInt(item.data("role"));
var role = parseInt(item.data('role'));
var title = item.text();
update("globalRole", "remove", { role: role })
update('globalRole', 'remove', { role: role })
.done(function() {
var option = $("<option></option>");
var option = $('<option></option>');
option.text(title);
option.val(role);
globalRoleSelect.append(option);
@ -75,45 +73,41 @@ $(function() {
function rowChange(action, data, element) {
element.disabled = true;
var row = $(element).closest("tr");
var id = parseInt(row.data("role-id"));
var type = row.data("role-type");
var row = $(element).closest('tr');
var id = parseInt(row.data('role-id'));
var type = row.data('role-type');
return update(type, action, $.extend({ id: id }, data)).always(function() {
element.disabled = false;
});
}
var roleTables = $(".role-table");
var roleTables = $('.role-table');
roleTables.on("change", ".select-role", function(event) {
rowChange("setRole", { role: parseInt(event.target.value) }, event.target)
roleTables.on('change', '.select-role', function(event) {
rowChange('setRole', { role: parseInt(event.target.value) }, event.target)
.fail(function() {
event.target.selectedIndex = event.target.defaultValue;
})
.done(function() {
event.target.defaultValue = event.target.selectedIndex;
if ($("option:selected", event.target).data("refresh")) {
if ($('option:selected', event.target).data('refresh')) {
history.go(0);
}
});
});
roleTables.find(".select-role").each(function(i, element) {
roleTables.find('.select-role').each(function(i, element) {
element.defaultValue = element.selectedIndex;
});
roleTables.on("change", ".role-accepted", function(event) {
rowChange(
"setAccepted",
{ accepted: event.target.checked },
event.target
).fail(function() {
roleTables.on('change', '.role-accepted', function(event) {
rowChange('setAccepted', { accepted: event.target.checked }, event.target).fail(function() {
event.target.checked = !event.target.checked;
});
});
roleTables.on("click", ".delete-role", function(event) {
roleTables.on('click', '.delete-role', function(event) {
event.preventDefault();
var row = $(event.target).closest("tr");
rowChange("deleteRole", {}, event.target).done(row.remove);
var row = $(event.target).closest('tr');
rowChange('deleteRole', {}, event.target).done(row.remove);
});
});

View File

@ -1,5 +1,5 @@
import $ from "jquery";
import {go} from "@/utils";
import $ from 'jquery';
import { go } from '@/utils';
//=====> EXTERNAL CONSTANTS
@ -8,27 +8,27 @@ var CURRENT_PAGE = 0;
//=====> DOCUMENT READY
$(function() {
$(".table-users")
.find("thead")
.find("td:not(:first-child)")
$('.table-users')
.find('thead')
.find('td:not(:first-child)')
.click(function() {
var sort = $(this)
.text()
.toLowerCase()
.trim();
var direction = "";
var direction = '';
var thisObj = $(this);
if (thisObj.hasClass("user-sort")) {
if (thisObj.hasClass('user-sort')) {
// Change direction
direction = $(this)
.find("svg")
.hasClass("fa-chevron-up")
? "-"
: "";
.find('svg')
.hasClass('fa-chevron-up')
? '-'
: '';
}
var start = thisObj.data("list");
var url = "/" + start + "?sort=" + direction + sort;
if (CURRENT_PAGE > 1) url += "&page=" + CURRENT_PAGE;
var start = thisObj.data('list');
var url = '/' + start + '?sort=' + direction + sort;
if (CURRENT_PAGE > 1) url += '&page=' + CURRENT_PAGE;
go(url);
});
});

View File

@ -1,5 +1,5 @@
import $ from "jquery";
import {apiV2Request} from "@/js/apiRequests";
import $ from 'jquery';
import { apiV2Request } from '@/js/apiRequests';
//=====> EXTERNAL CONSTANTS
@ -18,66 +18,46 @@ var pages = {
//=====> HELPER FUNCTIONS
function getStarsPanel(action) {
return $(".card-user-info[data-action=" + action + "]");
return $('.card-user-info[data-action=' + action + ']');
}
function getStarsFooter(action) {
return getStarsPanel(action).find(".card-footer");
return getStarsPanel(action).find('.card-footer');
}
function loadActions(increment, action) {
pages[action] += increment;
var offset = (pages[action] - 1) * CONTENT_PER_PAGE;
apiV2Request(
"users/" +
USERNAME +
"/" +
action +
"?offset=" +
offset +
"&limit=" +
CONTENT_PER_PAGE
).then(function(result) {
apiV2Request('users/' + USERNAME + '/' + action + '?offset=' + offset + '&limit=' + CONTENT_PER_PAGE).then(function(
result
) {
//TODO: Use pagination info
var tbody = getStarsPanel(action)
.find(".card-body")
.find("tbody");
.find('.card-body')
.find('tbody');
var content = [];
if (result.pagination.count === 0) {
content.push(
$("<tr>").append(
$("<td>").append(
$("<i class='minor'>").text(NO_ACTION_MESSAGE[action])
)
)
);
content.push($('<tr>').append($('<td>').append($("<i class='minor'>").text(NO_ACTION_MESSAGE[action]))));
} else {
for (var project of result.result) {
var link = $("<a>")
.attr(
"href",
"/" + project.namespace.owner + "/" + project.namespace.slug
)
.text(project.namespace.owner + "/")
.append($("<strong>").text(project.namespace.slug));
var link = $('<a>')
.attr('href', '/' + project.namespace.owner + '/' + project.namespace.slug)
.text(project.namespace.owner + '/')
.append($('<strong>').text(project.namespace.slug));
var versionDiv = $("<div class='float-right'>");
if (project.recommended_version) {
versionDiv.append(
$("<span class='minor'>").text(project.recommended_version.version)
);
versionDiv.append($("<span class='minor'>").text(project.recommended_version.version));
}
var versionIcon = $("<i>");
versionIcon.attr("title", CATEGORY_TITLE[project.category]);
versionIcon
.addClass("fas fa-fw")
.addClass(CATEGORY_ICON[project.category]);
var versionIcon = $('<i>');
versionIcon.attr('title', CATEGORY_TITLE[project.category]);
versionIcon.addClass('fas fa-fw').addClass(CATEGORY_ICON[project.category]);
versionDiv.append(versionIcon);
content.push($("<tr>").append($("<td>").append(link, versionDiv)));
content.push($('<tr>').append($('<td>').append(link, versionDiv)));
}
}
@ -85,7 +65,7 @@ function loadActions(increment, action) {
tbody.empty();
tbody.append(content);
var footer = getStarsFooter(action);
var prev = footer.find(".prev");
var prev = footer.find('.prev');
// Check if there is a last page
if (pages[action] > 1) {
@ -95,7 +75,7 @@ function loadActions(increment, action) {
}
// Check if there is a next page
var next = footer.find(".next");
var next = footer.find('.next');
if (result.pagination.count > pages[action] * CONTENT_PER_PAGE) {
next.show();
} else {
@ -109,7 +89,7 @@ function formAsync(form, route, onSuccess) {
e.preventDefault();
var formData = new FormData(this);
var spinner = $(this)
.find(".fa-spinner")
.find('.fa-spinner')
.show();
$.ajax({
url: route,
@ -117,8 +97,8 @@ function formAsync(form, route, onSuccess) {
cache: false,
contentType: false,
processData: false,
type: "post",
dataType: "json",
type: 'post',
dataType: 'json',
complete: function() {
spinner.hide();
},
@ -128,72 +108,63 @@ function formAsync(form, route, onSuccess) {
}
function setupAvatarForm() {
$(".btn-got-it").click(function() {
var prompt = $(this).closest(".prompt");
$('.btn-got-it').click(function() {
var prompt = $(this).closest('.prompt');
$.ajax({
type: "post",
url: "prompts/read/" + prompt.data("prompt-id")
type: 'post',
url: 'prompts/read/' + prompt.data('prompt-id')
});
prompt.fadeOut("fast");
prompt.fadeOut('fast');
});
$(".organization-avatar").hover(
$('.organization-avatar').hover(
function() {
$(".edit-avatar").fadeIn("fast");
$('.edit-avatar').fadeIn('fast');
},
function(e) {
if (
!$(e.relatedTarget)
.closest("div")
.hasClass("edit-avatar")
.closest('div')
.hasClass('edit-avatar')
) {
$(".edit-avatar").fadeOut("fast");
$('.edit-avatar').fadeOut('fast');
}
}
);
var avatarModal = $("#modal-avatar");
avatarModal.find(".alert").hide();
var avatarModal = $('#modal-avatar');
avatarModal.find('.alert').hide();
var avatarForm = avatarModal.find("#form-avatar");
var avatarForm = avatarModal.find('#form-avatar');
avatarForm.find('input[name="avatar-method"]').change(function() {
avatarForm
.find('input[name="avatar-file"]')
.prop("disabled", $(this).val() !== "by-file");
avatarForm.find('input[name="avatar-file"]').prop('disabled', $(this).val() !== 'by-file');
});
formAsync(
avatarForm,
"organizations/" + USERNAME + "/settings/avatar",
function(json) {
if (Object.prototype.hasOwnProperty.call(json, "errors")) {
var alert = avatarForm.find(".alert-danger");
alert.find(".error").text(json["errors"][0]);
alert.fadeIn("slow");
} else {
avatarModal.modal("hide");
var success = $(".alert-success");
success.find(".success").text("Avatar successfully updated!");
success.fadeIn("slow");
$('.user-avatar[title="' + USERNAME + '"]').prop(
"src",
json["avatarTemplate"].replace("{size}", "200")
);
}
formAsync(avatarForm, 'organizations/' + USERNAME + '/settings/avatar', function(json) {
if (Object.prototype.hasOwnProperty.call(json, 'errors')) {
var alert = avatarForm.find('.alert-danger');
alert.find('.error').text(json['errors'][0]);
alert.fadeIn('slow');
} else {
avatarModal.modal('hide');
var success = $('.alert-success');
success.find('.success').text('Avatar successfully updated!');
success.fadeIn('slow');
$('.user-avatar[title="' + USERNAME + '"]').prop('src', json['avatarTemplate'].replace('{size}', '200'));
}
);
});
}
//=====> DOCUMENT READY
$(function() {
for (let action of ["starred", "watching"]) {
for (let action of ['starred', 'watching']) {
var footer = getStarsFooter(action);
loadActions(0, action);
footer.find(".next").click(function() {
footer.find('.next').click(function() {
loadActions(1, action);
});
footer.find(".prev").click(function() {
footer.find('.prev').click(function() {
loadActions(-1, action);
});
}

View File

@ -1,55 +1,51 @@
import $ from "jquery";
import {KEY_ENTER, toggleSpinner} from "@/utils";
import $ from 'jquery';
import { KEY_ENTER, toggleSpinner } from '@/utils';
//=====> HELPER FUNCTIONS
export function initUserSearch(callback) {
var search = $(".user-search");
var input = search.find("input");
var search = $('.user-search');
var input = search.find('input');
// Disable button with no input
input.on("input", function() {
input.on('input', function() {
$(this)
.next()
.find(".btn")
.prop("disabled", $(this).val().length === 0);
.find('.btn')
.prop('disabled', $(this).val().length === 0);
});
// Catch enter key
input.on("keypress", function(event) {
input.on('keypress', function(event) {
if (event.keyCode === KEY_ENTER) {
event.preventDefault();
$(this)
.next()
.find(".btn")
.find('.btn')
.click();
}
});
// Search for user
search.find(".btn-search").click(function() {
search.find('.btn-search').click(function() {
const input = $(this)
.closest(".user-search")
.find("input");
.closest('.user-search')
.find('input');
const username = input.val().trim();
if (username !== "") {
if (username !== '') {
toggleSpinner(
$(this)
.find("[data-fa-i2svg]")
.toggleClass("fa-search")
.find('[data-fa-i2svg]')
.toggleClass('fa-search')
);
$.ajax({
url: "/api/v1/users/" + username,
dataType: "json",
url: '/api/v1/users/' + username,
dataType: 'json',
complete: function() {
input.val("");
toggleSpinner(
$(".user-search .btn-search [data-fa-i2svg]").toggleClass(
"fa-search"
)
);
$(".user-search .btn-search").prop("disabled", true);
input.val('');
toggleSpinner($('.user-search .btn-search [data-fa-i2svg]').toggleClass('fa-search'));
$('.user-search .btn-search').prop('disabled', true);
},
error: function() {

View File

@ -1,6 +1,6 @@
import $ from "jquery";
import "bootstrap/js/dist/modal";
import {initChannelManager} from "@/js/channelManage";
import $ from 'jquery';
import 'bootstrap/js/dist/modal';
import { initChannelManager } from '@/js/channelManage';
//=====> EXTERNAL CONSTANTS
@ -9,29 +9,20 @@ var DEFAULT_COLOR = null;
//=====> HELPER FUNCTIONS
function initChannelNew(color) {
initChannelManager(
"#channel-new",
"",
color,
"New channel",
null,
null,
"Create channel",
false
);
initChannelManager('#channel-new', '', color, 'New channel', null, null, 'Create channel', false);
}
function getForm() {
return $("#form-publish");
return $('#form-publish');
}
function getSelect() {
return $("#select-channel");
return $('#select-channel');
}
function setColorInput(val) {
getForm()
.find(".channel-color-input")
.find('.channel-color-input')
.val(val);
}
@ -45,8 +36,8 @@ $(function() {
getSelect().change(function() {
setColorInput(
$(this)
.find(":selected")
.data("color")
.find(':selected')
.data('color')
);
});
@ -62,7 +53,7 @@ $(function() {
// Add new name to select
var select = getSelect();
var exists =
select.find("option").find(function() {
select.find('option').find(function() {
return (
$(this)
.val()
@ -72,7 +63,7 @@ $(function() {
if (!exists) {
setColorInput(channelHex);
select.find(":selected").removeAttr("selected");
select.find(':selected').removeAttr('selected');
select.append(
'<option data-color="' +
channelHex +
@ -80,13 +71,13 @@ $(function() {
'value="' +
channelName +
'" ' +
"selected>" +
'selected>' +
channelName +
"</option>"
'</option>'
);
}
$("#channel-settings").modal("hide");
$('#channel-settings').modal('hide');
initChannelNew(DEFAULT_COLOR);
};
});

View File

@ -1,8 +1,8 @@
import $ from "jquery";
import $ from 'jquery';
export function clearFromEmpty(object) {
return Object.entries(object)
.filter(([key, value]) => value != null && value !== "") // eslint-disable-line no-unused-vars
.filter(([key, value]) => value != null && value !== '') // eslint-disable-line no-unused-vars
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
}
@ -27,14 +27,14 @@ export function parseJsonOrNull(jsonString) {
}
export function sanitize(html) {
return $("<textarea>")
return $('<textarea>')
.html(html)
.text();
}
export function decodeHtml(html) {
// lol
return $("<textarea>")
return $('<textarea>')
.html(html)
.val();
}
@ -44,13 +44,13 @@ export function go(str) {
}
export function clearUnread(e) {
e.find(".unread").remove();
if (!$(".user-dropdown .unread").length) $(".unread").remove();
e.find('.unread').remove();
if (!$('.user-dropdown .unread').length) $('.unread').remove();
}
export function initTooltips() {
$('[data-toggle="tooltip"]').tooltip({
container: "body",
container: 'body',
delay: { show: 500 }
});
}
@ -58,28 +58,28 @@ export function initTooltips() {
export function slugify(name) {
return name
.trim()
.replace(/ +/g, " ")
.replace(/ /g, "-");
.replace(/ +/g, ' ')
.replace(/ /g, '-');
}
export function toggleSpinner(e) {
return e.toggleClass("fa-spinner").toggleClass("fa-spin");
return e.toggleClass('fa-spinner').toggleClass('fa-spin');
}
export function numberWithCommas(x) {
const parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
const parts = x.toString().split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return parts.join('.');
}
export const scrollToAnchor = function(anchor) {
if (anchor) {
let target = $("a" + anchor);
let target = $('a' + anchor);
if (target.length) {
$("html,body").animate(
$('html,body').animate(
{
scrollTop: target.offset().top - ($("#topbar").height() + 10)
scrollTop: target.offset().top - ($('#topbar').height() + 10)
},
1
);

View File

@ -1,63 +1,52 @@
const path = require("path");
const fs = require("fs");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
const fs = require('fs');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const sourceDir = path.resolve(__dirname, "src");
const entryDir = path.resolve(sourceDir, "entrypoints");
const jsDir = path.resolve(sourceDir, "js");
const outputDir = path.resolve(
__dirname,
"..",
"..",
"..",
"target",
"classes",
"public",
"build"
);
const sourceDir = path.resolve(__dirname, 'src');
const entryDir = path.resolve(sourceDir, 'entrypoints');
const jsDir = path.resolve(sourceDir, 'js');
const outputDir = path.resolve(__dirname, '..', '..', '..', 'target', 'classes', 'public', 'build');
module.exports = {
chainWebpack: config => {
// clear default
config.entry("app").clear();
config.entry("app").add(path.resolve(entryDir, "dummy.js"));
config.entry('app').clear();
config.entry('app').add(path.resolve(entryDir, 'dummy.js'));
config.entry("main").add(path.resolve(sourceDir, "scss", "main.scss"));
config.entry('main').add(path.resolve(sourceDir, 'scss', 'main.scss'));
// iterate thru entry points and add them to webpack
for (const file of fs.readdirSync(entryDir)) {
config.entry(file.replace(".js", "")).add(path.resolve(entryDir, file));
config.entry(file.replace('.js', '')).add(path.resolve(entryDir, file));
}
for (const file of fs.readdirSync(jsDir)) {
config.entry(file.replace(".js", "")).add(path.resolve(jsDir, file));
config.entry(file.replace('.js', '')).add(path.resolve(jsDir, file));
}
config.module.rules.delete("css");
config.module.rules.delete("scss");
config.module.rules.delete('css');
config.module.rules.delete('scss');
config
.plugin("mini-css-extract")
.use(MiniCssExtractPlugin, [{ filename: "css/[name].css" }]);
config.plugin('mini-css-extract').use(MiniCssExtractPlugin, [{ filename: 'css/[name].css' }]);
config.module
.rule("css")
.rule('css')
.test(/\.(s?)css$/i)
.use("mini-css-extract")
.use('mini-css-extract')
.loader(MiniCssExtractPlugin.loader)
.options({
hmr: process.env.NODE_ENV === "development",
hmr: process.env.NODE_ENV === 'development',
reloadAll: true,
publicPath: "/css/"
publicPath: '/css/'
})
.end()
.use("css-loader")
.loader("css-loader")
.use('css-loader')
.loader('css-loader')
.end()
.use("postcss-loader")
.loader("postcss-loader")
.use('postcss-loader')
.loader('postcss-loader')
.end()
.use("sass-loader")
.loader("sass-loader")
.use('sass-loader')
.loader('sass-loader')
.end();
},

View File

@ -1970,13 +1970,6 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428"
integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==
axios@^0.15.3:
version "0.15.3"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.15.3.tgz#2c9d638b2e191a08ea1d6cc988eadd6ba5bdc053"
integrity sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=
dependencies:
follow-redirects "1.0.0"
axios@^0.20.0:
version "0.20.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd"
@ -4290,13 +4283,6 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
follow-redirects@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.0.0.tgz#8e34298cbd2e176f254effec75a1c78cc849fd37"
integrity sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=
dependencies:
debug "^2.2.0"
follow-redirects@^1.0.0, follow-redirects@^1.10.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
@ -9031,13 +9017,6 @@ vue@^3.0.0:
"@vue/runtime-dom" "3.0.0"
"@vue/shared" "3.0.0"
vuetable-2@^2.0.0-beta.4:
version "2.0.0-beta.4"
resolved "https://registry.yarnpkg.com/vuetable-2/-/vuetable-2-2.0.0-beta.4.tgz#474a28dfbf9372e88b34b0659f4b524bc19aa676"
integrity sha512-sWSdKIPYiATI9hOuPlQ09iSWEFAfhe6sPovl4hK2SemvqvgxLIF8UjG3LwJJC7idWS9UPpK9fRrSXoFJhRcluQ==
dependencies:
axios "^0.15.3"
watchpack-chokidar2@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"