Merge branch 'trunk'

This commit is contained in:
Jérémy Munsch 2021-10-22 14:03:40 +02:00
commit 63eec7eb34
No known key found for this signature in database
GPG key ID: 55196BEE445F6049
8 changed files with 1086 additions and 306 deletions

View file

@ -32,7 +32,18 @@ class Project extends Model
'validate' => [
'string',
'max:255',
'unique:sites,name'
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
$q = static::query();
if (request()->project) {
$q = $q->where('id', '!=', $this->id);
}
if ($q->where('name', $value)->exists()) {
$fail(__(':attribute est déjà utilisé', [
'attribute' => $attribute
]));
}
}
],
'required' => true,
'nullable' => false,

View file

@ -27,6 +27,10 @@ class Site extends Model
'description', 'todo'
];
protected $attributes = [
'status' => '',
];
public function __construct($attributes = [])
{
self::$editableProperties = [
@ -36,7 +40,18 @@ class Site extends Model
'validate' => [
'string',
'max:255',
'unique:sites,name'
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
$q = static::query();
if (request()->site) {
$q = $q->where('id', '!=', $this->id);
}
if ($q->where('name', $value)->exists()) {
$fail(__(':attribute est déjà utilisé', [
'attribute' => $attribute
]));
}
}
],
'required' => true,
'nullable' => false,
@ -54,8 +69,8 @@ class Site extends Model
'string',
'max:255'
],
'required' => true,
'nullable' => false,
'required' => false,
'nullable' => true, // n'est pas vraiment nullable en base
'actions' => [
CrudAction::view(),
CrudAction::create(),

View file

@ -15,7 +15,7 @@
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"kwaadpepper/crud-policies": "^0.1.20",
"kwaadpepper/crud-policies": "^0.1.22",
"kwaadpepper/enum": "^2.1",
"kwaadpepper/exception-handler": "^0.0.3",
"laravel-lang/lang": "~8.0",

1214
composer.lock generated

File diff suppressed because it is too large Load diff

13
package-lock.json generated
View file

@ -16,6 +16,7 @@
"resolve-url-loader": "^3.1.0",
"sass": "^1.15.2",
"sass-loader": "^8.0.0",
"toastify-js": "^1.11.2",
"vue": "^2.6.14",
"vue-loader": "^15.9.7",
"vue-select": "^3.13.0",
@ -9065,6 +9066,12 @@
"node": ">=8.0"
}
},
"node_modules/toastify-js": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.11.2.tgz",
"integrity": "sha512-bMBNKhZLPX/sDhpwM7KHIRUTtqCylQeoZDiEWy5zE7iDUJ92XmP8AKgDAp9rXx6pR5GXGFtQHHoH62toahbHgQ==",
"dev": true
},
"node_modules/toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@ -16776,6 +16783,12 @@
"is-number": "^7.0.0"
}
},
"toastify-js": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.11.2.tgz",
"integrity": "sha512-bMBNKhZLPX/sDhpwM7KHIRUTtqCylQeoZDiEWy5zE7iDUJ92XmP8AKgDAp9rXx6pR5GXGFtQHHoH62toahbHgQ==",
"dev": true
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",

View file

@ -21,6 +21,7 @@
"resolve-url-loader": "^3.1.0",
"sass": "^1.15.2",
"sass-loader": "^8.0.0",
"toastify-js": "^1.11.2",
"vue": "^2.6.14",
"vue-loader": "^15.9.7",
"vue-select": "^3.13.0",

View file

@ -30,9 +30,16 @@
</b>
<span v-else-if="!day[row.value]['text'].length">Rien</span><br>
{{ day[row.value]["text"] | str_limit(25) }}
<button class="btn btn-clear" @click="eraseCell(timestamp, row)">⌫</button>
<button class="btn btn-edit" type="button" data-bs-toggle="modal"
:data-bs-target="'#editModal'+currentWeek.id" @click="setModalData(timestamp, row)">✎</button>
<button :class="'btn btn-paste '+(!clipBoard.week ? 'hide' : '') " type="button"
@click="pasteCell(timestamp, row)">📋</button>
<button class="btn btn-copy" type="button"
@click="copyCell(timestamp, row)">
<span style="font-size: .875em; margin-right: .125em; position: relative; top: -.25em; left: -.125em">
📄<span style="position: absolute; top: .25em; left: .25em">📄</span>
</span></button>
<button class="btn btn-clear" @click="eraseCell(timestamp, row)">⌫</button>
</td>
</template>
</tr>
@ -117,17 +124,24 @@
</template>
<script>
import Toastify from 'toastify-js'
export default {
mounted() {
this.models = this.dbModels;
this.types = this.dbTypes;
this.rows = this.dbRows;
this.$set(this, 'currentWeek', this.dbCurrentWeek);
window.Toastify = Toastify
this.models = this.dbModels
this.types = this.dbTypes
this.rows = this.dbRows
this.$set(this, 'currentWeek', this.dbCurrentWeek)
this.search(false)
},
props: ["dbModels", "dbTypes", "dbRows", "dbCurrentWeek"],
data() {
return {
clipBoard: {
week: null,
timestamp: null,
row: null
},
textLimit: 90,
daysOfWeek: 5,
types: [],
@ -190,7 +204,57 @@ export default {
}
},
methods: {
sendToast(message) {
Toastify({
text: message,
duration: 3000,
gravity: "top",
position: "right",
offset: {
x: '2rem',
y: '3rem'
},
style: {
background: "linear-gradient(to right, #00317d, #0058ca)",
}
}).showToast();
},
clearClipBoard() {
this.clipBoard = {
week: null,
timestamp: null,
row: null
}
},
copyCell(timestamp, row) {
this.clipBoard = {
week: this.currentWeek.id,
timestamp: timestamp,
row: row
}
this.sendToast('Cellule copiée')
},
pasteCell(timestamp, row) {
const cell = this.currentWeek.planning[this.clipBoard.timestamp][this.clipBoard.row.value]
const data = {
'id': this.clipBoard.week,
'day': timestamp,
'type': cell.type,
'row': row.value,
'cellModel': cell.cellModel,
'foreign': cell.foreign,
'text': cell.text,
}
if(!data.text.length) {
this.eraseCell(timestamp, row)
return;
}
this.saveCellOnServer(timestamp, row.value, data)
this.clearClipBoard()
this.sendToast('Cellule collée')
},
eraseCell(timestamp, row) {
this.clearClipBoard()
this.setModalData(timestamp, row)
const data = {
'id': this.currentWeek.id,
@ -228,10 +292,16 @@ export default {
'foreign': this.value.value,
'text': this.$refs.text.value,
}
this.saveCellOnServer(this.currentTimestamp, this.currentRow.value, data)
},
saveCellOnServer(timestamp, row, data) {
this.error = false
axios.post(this.route('planning.setCellContent'), data)
.then(response => {
if(response.data.status) {
this.$set(this.currentWeek.planning[this.currentTimestamp], this.currentRow.value, {
console.log(this.currentWeek.planning[timestamp])
console.log(row)
this.$set(this.currentWeek.planning[timestamp], row, {
'type': data['type'],
'foreign': data['foreign'],
'cellModel': data['cellModel'],
@ -277,6 +347,15 @@ export default {
default: this.dDisplay = false
}
},
resetModalFields() {
this.$set(this, 'currentType' , null)
this.$set(this, 'value' , {
label: null,
value: null
})
this.$refs.type.value = ''
this.$refs.morph.value = ''
},
search (search = null) {
this.$nextTick(() => {
this.error = null
@ -357,10 +436,7 @@ export default {
this.$refs.text.value = cellData.text
this.$nextTick(() => {
let route = null
this.value = {
label: null,
value: null
}
this.resetModalFields()
switch(this.currentModel) {
case 'tickets':
this.dDisplay = true
@ -382,19 +458,6 @@ export default {
break
default: this.dDisplay = false
}
if(route) {
axios.get(route).then(response => {
this.value = response.data
}).catch(error => {
if(error.response.status === 429) {
location.reload()
}
this.error = error
}).then(() => {
this.loading = false
})
this.search()
}
})
},
limitLines(e) {
@ -420,6 +483,7 @@ export default {
</script>
<style lang="scss">
@import "toastify-js/src/toastify.css";
@import "vue-select/src/scss/vue-select.scss";
.planning {
overflow: auto;
@ -489,6 +553,9 @@ export default {
background-color: $buttonBgColor;
opacity: 0;
transition: 200ms opacity;
&.hide {
opacity: 0 !important;
}
&:hover,
&:focus {
background-color: darken($buttonBgColor, 10%);
@ -496,8 +563,18 @@ export default {
&.btn-clear {
color: darken($color: #fff, $amount: 5);
}
&:nth-last-child(2) {
right: inherit;
left: 0.1rem;
}
&:nth-last-child(3) {
right: inherit;
top: 2.1rem;
left: 0.1rem;
}
&:nth-last-child(1) {
right: 2.1rem;
top: 2.1rem;
right: 0.1rem;
}
}
}

View file

@ -31,7 +31,10 @@
<div class="container container-xxl">
<div class="row justify-content-center">
<div class="col-12 @yield('bodyClass')">
@if(!isset($modelClass))
{{-- Dont use for crud-policies --}}
@include('modules.flashMessage')
@endif
@yield('content')
</div>
</div>