Merge branch 'master' into patch-1
1103
composer.lock
generated
|
|
@ -66,7 +66,7 @@ return [
|
|||
'url' => 'usage',
|
||||
'children' => [
|
||||
'Creating Tenants' => 'creating-tenants',
|
||||
'Tenant Migrations'=> 'tenant-migrations',
|
||||
'Tenant Migrations' => 'tenant-migrations',
|
||||
'Tenant Routes' => 'tenant-routes',
|
||||
'Tenant Storage' => 'tenant-storage',
|
||||
'Tenant Manager' => 'tenant-manager',
|
||||
|
|
@ -205,6 +205,7 @@ return [
|
|||
'Nova' => 'integrations/nova',
|
||||
'Telescope' => 'integrations/telescope',
|
||||
'Livewire' => 'integrations/livewire',
|
||||
'Orchid' => 'integrations/orchid',
|
||||
],
|
||||
],
|
||||
'Console commands' => 'console-commands',
|
||||
|
|
|
|||
10
netlify.toml
|
|
@ -11,3 +11,13 @@ command = "npm run staging"
|
|||
from = "/docs/master/*"
|
||||
to = "/docs/v3/:splat"
|
||||
status = 302
|
||||
|
||||
[[redirects]]
|
||||
from = "/bee.js"
|
||||
to = "https://cdn.splitbee.io/sb.js"
|
||||
status = 200
|
||||
|
||||
[[redirects]]
|
||||
from = "/_hive/*"
|
||||
to = "https://hive.splitbee.io/:splat"
|
||||
status = 200
|
||||
|
|
|
|||
341
package-lock.json
generated
|
|
@ -1136,6 +1136,11 @@
|
|||
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
|
||||
"dev": true
|
||||
},
|
||||
"@splitbee/web": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@splitbee/web/-/web-0.3.0.tgz",
|
||||
"integrity": "sha512-jNPDKg0GQGa4jCaBc6JQsv0NHmBA80WCwZE49nFyhcbo32WF0GyqXeice7ZApy7OUHI16bAUAzm4MOQw3gvxfQ=="
|
||||
},
|
||||
"@tailwindcss/custom-forms": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/custom-forms/-/custom-forms-0.2.1.tgz",
|
||||
|
|
@ -5367,29 +5372,25 @@
|
|||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5399,15 +5400,13 @@
|
|||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5415,38 +5414,39 @@
|
|||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5455,36 +5455,40 @@
|
|||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5500,8 +5504,7 @@
|
|||
},
|
||||
"glob": {
|
||||
"version": "7.1.3",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5515,15 +5518,13 @@
|
|||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5532,8 +5533,7 @@
|
|||
},
|
||||
"ignore-walk": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5542,8 +5542,7 @@
|
|||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5553,22 +5552,19 @@
|
|||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5577,42 +5573,62 @@
|
|||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.2.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"needle": {
|
||||
"version": "2.3.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5623,8 +5639,7 @@
|
|||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.12.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5642,8 +5657,7 @@
|
|||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5653,15 +5667,13 @@
|
|||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.0.6",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.4.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5671,8 +5683,7 @@
|
|||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5684,22 +5695,19 @@
|
|||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5708,22 +5716,19 @@
|
|||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.5",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5733,22 +5738,19 @@
|
|||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5759,9 +5761,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
|
|
@ -5769,8 +5770,7 @@
|
|||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5785,8 +5785,7 @@
|
|||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.3",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5795,50 +5794,43 @@
|
|||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5849,8 +5841,7 @@
|
|||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5859,8 +5850,7 @@
|
|||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5869,22 +5859,34 @@
|
|||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"fs-minipass": "^1.2.5",
|
||||
"minipass": "^2.3.4",
|
||||
"minizlib": "^1.1.1",
|
||||
"mkdirp": "^0.5.0",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -5893,8 +5895,13 @@
|
|||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
|
|
@ -7443,8 +7450,8 @@
|
|||
}
|
||||
},
|
||||
"laravel-mix-jigsaw": {
|
||||
"version": "github:iskrisis/laravel-mix-jigsaw#7c81913bc5cb6f3c8ab238c97443f059182bce7f",
|
||||
"from": "github:iskrisis/laravel-mix-jigsaw",
|
||||
"version": "git+ssh://git@github.com/iskrisis/laravel-mix-jigsaw.git#7c81913bc5cb6f3c8ab238c97443f059182bce7f",
|
||||
"from": "laravel-mix-jigsaw@github:iskrisis/laravel-mix-jigsaw",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browser-sync": "^2.26.7",
|
||||
|
|
@ -8026,36 +8033,6 @@
|
|||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
|
||||
"integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minipass": "^2.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"mississippi": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
||||
|
|
@ -12387,62 +12364,6 @@
|
|||
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
|
||||
"dev": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.13",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
|
||||
"integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"fs-minipass": "^1.2.5",
|
||||
"minipass": "^2.8.6",
|
||||
"minizlib": "^1.2.1",
|
||||
"mkdirp": "^0.5.0",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-minipass": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
|
||||
"integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minipass": "^2.6.0"
|
||||
}
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcomb": {
|
||||
"version": "3.2.29",
|
||||
"resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
"sass": "^1.15.2",
|
||||
"sass-loader": "^7.1.0",
|
||||
"tailwindcss": "^1.4.6",
|
||||
"vue-template-compiler": "^2.5.21"
|
||||
"vue-template-compiler": "^2.5.21",
|
||||
"@splitbee/web": "^0.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"turbolinks": "^5.2.0"
|
||||
|
|
|
|||
16
source/_assets/js/extsb.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import splitbee from '@splitbee/web';
|
||||
|
||||
splitbee.init({
|
||||
scriptUrl: "https://tenancyforlaravel.com/bee.js",
|
||||
apiUrl: "https://tenancyforlaravel.com/_hive",
|
||||
})
|
||||
|
||||
window.auth = function (username) {
|
||||
if (! username) return window.location.replace('https://github.com/tenancy-for-laravel/saas-boilerplate');
|
||||
|
||||
splitbee.user.set({
|
||||
userId: username.substr(1),
|
||||
}).finally(() => {
|
||||
window.location.replace('https://github.com/tenancy-for-laravel/saas-boilerplate');
|
||||
});
|
||||
}
|
||||
|
|
@ -10,12 +10,21 @@
|
|||
<meta property="og:title" content="{{ $page->title ? $page->title . ' | ' : '' }}{{ $page->siteName }}"/>
|
||||
<meta property="og:description" content="{{ $page->description ?? $page->title }} | {{ $page->siteName }}"/>
|
||||
<meta property="og:url" content="{{ $page->getUrl() }}"/>
|
||||
<meta property="og:image" content="/assets/img/logo.png"/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="twitter:image" content="https://tenancyforlaravel.com/assets/img/logo.png"/>
|
||||
|
||||
<meta property="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:site" content="@samuelstancl">
|
||||
<meta property="twitter:title" content="{{ ($title ?? null) ? $title . ' | Tenancy for Laravel' : 'Tenancy for Laravel' }}">
|
||||
<meta name="twitter:image:alt" content="{{ $page->siteName }}">
|
||||
|
||||
<meta name="twitter:image" content="https://previewify.app/generate/templates/760/meta?url={{ $page->getUrl() }}">
|
||||
<meta property="og:image" content="https://previewify.app/generate/templates/760/meta?url={{ $page->getUrl() }}">
|
||||
|
||||
<meta name="previewify:overline" content="Tenancy for Laravel {{ $page->version() }}">
|
||||
<meta name="previewify:title" content="{{ $page->title ?: 'Documentation | Tenancy for Laravel' }}">
|
||||
<meta name="previewify:subtitle" content="Turn any Laravel application multi-tenant, automatically. No code changes needed.">
|
||||
<meta name="previewify:repository" content="stancl/tenancy">
|
||||
<meta name="previewify:image" content="https://tenancyforlaravel.com/assets/img/previewify-image.png">
|
||||
|
||||
<meta name="theme-color" content="#5850EC">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
|
|
@ -23,9 +32,6 @@
|
|||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
|
||||
<meta name="twitter:image:alt" content="{{ $page->siteName }}">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
|
||||
<meta name="docsearch:language" content="en" />
|
||||
<meta name="docsearch:version" content="{{ $page->version() }}" />
|
||||
|
||||
|
|
@ -54,6 +60,7 @@
|
|||
<link href="https://rsms.me/inter/inter.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="{{ mix('css/main.css', 'assets/build') }}">
|
||||
|
||||
<script async data-api="/_hive" src="/bee.js"></script>
|
||||
<script src="{{ mix('js/turbolinks.js', 'assets/build') }}"></script>
|
||||
|
||||
@if ($page->docsearchApiKey && $page->docsearchIndexName)
|
||||
|
|
@ -61,11 +68,15 @@
|
|||
@endif
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Code&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
[x-cloak] { display: none !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="font-sans antialiased">
|
||||
<div class="p-2">
|
||||
@include('_partials.header-docs')
|
||||
|
||||
|
||||
<main role="main" class="">
|
||||
<section class="px-6 py-4">
|
||||
<div class="grid grid-cols-8 gap-4">
|
||||
|
|
@ -104,6 +115,12 @@
|
|||
|
||||
@include('_partials.footer')
|
||||
|
||||
{{-- Banner --}}
|
||||
@unless(isset($banner) && $banner === false )
|
||||
@include('_partials.banner')
|
||||
@endunless
|
||||
{{-- /Banner --}}
|
||||
|
||||
@if ($page->docsearchApiKey && $page->docsearchIndexName)
|
||||
<script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js" data-turbolinks-eval="false"></script>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -37,6 +37,12 @@
|
|||
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
||||
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
|
||||
<title>{{ ($title ?? null) ? $title . ' | Tenancy for Laravel' : 'Tenancy for Laravel' }}</title>
|
||||
|
||||
<script async data-api="/_hive" src="/bee.js"></script>
|
||||
|
||||
<style>
|
||||
[x-cloak] { display: none !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="font-sans antialiased">
|
||||
|
||||
|
|
@ -55,6 +61,13 @@
|
|||
@include('_partials.footer')
|
||||
{{-- /Footer --}}
|
||||
|
||||
{{-- Banner --}}
|
||||
@unless(isset($banner) && $banner === false )
|
||||
@include('_partials.banner')
|
||||
@endunless
|
||||
{{-- /Banner --}}
|
||||
|
||||
<script src="{{ $page->baseUrl . mix('js/main.js', 'assets/build') }}"></script>
|
||||
@stack('scripts')
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
@if ($url = is_string($item) ? $item : $item->url)
|
||||
<a href="{{ $page->isUrl($url) ? $url : $page->link($url) }}"
|
||||
class="{{ 'lvl' . $level }} {{ $page->isActiveParent($item) ? 'lvl' . $level . '-active' : '' }} {{ $page->isActive($url) ? 'active' : '' }} nav-menu__item"
|
||||
@if(\Illuminate\Support\Str::contains($url, 'saas-boilerplate')) data-splitbee-event="Click sidebar CTA" @endif
|
||||
>
|
||||
{{ $label }}
|
||||
</a>
|
||||
|
|
|
|||
41
source/_partials/banner.blade.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<div x-cloak class="z-50 fixed bottom-0 inset-x-0 pb-2 sm:pb-5" x-data="{ show: true, hide() { window.localStorage.show_banner = 'hide'; this.show = false } }" x-init="
|
||||
show = window.localStorage.show_banner !== 'hide'
|
||||
" x-show="show">
|
||||
<div class="max-w-screen-xl mx-auto px-2 sm:px-6 lg:px-8">
|
||||
<div class="p-2 rounded-lg bg-indigo-600 shadow-lg sm:p-3">
|
||||
<div class="flex items-center justify-between flex-wrap">
|
||||
<div class="w-0 flex-1 flex items-center">
|
||||
<span class="flex p-2 rounded-lg bg-indigo-800">
|
||||
<!-- Heroicon name: speakerphone -->
|
||||
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5.882V19.24a1.76 1.76 0 01-3.417.592l-2.147-6.15M18 13a3 3 0 100-6M5.436 13.683A4.001 4.001 0 017 6h1.832c4.1 0 7.625-1.234 9.168-3v14c-1.543-1.766-5.067-3-9.168-3H7a3.988 3.988 0 01-1.564-.317z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<p class="ml-3 font-medium text-white truncate">
|
||||
<span class="md:hidden text-brown-900">
|
||||
Save time with our SaaS application template.
|
||||
</span>
|
||||
<span class="hidden md:inline text-brown-900">
|
||||
Want to save time? Get our multi-tenant SaaS application template.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="order-3 mt-2 flex-shrink-0 w-full sm:order-2 sm:mt-0 sm:w-auto">
|
||||
<a href="https://tenancyforlaravel.com/saas-boilerplate/" data-splitbee-event="Click banner CTA" class="w-full inline-flex space-x-2 justify-center py-2 px-4 rounded-md bg-white text-sm font-medium hover:bg-gray-50">
|
||||
<span class="font-medium text-brown-900">
|
||||
SaaS boilerplate
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="order-2 flex-shrink-0 sm:order-3 sm:ml-2">
|
||||
<button @click="hide()" type="button" class="-mr-1 flex p-2 rounded-md hover:bg-indigo-500 focus:outline-none focus:bg-indigo-500 transition ease-in-out duration-150" aria-label="Dismiss">
|
||||
<!-- Heroicon name: x -->
|
||||
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,141 +1,141 @@
|
|||
<div class="bg-gray-900">
|
||||
<div class="max-w-screen-xl px-4 py-12 mx-auto sm:px-6 lg:py-16 lg:px-8">
|
||||
<div class="xl:grid xl:grid-cols-3 xl:gap-8">
|
||||
<div class="grid grid-cols-2 gap-8 xl:col-span-2">
|
||||
<div class="md:grid md:grid-cols-2 md:gap-8">
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Documentation
|
||||
</h4>
|
||||
<ul class="mt-4">
|
||||
<li>
|
||||
<a href="/docs/v3/tenants" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Tenants
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/event-system" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Event system
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/configuration" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Configuration
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mt-12 md:mt-0">
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Documentation
|
||||
</h4>
|
||||
<ul class="mt-4">
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/package-comparison" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Compared to other packages
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/integrating" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Integrations
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/tenant-identification" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Tenant identification
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md:grid md:grid-cols-2 md:gap-8">
|
||||
<div class="">
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Business
|
||||
</h4>
|
||||
<ul class="mt-4">
|
||||
<li>
|
||||
<a href="/saas-boilerplate" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
SaaS boilerplate
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/contact" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Consulting
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/contact" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Audits
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mt-12 md:mt-0">
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Links
|
||||
</h4>
|
||||
<ul class="mt-4">
|
||||
<li>
|
||||
<a href="/branding" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Branding
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="https://github.com/stancl/tenancy" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
GitHub
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="https://discord.gg/7cpgPxv" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Discord
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/donate" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Donate
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 xl:mt-0">
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Subscribe to our newsletter
|
||||
</h4>
|
||||
<p class="mt-4 text-base leading-6 text-gray-300">
|
||||
Receive notifications about important releases, new packages and other updates.
|
||||
</p>
|
||||
<form action="https://github.us3.list-manage.com/subscribe/post?u=6a33c422777aedd88e9a9488e&id=9b99f013b8" method="post" target="_blank" class="mt-4 sm:flex sm:max-w-md">
|
||||
<input name="EMAIL" aria-label="Email address" type="email" required class="w-full px-5 py-3 text-base leading-6 text-gray-900 placeholder-gray-500 transition duration-150 ease-in-out bg-white border border-transparent rounded-md appearance-none focus:outline-none focus:placeholder-gray-400" placeholder="Enter your email" />
|
||||
<input type="hidden" value="8" name="group[27425][8]" id="mce-group[27425]-27425-3">
|
||||
<div class="mt-3 rounded-md shadow sm:mt-0 sm:ml-3 sm:flex-shrink-0">
|
||||
<button class="flex items-center justify-center w-full px-5 py-3 text-base font-medium leading-6 text-white transition duration-150 ease-in-out bg-indigo-600 border border-transparent rounded-md hover:bg-indigo-500 focus:outline-none focus:bg-indigo-500">
|
||||
Subscribe
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-8 mt-8 border-t border-gray-700 md:flex md:items-center md:justify-between">
|
||||
<div class="flex md:order-2">
|
||||
<a href="https://twitter.com/samuelstancl" class="ml-6 text-gray-400 hover:text-gray-300">
|
||||
<span class="sr-only">Twitter</span>
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://github.com/stancl/tenancy" class="ml-6 text-gray-400 hover:text-gray-300">
|
||||
<span class="sr-only">GitHub</span>
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<p class="mt-8 text-base leading-6 text-gray-400 md:mt-0 md:order-1">
|
||||
© 2020 Samuel Štancl. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="max-w-screen-xl px-4 py-12 mx-auto sm:px-6 lg:py-16 lg:px-8">
|
||||
<div class="xl:grid xl:grid-cols-3 xl:gap-8">
|
||||
<div class="grid grid-cols-2 gap-8 xl:col-span-2">
|
||||
<div class="md:grid md:grid-cols-2 md:gap-8">
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Documentation
|
||||
</h4>
|
||||
<ul class="mt-4">
|
||||
<li>
|
||||
<a href="/docs/v3/tenants" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Tenants
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/event-system" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Event system
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/configuration" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Configuration
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mt-12 md:mt-0">
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Documentation
|
||||
</h4>
|
||||
<ul class="mt-4">
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/package-comparison" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Compared to other packages
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/integrating" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Integrations
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/docs/v3/tenant-identification" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Tenant identification
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md:grid md:grid-cols-2 md:gap-8">
|
||||
<div class="">
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Business
|
||||
</h4>
|
||||
<ul class="mt-4">
|
||||
<li>
|
||||
<a href="/saas-boilerplate" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
SaaS boilerplate
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/contact" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Consulting
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/contact" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Audits
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mt-12 md:mt-0">
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Links
|
||||
</h4>
|
||||
<ul class="mt-4">
|
||||
<li>
|
||||
<a href="/branding" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Branding
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="https://github.com/stancl/tenancy" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
GitHub
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="https://discord.gg/7cpgPxv" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Discord
|
||||
</a>
|
||||
</li>
|
||||
<li class="mt-4">
|
||||
<a href="/donate" class="text-base leading-6 text-gray-300 hover:text-white">
|
||||
Donate
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 xl:mt-0">
|
||||
<h4 class="text-sm font-semibold leading-5 tracking-wider text-gray-400 uppercase">
|
||||
Subscribe to our newsletter
|
||||
</h4>
|
||||
<p class="mt-4 text-base leading-6 text-gray-300">
|
||||
Receive notifications about important releases, new packages and other updates.
|
||||
</p>
|
||||
<form action="https://github.us3.list-manage.com/subscribe/post?u=6a33c422777aedd88e9a9488e&id=9b99f013b8" method="post" target="_blank" class="mt-4 sm:flex sm:max-w-md">
|
||||
<input name="EMAIL" aria-label="Email address" type="email" required class="w-full px-5 py-3 text-base leading-6 text-gray-900 placeholder-gray-500 transition duration-150 ease-in-out bg-white border border-transparent rounded-md appearance-none focus:outline-none focus:placeholder-gray-400" placeholder="Enter your email" />
|
||||
<input type="hidden" value="8" name="group[27425][8]" id="mce-group[27425]-27425-3">
|
||||
<div class="mt-3 rounded-md shadow sm:mt-0 sm:ml-3 sm:flex-shrink-0">
|
||||
<button class="flex items-center justify-center w-full px-5 py-3 text-base font-medium leading-6 text-white transition duration-150 ease-in-out bg-indigo-600 border border-transparent rounded-md hover:bg-indigo-500 focus:outline-none focus:bg-indigo-500">
|
||||
Subscribe
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-8 mt-8 border-t border-gray-700 md:flex md:items-center md:justify-between">
|
||||
<div class="flex md:order-2">
|
||||
<a href="https://twitter.com/samuelstancl" class="ml-6 text-gray-400 hover:text-gray-300">
|
||||
<span class="sr-only">Twitter</span>
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://github.com/stancl/tenancy" class="ml-6 text-gray-400 hover:text-gray-300">
|
||||
<span class="sr-only">GitHub</span>
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<p class="mt-8 text-base leading-6 text-gray-400 md:mt-0 md:order-1">
|
||||
Made by <a class="text-base leading-6 text-gray-300 hover:text-white" href="https://archte.ch">ArchTech</a>. © {{ date('Y') }} All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@
|
|||
<div class="rounded-lg shadow-lg">
|
||||
<div class="overflow-hidden rounded-lg shadow-xs">
|
||||
<div class="sm:gap-8 sm:p-8 relative z-20 grid gap-6 px-5 py-6 bg-white">
|
||||
<a href="/saas-boilerplate" class="hover:bg-gray-50 block p-3 -m-3 space-y-1 transition duration-150 ease-in-out rounded-md">
|
||||
<a href="/saas-boilerplate" data-splitbee-event="Click header CTA" class="hover:bg-gray-50 block p-3 -m-3 space-y-1 transition duration-150 ease-in-out rounded-md">
|
||||
<p class="text-base font-medium leading-6 text-gray-900">
|
||||
SaaS boilerplate
|
||||
</p>
|
||||
|
|
@ -184,6 +184,40 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div x-data="{ flyoutMenuOpen: false }" @click.away="flyoutMenuOpen = false" class="relative">
|
||||
<button type="button" @click="flyoutMenuOpen = !flyoutMenuOpen" x-state:on="Item active" x-state:off="Item inactive" :class="{ 'text-gray-900': flyoutMenuOpen, 'text-gray-500': !flyoutMenuOpen }" class="group hover:text-gray-900 focus:outline-none focus:text-gray-900 inline-flex items-center space-x-2 text-base font-medium leading-6 text-gray-500 transition duration-150 ease-in-out">
|
||||
<span>Learn
|
||||
</span>
|
||||
<svg x-state:on="Item active" x-state:off="Item inactive" class="group-hover:text-gray-500 group-focus:text-gray-500 w-5 h-5 text-gray-400 transition duration-150 ease-in-out" x-bind:class="{ 'text-gray-600': flyoutMenuOpen, 'text-gray-400': !flyoutMenuOpen }" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div x-description="'Learn' flyout menu, show/hide based on flyout menu state." x-show="flyoutMenuOpen" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 translate-y-1" x-transition:enter-end="opacity-100 translate-y-0" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 translate-y-0" x-transition:leave-end="opacity-0 translate-y-1" class="left-1/2 sm:px-0 absolute w-screen max-w-xs px-2 mt-3 transform -translate-x-1/2" style="display: none;">
|
||||
<div class="rounded-lg shadow-lg">
|
||||
<div class="overflow-hidden rounded-lg shadow-xs">
|
||||
<div class="sm:gap-8 sm:p-8 relative z-20 grid gap-6 px-5 py-6 bg-white">
|
||||
<a href="https://codecourse.com/courses/laravel-multi-tenancy-basics" target="_blank" class="hover:bg-gray-50 block p-3 -m-3 space-y-1 transition duration-150 ease-in-out rounded-md">
|
||||
<p class="text-base font-medium leading-6 text-gray-900">
|
||||
Video course
|
||||
</p>
|
||||
<p class="text-sm leading-5 text-gray-500">
|
||||
A video course explaining how to create multi-database, subdomain separated tenants using this package.
|
||||
</p>
|
||||
</a>
|
||||
<a href="https://airtable.com/shrUpJo4jp6Cw4ER3" target="_blank" class="hover:bg-gray-50 block p-3 -m-3 space-y-1 transition duration-150 ease-in-out rounded-md">
|
||||
<p class="text-base font-medium leading-6 text-gray-900">
|
||||
Book
|
||||
</p>
|
||||
<p class="text-sm leading-5 text-gray-500">
|
||||
A book going through the practical aspects of developing and running a multi-tenant application using this package.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a target="_blank" href="https://github.com/stancl/tenancy" class="hidden xl:inline hover:text-gray-900 focus:outline-none focus:text-gray-900 text-base font-medium leading-6 text-gray-500 transition duration-150 ease-in-out">
|
||||
GitHub
|
||||
</a>
|
||||
|
|
@ -281,7 +315,7 @@
|
|||
</div>
|
||||
<div class="px-5 py-6 space-y-6">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<a href="/saas-boilerplate" class="hover:text-gray-700 text-base font-medium leading-6 text-gray-900 transition duration-150 ease-in-out">
|
||||
<a href="/saas-boilerplate" data-splitbee-event="Click header CTA" class="hover:text-gray-700 text-base font-medium leading-6 text-gray-900 transition duration-150 ease-in-out">
|
||||
SaaS boilerplate
|
||||
</a>
|
||||
<a href="/contact" class="hover:text-gray-700 text-base font-medium leading-6 text-gray-900 transition duration-150 ease-in-out">
|
||||
|
|
@ -316,4 +350,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<footer class="mt-8">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0 inline-flex rounded-full border-2 border-white">
|
||||
<img class="h-12 w-12 rounded-full" src="https://media-exp1.licdn.com/dms/image/C5603AQEmispANTVYDA/profile-displayphoto-shrink_200_200/0?e=1600905600&v=beta&t=5D91f-juRO3AYIN-0qvGM1bUwg0PlwIDgG9bdol9Qwc" alt="Jørgen Solli" />
|
||||
<img class="h-12 w-12 rounded-full" src="https://avatars0.githubusercontent.com/u/14874283?s=460&u=87dea255b58f176fe041101381fbac5815379d2e&v=4" alt="Jørgen Solli" />
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<div class="text-base leading-6 font-medium text-gray-900">Jørgen Solli
|
||||
|
|
|
|||
2
source/assets/build/js/extsb.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=2)}({2:function(e,t,n){e.exports=n("j7ye")},j7ye:function(e,t,n){"use strict";n.r(t);var r="undefined"!=typeof window,o=[],i=function(){r&&!window.splitbee||(a.track=window.splitbee.track,a.user=window.splitbee.user,a.enableCookie=window.splitbee.enableCookie,a.reset=window.splitbee.reset,o.forEach((function(e){"track"===e.type?window.splitbee.track.apply(null,e.payload):"user"===e.type?window.splitbee.user.set.apply(null,e.payload):"enableCookie"===e.type?window.splitbee.enableCookie.apply(null,e.payload):"reset"===e.type&&window.splitbee.reset()})),o=[])},l=function(e){return function(){try{for(var t=arguments.length,n=new Array(t),l=0;l<t;l++)n[l]=arguments[l];return o.push({type:e,payload:n}),r&&window.splitbee&&i(),Promise.resolve()}catch(e){return Promise.reject(e)}}},a={track:l("track"),user:{set:l("user")},init:function(e){if(r&&!window.splitbee){var t=window.document,n=null!=e&&e.scriptUrl?e.scriptUrl:"https://cdn.splitbee.io/sb.js",o=t.querySelector("script[src='"+n+"']");if(o)o.onload=i;else{var l=t.createElement("script");l.src=n,l.async=!0,e&&(e.apiUrl&&(l.dataset.api=e.apiUrl),e.token&&(l.dataset.token=e.token),e.disableCookie&&(l.dataset.noCookie="1")),l.onload=i,t.head.appendChild(l)}}},enableCookie:l("enableCookie"),reset:l("reset")},s=a;s.init({scriptUrl:"https://tenancyforlaravel.com/bee.js",apiUrl:"https://tenancyforlaravel.com/_hive"}),window.auth=function(e){e&&s.user.set({userId:e.substr(1)}).finally((function(){window.location.replace("https://github.com/tenancy-for-laravel/saas-boilerplate")}))}}});
|
||||
//# sourceMappingURL=extsb.js.map
|
||||
1
source/assets/build/js/extsb.js.map
Normal file
1
source/assets/build/js/turbolinks.js.map
Normal file
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 46 KiB |
BIN
source/assets/img/previewify-image-1.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
source/assets/img/previewify-image-2.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
source/assets/img/previewify-image.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -11,7 +11,7 @@
|
|||
You can contact us if you need consulting, want to have your implementation audited, or want to discuss something.
|
||||
</p>
|
||||
<p class="mt-4 text-lg leading-6 text-gray-500">
|
||||
You can also use email: <a class="text-indigo-700" href="mailto:samuel@tenancyforlaravel.com">samuel@tenancyforlaravel.com</a>.
|
||||
You can also use email: <a class="text-indigo-700" href="mailto:tenancy@archte.ch">tenancy@archte.ch</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-12">
|
||||
|
|
@ -62,4 +62,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ You can run migrations from outside the command line as well. To run migrations
|
|||
$tenant = \Tenant::create('tenant1.localhost');
|
||||
|
||||
\Artisan::call('tenants:migrate', [
|
||||
'--tenants' => [$tenant->id];
|
||||
'--tenants' => [$tenant->id]
|
||||
]);
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ If you wish to use autoincrement ids instead of uuids:
|
|||
|
||||
1. set this config key to null, or create a custom tenant model that doesn't use this trait
|
||||
2. update the `tenants` table migration to use an incrementing column type instead of `string`
|
||||
3. update the `domains` table migration `tenant_id` column to the same type as `tenants` id
|
||||
|
||||
### Domain model {#domain-model}
|
||||
|
||||
|
|
@ -80,7 +81,7 @@ See this section in the config, it's documented with comments.
|
|||
|
||||
`tenancy.filesystem.*`
|
||||
|
||||
This section is relevant to cache separation, specifically, to the `FilesystemTenancyBootstrapper`.
|
||||
This section is relevant to storage separation, specifically, to the `FilesystemTenancyBootstrapper`.
|
||||
|
||||
See this section in the config, it's documented with comments.
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ Note that you don't want to grant the users the ability to grant themselves more
|
|||
|
||||
## Specifying template connections {#specifying-the-template-connections}
|
||||
|
||||
> **Important:** there should be no `tenant` connection in `config/database.php`. If you create a template connection for tenants, name it something like `tenant_template`. The `tenant` connection is entirely managed by the package and gets reset to `null` when tenancy is ended.
|
||||
|
||||
To specify the connection that should be used to construct this tenant's database connection (the array like you'd find in `config/database.php`, set the `tenancy_db_connection` key. Otherwise, the connection whose name is in the `tenancy.database.template_connection` config will be used. If that key is null, the central connection will be used.
|
||||
|
||||
## Specifying other connection details {#specifyng-other-connection-details}
|
||||
|
|
@ -62,4 +64,4 @@ You may also set specific connection details without necessarily creating a new
|
|||
- optionally, the username and password
|
||||
- all `tenancy_db_*` keys
|
||||
|
||||
This means that you can store a value for e.g. `tenancy_db_charset` if you want to specify the charset for the tenant's database connection for whatever reason.
|
||||
This means that you can store a value for e.g. `tenancy_db_charset` if you want to specify the charset for the tenant's database connection for whatever reason.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ $tenant->domains()->create([
|
|||
]);
|
||||
```
|
||||
|
||||
If you use the subdomain identification middleware, the example above will work for `acme.{any of your central domains}`. If you use the domain identification middleware, use the full hostname like `acme.com`. If you use the combined domain/subdomain identification middleware, `acme` will work as a subdomain and `acme.com` will work as a domain.
|
||||
If you use the subdomain identification middleware, the example above will work for `acme.{any of your central domains}`. If you use the domain identification middleware, use the full hostname like `acme.com`. If you use the combined domain/subdomain identification middleware, you should use both `acme` as a subdomain and `acme.com` for the domain.
|
||||
|
||||
Note that starting with Laravel 8 and up, Laravel TrustHost middleware is enabled by default (see [laravel/laravel#5477](https://github.com/laravel/laravel/pull/5477)). This blocks Domain-based tenant identification since these requests will be treated as 'untrusted' unless added as a trusted host. You can either comment out this middleware in your App\Http\Kernel.php, or you can add the custom tenant domains in the App\Http\Middleware\TrustHosts.php `hosts()` method.
|
||||
|
||||
To retrieve the current domain model (when using domain identification), you may access the `$currentDomain` public static property on `DomainTenantResolver`.
|
||||
|
||||
|
|
@ -24,4 +26,4 @@ To retrieve the current domain model (when using domain identification), you may
|
|||
|
||||
For local development, you may use `*.localhost` domains (like `foo.localhost`) for tenants. On many operating systems, these work the same way as `localhost`.
|
||||
|
||||
If you're using Valet, you may want to use e.g. `saas.test` for the central domain and `foo.saas.test`, `bar.saas.test` etc for tenant domains.
|
||||
If you're using Valet, you may want to use e.g. `saas.test` for the central domain and `foo.saas.test`, `bar.saas.test` etc for tenant domains. Alternatively, if you want to use **multiple second-level domains**, you can use the `valet link` command to attach additional domains to the project. For example: `valet link bar.test`
|
||||
|
|
|
|||
|
|
@ -12,4 +12,10 @@ Sometimes you may want to redirect the user to a specific route on a different d
|
|||
|
||||
```php
|
||||
return redirect()->route('home')->domain($domain);
|
||||
```
|
||||
```
|
||||
|
||||
You can also use the `tenant_route()` helper to redirect users to another domain.
|
||||
|
||||
```php
|
||||
return redirect(tenant_route($domain, 'home'));
|
||||
```
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ Uncomment the following line in your `tenancy.features` config:
|
|||
|
||||
## **Configuring the mappings** {#configuring-the-mappings}
|
||||
|
||||
This feature maps keys in the tenant storage to config keys based on the `$storageToConfigMap` public property.
|
||||
This feature maps keys in the tenant storage to config keys based on the `$storageToConfigMap` [static property]({{ $page->link('configuration#static-properties') }}).
|
||||
|
||||
For example, if your `$storageToConfigMap` looked like this:
|
||||
|
||||
```php
|
||||
\Stancl\Tenancy\Features\TenantConfig::$storageToConfigMap = [
|
||||
'paypal_api_key' => 'services.paypal.api_key',
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
the value of `paypal_api_key` in tenant model would be copied to the `services.paypal.api_key` config when tenancy is initialized.
|
||||
|
|
@ -45,5 +45,5 @@ Sometimes you may want to copy the value to multiple config keys. To do that, sp
|
|||
'app.locale',
|
||||
'locales.default',
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ section: content
|
|||
|
||||
# Installation {#installation}
|
||||
|
||||
Laravel 6.0 or higher is needed.
|
||||
|
||||
Require the package using composer:
|
||||
|
||||
```php
|
||||
|
|
@ -39,4 +41,4 @@ App\Providers\RouteServiceProvider::class,
|
|||
App\Providers\TenancyServiceProvider::class, // <-- here
|
||||
```
|
||||
|
||||
And finally, name your central connection (in `config/database.php`) `central` — or however else you want, but make sure it's the same name as the `tenancy.central_connection` config.
|
||||
And finally, if you want to use a different central database than the one defined by `DB_CONNECTION` in the file `.env`, name your central connection (in `config/database.php`) `central` — or however else you want, but make sure it's the same name as the `tenancy.central_connection` config.
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ to this:
|
|||
],
|
||||
```
|
||||
|
||||
(Don't forget to import the middleware class.)
|
||||
|
||||
Now you can use Livewire both in the central app and the tenant app.
|
||||
|
||||
Also make sure to enable [universal routes]({{ $page->link('features/universal-routes') }}).
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ To use Nova inside of the tenant part of your application, do the following:
|
|||
|
||||
- Prevent Nova from adding its migrations to your central migrations by adding `Nova::ignoreMigrations()` to `NovaServiceProvider::boot()` (Don't do this if you want to use Nova **[both in the central & tenant parts]({{ $page->link('features/universal-routes') }})** of the app.)
|
||||
- Add the tenancy middleware to your `nova.middleware` config. Example:
|
||||
|
||||
```php
|
||||
'middleware' => [
|
||||
// You can make this simpler by creating a tenancy route group
|
||||
|
|
|
|||
54
source/docs/v3/integrations/orchid.blade.md
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
title: Laravel Orchid integration
|
||||
extends: _layouts.documentation
|
||||
section: content
|
||||
---
|
||||
|
||||
# Laravel Orchid {#laravel-orchid}
|
||||
|
||||
The instruction is written for a newly installed Orchid platform, it is proposed to use the platform as a central application and the tenant app.
|
||||
|
||||
## Both in the central app and the tenant app
|
||||
|
||||
Laravel Orchid has already been installed according to the [documentation Orchid](https://orchid.software/en/docs/installation/). All the steps have also been completed [Quickstart Tutorial](/docs/v3/quickstart).
|
||||
|
||||
- To use Orchid both in the central & tenant parts you need to enable [Universal Routes]({{ $page->link('features/universal-routes') }}).
|
||||
- Add the tenancy middleware to your `config\platform.php`
|
||||
|
||||
```php
|
||||
'middleware' => [
|
||||
'public' => ['web', 'universal', \Stancl\Tenancy\Middleware\InitializeTenancyByDomain::class],
|
||||
'private' => ['web', 'platform', 'universal', \Stancl\Tenancy\Middleware\InitializeTenancyByDomain::class],
|
||||
],
|
||||
```
|
||||
|
||||
- Add a route to `routes\platform.php`
|
||||
|
||||
```php
|
||||
Route::screen('/', PlatformScreen::class)
|
||||
->name('platform.index')
|
||||
->breadcrumbs(function (Trail $trail) {
|
||||
return $trail->push(__('Home'), route('platform.index'));
|
||||
});
|
||||
```
|
||||
|
||||
- In the file `app\Providers\RouteServiceProvider.php`, if necessary, change the path to the "home" route for your central application. By default for Orchid it will be `'admin/main'`
|
||||
|
||||
```php
|
||||
public const HOME = 'admin/main';
|
||||
```
|
||||
|
||||
- Tenant Routes `routes\tenant.php`
|
||||
|
||||
```php
|
||||
Route::middleware([
|
||||
'web',
|
||||
'platform',
|
||||
InitializeTenancyByDomain::class,
|
||||
PreventAccessFromCentralDomains::class,
|
||||
])->prefix(Orchid\Platform\Dashboard::prefix('/'))->group(function () {
|
||||
Route::get('/', function () {
|
||||
return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
|
@ -22,14 +22,50 @@ To use Passport inside the tenant part of your application, you may do the follo
|
|||
PreventAccessFromCentralDomains::class,
|
||||
]]);
|
||||
```
|
||||
|
||||
- Add this to `boot` method in your `AppServiceProvider`:
|
||||
|
||||
```php
|
||||
Passport::loadKeysFrom(base_path(config('passport.key_path')));
|
||||
```
|
||||
|
||||
- `php artisan vendor:publish --tag=passport-migrations` & move to `database/migrations/tenant/` directory
|
||||
|
||||
- Create `passport.php` file in your config directory and add database connection and key path config. This makes passport use the default connection.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'storage' => [
|
||||
'database' => [
|
||||
'connection' => null,
|
||||
],
|
||||
],
|
||||
'key_path' => env('OAUTH_KEY_PATH', 'storage')
|
||||
|
||||
];
|
||||
```
|
||||
|
||||
You may set the OAUTH_KEY_PATH in your .env, but by default `passport:keys` puts them in `storage/` directory
|
||||
|
||||
## **Shared keys**
|
||||
|
||||
If you want to use the same keypair for all tenants, do the following.
|
||||
|
||||
- Don't use `passport:install`, use just `passport:keys`. The install command creates keys & two clients. Instead of creating clients centrally, create `Client`s manually in your [tenant database seeder]({{ $page->link('configuration#seeder-params') }}).
|
||||
- Don't use `passport:install`, use just `passport:keys`. The install command creates keys & two clients. Instead of creating clients centrally, create `Client`s manually in your [tenant database seeder]({{ $page->link('configuration#seeder-params') }}), like this:
|
||||
|
||||
```php
|
||||
public function run()
|
||||
{
|
||||
$client = new ClientRepository();
|
||||
|
||||
$client->createPasswordGrantClient(null, 'Default password grant client', 'http://your.redirect.path');
|
||||
$client->createPersonalAccessClient(null, 'Default personal access client', 'http://your.redirect.path');
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## **Tenant-specific keys** {#tenant-specific-keys}
|
||||
|
||||
|
|
@ -51,7 +87,25 @@ And again, you need to create clients in your tenant database seeding process.
|
|||
|
||||
## Using Passport in both the central & tenant app {#using-passport-in-both-the-central-and-tenant-app}
|
||||
|
||||

|
||||
To use Passport on central and tenant application, you may apply the following changes.
|
||||
|
||||
- Remove this from the `register` method in your `AppServiceProvider` if you added it previously:
|
||||
|
||||
```php
|
||||
Passport::ignoreMigrations();
|
||||
```
|
||||
|
||||
- Configure `Passport routes` on the `register` method in your `AppServiceProvider` as follows:
|
||||
|
||||
```php
|
||||
Passport::routes(null, ['middleware' => [
|
||||
'universal',
|
||||
InitializeTenancyByDomain::class
|
||||
]]);
|
||||
```
|
||||
|
||||
- Make a copy of `Passport migrations` to `database/migrations/tenant/` directory
|
||||
|
||||
|
||||
And make sure you enable the *Universal Routes* feature.
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Multi-tenancy is the ability to provide your service to multiple users (tenants)
|
|||
|
||||
You may find this talk insightful: [https://multitenantlaravel.com/](https://multitenantlaravel.com/). Simply going through the slides will give you 80% of the value of the talk in under five minutes.
|
||||
|
||||
Note that if you just want to, say, scope todo tasks to the current user, there's no need to use a multi-tenancy package. Just use calls like `auth()->user()->tasks()`. This is the simplest for of multi-tenancy.
|
||||
Note that if you just want to, say, scope todo tasks to the current user, there's no need to use a multi-tenancy package. Just use calls like `auth()->user()->tasks()`. This is the simplest form of multi-tenancy.
|
||||
|
||||
This package is built around the idea that multi-tenancy usually means letting tenants have their own users which have their own resources, e.g. todo tasks. Not just users having tasks.
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ If you're using the `QueueTenancyBootstrapper`, queued jobs dispatched from the
|
|||
|
||||
**However**, note that if you're using the `DatabaseTenancyBootstrapper` and the `database` queue driver, or the `RedisTenancyBootstrapper` and the `redis` queue driver, you will need to make sure the jobs don't get dispatched into the tenant context for these drivers.
|
||||
|
||||
Note: You cannot inject model **instances** with the `SerializesModels` trait, because it tries to hydrate the models before the `tenant` connection is created. Inject model ids instead and use `find()` in the handle method.
|
||||
|
||||
### Database queue driver {#database-queue-driver}
|
||||
|
||||
To force the database queue driver to use the central connection, open your `queue.connections.database` config and add the following line:
|
||||
|
|
@ -35,11 +33,11 @@ To dispatch a job such that it will run centrally under all circumstances, creat
|
|||
```jsx
|
||||
// queue.connections
|
||||
'central' => [
|
||||
'driver' => 'database',
|
||||
'driver' => 'database',
|
||||
'table' => 'jobs',
|
||||
'queue' => 'default',
|
||||
'retry_after' => 90,
|
||||
'central' => true, // <---
|
||||
'central' => true, // <---
|
||||
],
|
||||
```
|
||||
|
||||
|
|
@ -47,4 +45,4 @@ And use this connection like this:
|
|||
|
||||
```jsx
|
||||
dispatch(new SomeJob(...))->onConnection('central');
|
||||
```
|
||||
```
|
||||
|
|
|
|||
|
|
@ -48,12 +48,12 @@ App\Providers\TenancyServiceProvider::class, // <-- here
|
|||
|
||||
## Creating a tenant model {#creating-a-tenant-model}
|
||||
|
||||
Now you need to create a Tenant model. The package comes with a default Tenant model that has many features, but it attempts to be mostly unopinonated and as such, we need to create a custom model to use domains & databases. Create `App\Tenant` like this:
|
||||
Now you need to create a Tenant model. The package comes with a default Tenant model that has many features, but it attempts to be mostly unopinonated and as such, we need to create a custom model to use domains & databases. Create the file `app/Models/Tenant.php` like this:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
namespace App\Models;
|
||||
|
||||
use Stancl\Tenancy\Database\Models\Tenant as BaseTenant;
|
||||
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
||||
|
|
@ -66,12 +66,12 @@ class Tenant extends BaseTenant implements TenantWithDatabase
|
|||
}
|
||||
```
|
||||
|
||||
Now we need to tell the package to use this custom model:
|
||||
*Please note: if you have the models anywhere else, you should adjust the code and commands of this tutorial accordingly.*
|
||||
|
||||
Now we need to tell the package to use this custom model. Open the `config/tenancy.php` file and modify the line below:
|
||||
|
||||
```php
|
||||
// config/tenancy.php
|
||||
|
||||
'tenant_model' => \App\Tenant::class,
|
||||
'tenant_model' => \App\Models\Tenant::class,
|
||||
```
|
||||
|
||||
## Events {#events}
|
||||
|
|
@ -112,7 +112,7 @@ protected function centralDomains(): array
|
|||
}
|
||||
```
|
||||
|
||||
If you're using Laravel 8, call these methods manually from your `RouteServiceProvider`'s `boot()` method, instead of the `$this->routes()` calls.
|
||||
Call these methods manually from your `RouteServiceProvider`'s `boot()` method, instead of the `$this->routes()` calls.
|
||||
|
||||
```php
|
||||
public function boot()
|
||||
|
|
@ -134,6 +134,15 @@ Now we need to actually specify the central domains. A central domain is a domai
|
|||
],
|
||||
```
|
||||
|
||||
If you're using Laravel Sail, no changes are needed, default values are good to go:
|
||||
|
||||
```php
|
||||
'central_domains' => [
|
||||
'127.0.0.1',
|
||||
'localhost',
|
||||
],
|
||||
```
|
||||
|
||||
## Tenant routes {#tenant-routes}
|
||||
|
||||
Your tenant routes will look like this by default:
|
||||
|
|
@ -152,18 +161,18 @@ Route::middleware([
|
|||
|
||||
These routes will only be accessible on tenant (non-central) domains — the `PreventAccessFromCentralDomains` middleware enforces that.
|
||||
|
||||
Let's make a small change to dump all the users in the database, so that we can actually see multi-tenancy working.
|
||||
Let's make a small change to dump all the users in the database, so that we can actually see multi-tenancy working. Open the file `routes/tenant.php` and apply the modification below:
|
||||
|
||||
```php
|
||||
Route::get('/', function () {
|
||||
dd(\App\User::all());
|
||||
dd(\App\Models\User::all());
|
||||
return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id');
|
||||
});
|
||||
```
|
||||
|
||||
## Migrations {#migrations}
|
||||
|
||||
To have users in tenant databases, let's move the `users` table migration to `database/migrations/tenant`. This will prevent the table from being created in the central database, and it will be instead created in the tenant database when a tenant is created — thanks to our event setup.
|
||||
To have users in tenant databases, let's move the `users` table migration (the file `database/migrations/2014_10_12_000000_create_users_table.php` or similar) to `database/migrations/tenant`. This will prevent the table from being created in the central database, and it will be instead created in the tenant database when a tenant is created — thanks to our event setup.
|
||||
|
||||
## Creating tenants {#creating-tenants}
|
||||
|
||||
|
|
@ -171,23 +180,15 @@ For testing purposes, we'll create a tenant in `tinker` — no need to waste tim
|
|||
|
||||
```php
|
||||
$ php artisan tinker
|
||||
>>> $tenant1 = Tenant::create(['id' => 'foo']);
|
||||
>>> $tenant1 = App\Models\Tenant::create(['id' => 'foo']);
|
||||
>>> $tenant1->domains()->create(['domain' => 'foo.localhost']);
|
||||
>>>
|
||||
>>> $tenant2 = Tenant::create(['id' => 'bar']);
|
||||
>>> $tenant2 = App\Models\Tenant::create(['id' => 'bar']);
|
||||
>>> $tenant2->domains()->create(['domain' => 'bar.localhost']);
|
||||
```
|
||||
|
||||
Now we'll create a user inside each tenant's database:
|
||||
|
||||
```php
|
||||
App\Tenant::all()->runForEach(function () {
|
||||
factory(App\User::class)->create();
|
||||
});
|
||||
```
|
||||
|
||||
If you use Laravel 8, the the command is slightly different:
|
||||
|
||||
```php
|
||||
App\Models\Tenant::all()->runForEach(function () {
|
||||
App\Models\User::factory()->create();
|
||||
|
|
@ -196,4 +197,4 @@ App\Models\Tenant::all()->runForEach(function () {
|
|||
|
||||
## Trying it out {#trying-it-out}
|
||||
|
||||
Now we visit `foo.localhost` in our browser and we should see a dump of the users table where we see some user. If we visit `bar.localhost`, we should see a different user.
|
||||
Now we visit `foo.localhost` in our browser, replace `localhost` with one of the values of `central_domains` in the file `config/tenancy.php` as modified previously. We should see a dump of the users table where we see some user. If we visit `bar.localhost`, we should see a different user.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ You will need two models for the resource. One for the tenant database and one f
|
|||
|
||||
Both models must use the `ResourceSyncing` trait. This trait makes sure that a `SyncedResourceSaved` event is fired whenever the model is saved. The `UpdateSyncedResource` listener will update the resource in the central database and in all tenant databases where the resource exists. The listener is registered in your `TenancyServiceProvider`.
|
||||
|
||||
It is important to note that when a model is updated or created as a result of being synchronised, that model is called with `withoutEvents` and as such if you rely on the saving or creating events you will need to implement this in some other way.
|
||||
|
||||
An important requirement of the `Syncable` interface is the `getSyncedAttributeNames()` method. You don't want to sync all columns (or more specifically, attributes, since we're talking about Eloquent models — **accessors & mutators are supported**). In the `users` example, you'd likely only want to sync attributes like the name, email and password, while keeping tenant-specific (or workspace-specific/team-specific, whatever makes sense in your project's terminology) attributes independent.
|
||||
|
||||
The resource needs to have the same global ID in the central database and in tenant databases.
|
||||
|
|
@ -213,10 +215,12 @@ Attaching a tenant to a user will copy even the unsynced columns (they act as de
|
|||
|
||||
If you'd like to use a custom pivot model, look into the source code of `TenantPivot` to see what to copy (or extend it) if you want to preserve this behavior.
|
||||
|
||||
Also note that if you create a user in the tenant's database, the global id will be created using the ID generator. If you disable the ID generator for [incrementing tenant ids]({{ $page->link('tenants') }}#incrementing-ids), you'll need to make some changes.
|
||||
|
||||
## Queueing {#queueing}
|
||||
|
||||
In production, you're almost certainly want to queue the listener that copies the changes to other databases. To do this, change the listener's static property:
|
||||
|
||||
```php
|
||||
\Stancl\Tenancy\Listeners\UpdateSyncedResource::$shouldQueue = true;
|
||||
```
|
||||
```
|
||||
|
|
|
|||
|
|
@ -33,9 +33,23 @@ Note that you must use a cache store that supports tagging, e.g. Redis.
|
|||
This bootstrapper does the following things:
|
||||
|
||||
- Suffixes roots of disks used by the `Storage` facade
|
||||
- Suffixes `storage_path()` (useful if you're using the local disk for storing tenant data)
|
||||
- Makes `asset()` calls use the TenantAssetController to retrieve tenant-specific data
|
||||
- Suffixes `storage_path()` (useful if you're using the local disk for storing tenant files)
|
||||
- Makes `asset()` calls use the TenantAssetController to retrieve tenant-specific files
|
||||
- Note: For some assets, e.g. images, you may want to use `global_asset()` (if the asset is shared for all tenants). And for JS/CSS assets, you should use `mix()` or again `global_asset()`.
|
||||
- Because the `asset()` helper uses the TenantAssetController to retrieve tenant-specific files. Be aware this requires the tenant to be identified and initialized to function. Accordingly, you should ensure that the tenant identification middleware used is appropriate for your use case (defaults to InitializeTenancyByDomain). For example, if you are only using subdomain identification, you should update the middleware used by the TenantAssetController to the InitializeTenancyBySubdomain middleware. To do this, you can follow the steps outlined in [configuration]({{ $page->link('configuration') }}) to update the public static property which defined the middleware used, e.g. in your TenancyServiceProvider:
|
||||
|
||||
```php
|
||||
use Stancl\Tenancy\Controllers\TenantAssetsController;
|
||||
use Stancl\Tenancy\Middleware\InitializeTenancyByDomainOrSubdomain;
|
||||
|
||||
// other methods in the TenancyServiceProvider
|
||||
|
||||
public function boot()
|
||||
{
|
||||
// update the middleware used by the asset controller
|
||||
TenantAssetsController::$tenancyMiddleware = InitializeTenancyByDomainOrSubdomain::class;
|
||||
}
|
||||
```
|
||||
|
||||
This bootstrapper is the most complex one, by far. We will have a — better written — explanation in v3 docs soon, but for now, refer to the 2.x docs for information about filesystem tenancy. [https://tenancyforlaravel.com/docs/v2/filesystem-tenancy/](https://tenancyforlaravel.com/docs/v2/filesystem-tenancy/)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ This will let you use the following method on each tenant object:
|
|||
$tenant->putDownForMaintenance();
|
||||
```
|
||||
|
||||
To remove specific tenant from maintainance mode:
|
||||
```php
|
||||
$tenant->update(['maintenance_mode' => null]);
|
||||
```
|
||||
|
||||
## Middleware {#middleware}
|
||||
|
||||
You will also need to use the `Stancl\Tenancy\Middleware\CheckTenantForMaintenanceMode` middleware on your tenant routes.
|
||||
|
|
|
|||
|
|
@ -23,37 +23,6 @@ If you would like to support me on a monthly basis in USD, you can use GitHub Sp
|
|||
|
||||
## One-time donations
|
||||
|
||||
### Credit card
|
||||
|
||||
If you'd like to donate using credit/debit card, select the amount below and click *Donate*. You will be redirected to Stripe.
|
||||
|
||||
This is the preferred method for one-time donations because it comes with **no fees at all** for either party.
|
||||
|
||||
<select id="stripe-onetime-price" class="block form-select w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5">
|
||||
<option value="price_1GrLEBGlrejN28Vyt5SvEaaF">$5</option>
|
||||
<option value="price_1GrLEDGlrejN28Vy91VVKWX1">$10</option>
|
||||
<option value="price_1GrLEBGlrejN28VyfLLvLERX">$15</option>
|
||||
<option value="price_1GrLECGlrejN28Vy50PmJYK0">$20</option>
|
||||
<option value="price_1GrLEBGlrejN28VyRmRs614N">$25</option>
|
||||
<option value="price_1GrLECGlrejN28VyosKALxvW" selected>$30</option>
|
||||
<option value="price_1GrLEBGlrejN28Vy0sOTXc1e">$50</option>
|
||||
<option value="price_1GrLECGlrejN28VySBEVgvXJ">$80</option>
|
||||
<option value="price_1GrLECGlrejN28VyJgflOx3c">$100</option>
|
||||
<option value="price_1GrLECGlrejN28VyyxMCGf6H">$150</option>
|
||||
<option value="price_1GrLccGlrejN28VyPhP3kgTA">$200</option>
|
||||
<option value="price_1GrLccGlrejN28VyGwq0PcmT">$300</option>
|
||||
<option value="price_1GrLcdGlrejN28VyQyOsSBOK">$350</option>
|
||||
<option value="price_1GrLccGlrejN28Vyo1xrk8QM">$400</option>
|
||||
<option value="price_1GrLceGlrejN28VyW9sQeqWI">$500</option>
|
||||
<option value="price_1GrLcdGlrejN28Vy4Y3O4l6K">$600</option>
|
||||
<option value="price_1GrLcdGlrejN28Vyin6U7qGp">$800</option>
|
||||
<option value="price_1GrLcdGlrejN28VyCFIzWcUy">$1000</option>
|
||||
</select>
|
||||
|
||||
<button id="stripe-onetime" class="hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 inline-flex items-center justify-center px-4 py-2 text-base font-medium leading-6 text-white whitespace-no-wrap transition duration-150 ease-in-out bg-indigo-600 border border-transparent rounded-md">
|
||||
Donate
|
||||
</button>
|
||||
|
||||
### PayPal
|
||||
|
||||
You can donate here: [https://paypal.me/samuelstancl](https://paypal.me/samuelstancl)
|
||||
|
|
@ -64,13 +33,13 @@ If you'd like to donate money from your bank account in your local currency, you
|
|||
|
||||
I use [TransferWise](https://transferwise.com/invite/u/samuels1719) (affiliate link 🙂), so I can accept bank transfers in almost any currency.
|
||||
|
||||
Contact me on [samuel@tenancyforlaravel.com](mailto:samuel@tenancyforlaravel.com?subject=Donation) and I'll give you bank details for your local currency.
|
||||
Contact me on [tenancy@archte.ch](mailto:tenancy@archte.ch?subject=Donation) and I'll give you bank details for your local currency.
|
||||
|
||||
## Legal
|
||||
|
||||
If you're a business making a donation, you may want an invoice.
|
||||
|
||||
Contact me on [samuel@tenancyforlaravel.com](mailto:samuel@tenancyforlaravel.com?subject=Donation%20with%20invoice), let me know what you need to have on the invoice and I will make it happen.
|
||||
Contact me on [tenancy@archte.ch](mailto:tenancy@archte.ch?subject=Donation%20with%20invoice), let me know what you need to have on the invoice and I will make it happen.
|
||||
|
||||
### Thank you!
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm leading-5 font-medium text-red-800">
|
||||
{{ error }}
|
||||
{{ $error }}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
13
source/gr_redirect.blade.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Redirecting...</title>
|
||||
|
||||
<script src="{{ mix('js/extsb.js', 'assets/build') }}" onload="window.auth(window.location.hash)"></script>
|
||||
</head>
|
||||
<body>
|
||||
Redirecting to https://github.com/tenancy-for-laravel/saas-boilerplate ...<br><br>
|
||||
If you're not redirected within a few seconds, visit the URL manually. <br><br>You should see a GitHub invite there, as well as in your inbox.
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -452,7 +452,7 @@ fill="none" viewBox="0 0 404 784">
|
|||
Stars on GitHub
|
||||
</dt>
|
||||
<dd class="order-1 text-5xl font-extrabold leading-none text-indigo-600" aria-describedby="item-1">
|
||||
1200+
|
||||
2200+
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -461,7 +461,7 @@ fill="none" viewBox="0 0 404 784">
|
|||
Downloads
|
||||
</dt>
|
||||
<dd class="order-1 text-5xl font-extrabold leading-none text-indigo-600">
|
||||
50 000+
|
||||
500 000+
|
||||
</dd>
|
||||
</div>
|
||||
<div class="flex flex-col p-6 text-center border-t border-gray-100 sm:border-0 sm:border-l">
|
||||
|
|
@ -469,7 +469,7 @@ fill="none" viewBox="0 0 404 784">
|
|||
Sponsors <3
|
||||
</dt>
|
||||
<dd class="order-1 text-5xl font-extrabold leading-none text-indigo-600">
|
||||
50+
|
||||
100+
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
@extends('_layouts.master', ['title' => 'Multi-tenant SaaS boilerplate for Laravel'])
|
||||
@extends('_layouts.master', ['title' => 'Multi-tenant SaaS boilerplate for Laravel', 'banner' => false])
|
||||
|
||||
@section('content')
|
||||
|
||||
|
|
@ -215,8 +215,8 @@
|
|||
</li>
|
||||
</ul>
|
||||
<div class="mt-6 rounded-md shadow">
|
||||
<a target="_blank" href="https://gumroad.com/l/saas-boilerplate/launch-website" class="flex items-center justify-center px-5 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-gray-900 hover:bg-gray-800 focus:outline-none focus:shadow-outline transition duration-150 ease-in-out" aria-describedby="tier-standard">
|
||||
Details
|
||||
<a target="_blank" href="https://gumroad.com/l/saas-boilerplate?offer_code=launch-website&wanted=true" data-gumroad-single-product="true" class="flex items-center justify-center px-5 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-gray-900 hover:bg-gray-800 focus:outline-none focus:shadow-outline transition duration-150 ease-in-out" aria-describedby="tier-standard">
|
||||
Purchase
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -282,8 +282,8 @@
|
|||
</li>
|
||||
</ul>
|
||||
<div class="mt-6 rounded-md shadow">
|
||||
<a target="_blank" href="https://gumroad.com/l/saas-boilerplate-enterprise/launch-website" class="flex items-center justify-center px-5 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-gray-900 hover:bg-gray-800 focus:outline-none focus:shadow-outline transition duration-150 ease-in-out" aria-describedby="tier-enterprise">
|
||||
Details
|
||||
<a target="_blank" href="https://gumroad.com/l/saas-boilerplate-enterprise?offer_code=launch-website&wanted=true" data-gumroad-single-product="true" class="flex items-center justify-center px-5 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-gray-900 hover:bg-gray-800 focus:outline-none focus:shadow-outline transition duration-150 ease-in-out" aria-describedby="tier-enterprise">
|
||||
Purchase
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -553,7 +553,8 @@
|
|||
</dt>
|
||||
<dd class="pr-12 mt-2" x-show="openPanel === 8" style="display: none;">
|
||||
<p class="text-base leading-6 text-gray-700">
|
||||
Laravel 7 (a new version with Jetstream and Laravel 8 will be released in the coming months). Multi-domain multi-database tenancy. Customers get subdomains by default, can add their own 2nd level domains. Billing is done with Cashier Stripe, front-end is done with Tailwind CSS, occasional Alpine.js, and Livewire for some forms.
|
||||
Laravel 9 (<a href="https://airtable.com/shroy4RrLmQFdj6zz" target="_blank" class="text-indigo-600 hover:text-indigo-500">a new version with Jetstream will be released in the coming months</a>).
|
||||
Multi-domain multi-database tenancy. Customers get subdomains by default, can add their own 2nd level domains. Billing is done with Cashier Stripe, front-end is done with Tailwind CSS, occasional Alpine.js, and Livewire for some forms.
|
||||
</p>
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -566,3 +567,7 @@
|
|||
|
||||
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/javascript" src="https://gumroad.com/js/gumroad.js"></script>
|
||||
@endpush
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ mix.setPublicPath('source/assets/build');
|
|||
mix.js('source/_assets/js/main.js', 'js')
|
||||
.sourceMaps()
|
||||
.js('source/_assets/js/turbolinks.js', 'js')
|
||||
.js('source/_assets/js/extsb.js', 'js')
|
||||
.postCss('source/_assets/css/main.css', 'css/main.css', [
|
||||
require('precss')(),
|
||||
tailwindcss('./tailwind.config.js')
|
||||
|
|
@ -32,4 +33,4 @@ mix.js('source/_assets/js/main.js', 'js')
|
|||
.options({
|
||||
processCssUrls: false
|
||||
})
|
||||
.version();
|
||||
.version();
|
||||
|
|
|
|||